From a9d31bc7fe03d2d18ec37b8324db28c58c62f758 Mon Sep 17 00:00:00 2001 From: vikpeni Date: Fri, 31 Oct 2025 10:21:28 -0400 Subject: [PATCH 1/2] Updating Multer to ^2.0.2 --- package-lock.json | 3269 ++++++++++++++++++++++++++------------------- package.json | 2 +- 2 files changed, 1907 insertions(+), 1364 deletions(-) diff --git a/package-lock.json b/package-lock.json index 103e0091..7f2249e8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,7 +18,7 @@ "express-rate-limit": "^7.3.1", "https-proxy-agent": "^7.0.5", "jsdom": "^24.1.0", - "multer": "^1.4.5-lts.1", + "multer": "^2.0.2", "prompts": "^2.4.2", "puppeteer": "^22.12.1", "tarn": "^3.0.2", @@ -45,37 +45,43 @@ "node": ">=18.12.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", + "node_modules/@asamuzakjp/css-color": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.2.0.tgz", + "integrity": "sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==", + "license": "MIT", "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" + "@csstools/css-calc": "^2.1.3", + "@csstools/css-color-parser": "^3.0.9", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "lru-cache": "^10.4.3" } }, + "node_modules/@asamuzakjp/css-color/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==", + "license": "ISC" + }, "node_modules/@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.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", "license": "MIT", "dependencies": { - "@babel/highlight": "^7.24.7", - "picocolors": "^1.0.0" + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@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.28.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz", + "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==", "dev": true, "license": "MIT", "engines": { @@ -83,22 +89,22 @@ } }, "node_modules/@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==", - "dev": true, - "license": "MIT", - "dependencies": { - "@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", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz", + "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.5", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.28.3", + "@babel/helpers": "^7.28.4", + "@babel/parser": "^7.28.5", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.5", + "@babel/types": "^7.28.5", + "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -114,31 +120,32 @@ } }, "node_modules/@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.28.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz", + "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.24.7", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" + "@babel/parser": "^7.28.5", + "@babel/types": "^7.28.5", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@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.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.24.7", - "@babel/helper-validator-option": "^7.24.7", - "browserslist": "^4.22.2", + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -146,72 +153,40 @@ "node": ">=6.9.0" } }, - "node_modules/@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==", + "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", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@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, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@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, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.24.7" - }, "engines": { "node": ">=6.9.0" } }, "node_modules/@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.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", "dev": true, "license": "MIT", "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@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.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", + "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", "dev": true, "license": "MIT", "dependencies": { - "@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.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.28.3" }, "engines": { "node": ">=6.9.0" @@ -221,46 +196,19 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", - "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" } }, - "node_modules/@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==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@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, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@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.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": { @@ -268,18 +216,18 @@ } }, "node_modules/@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.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@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.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": { @@ -287,111 +235,28 @@ } }, "node_modules/@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.28.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", + "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", "dev": true, "license": "MIT", "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.24.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==", - "license": "MIT", - "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==", - "license": "MIT", - "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==", - "license": "MIT", - "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==", - "license": "MIT" - }, - "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==", - "license": "MIT", - "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==", - "license": "MIT", - "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==", - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/@babel/parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", - "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", + "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", "dev": true, "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.5" + }, "bin": { "parser": "bin/babel-parser.js" }, @@ -438,6 +303,38 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz", + "integrity": "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-syntax-import-meta": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", @@ -465,13 +362,13 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz", - "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz", + "integrity": "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -558,6 +455,22 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-syntax-top-level-await": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", @@ -575,13 +488,13 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.7.tgz", - "integrity": "sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz", + "integrity": "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -591,62 +504,48 @@ } }, "node_modules/@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.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz", - "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", + "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", "dev": true, "license": "MIT", "dependencies": { - "@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" + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.5", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.5", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.5", + "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.24.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", - "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", + "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7", - "to-fast-properties": "^2.0.0" + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" }, "engines": { "node": ">=6.9.0" @@ -659,26 +558,139 @@ "dev": true, "license": "MIT" }, + "node_modules/@csstools/color-helpers": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz", + "integrity": "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + } + }, + "node_modules/@csstools/css-calc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz", + "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-color-parser": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz", + "integrity": "sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/color-helpers": "^5.1.0", + "@csstools/css-calc": "^2.1.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", + "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", + "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "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.9.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", + "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", "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.11.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", - "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", + "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": { @@ -710,9 +722,9 @@ } }, "node_modules/@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, "license": "MIT", "engines": { @@ -720,14 +732,14 @@ } }, "node_modules/@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==", "deprecated": "Use @eslint/config-array instead", "dev": true, "license": "Apache-2.0", "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", + "@humanwhocodes/object-schema": "^2.0.3", "debug": "^4.3.1", "minimatch": "^3.0.5" }, @@ -864,13 +876,6 @@ "node": ">=8" } }, - "node_modules/@istanbuljs/load-nyc-config/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, - "license": "BSD-3-Clause" - }, "node_modules/@istanbuljs/schema": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", @@ -1174,34 +1179,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": { @@ -1209,9 +1211,9 @@ } }, "node_modules/@jridgewell/source-map": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", - "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", "dev": true, "license": "MIT", "dependencies": { @@ -1220,16 +1222,16 @@ } }, "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==", + "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": { @@ -1276,32 +1278,32 @@ } }, "node_modules/@pkgr/core": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", - "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", + "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==", "dev": true, "license": "MIT", "engines": { "node": "^12.20.0 || ^14.18.0 || >=16.0.0" }, "funding": { - "url": "https://opencollective.com/unts" + "url": "https://opencollective.com/pkgr" } }, "node_modules/@puppeteer/browsers": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.2.3.tgz", - "integrity": "sha512-bJ0UBsk0ESOs6RFcLXOt99a3yTDcOKlzfjad+rhFwdaG1Lu/Wzq58GHYCDTlZ9z6mldf4g+NTb+TXEfe0PpnsQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.3.0.tgz", + "integrity": "sha512-ioXoq9gPxkss4MYhD+SFaU9p1IHFUX0ILAWFPyjGaBdjLsYAlZw6j1iLA0N/m12uVHLFDfSYNF7EQccjinIMDA==", "license": "Apache-2.0", "dependencies": { - "debug": "4.3.4", - "extract-zip": "2.0.1", - "progress": "2.0.3", - "proxy-agent": "6.4.0", - "semver": "7.6.0", - "tar-fs": "3.0.5", - "unbzip2-stream": "1.4.3", - "yargs": "17.7.2" + "debug": "^4.3.5", + "extract-zip": "^2.0.1", + "progress": "^2.0.3", + "proxy-agent": "^6.4.0", + "semver": "^7.6.3", + "tar-fs": "^3.0.6", + "unbzip2-stream": "^1.4.3", + "yargs": "^17.7.2" }, "bin": { "browsers": "lib/cjs/main-cli.js" @@ -1310,43 +1312,11 @@ "node": ">=18" } }, - "node_modules/@puppeteer/browsers/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "license": "MIT", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@puppeteer/browsers/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/@puppeteer/browsers/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, "bin": { "semver": "bin/semver.js" }, @@ -1354,12 +1324,6 @@ "node": ">=10" } }, - "node_modules/@puppeteer/browsers/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/@rollup/plugin-terser": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz", @@ -1384,9 +1348,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.26.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.26.0.tgz", - "integrity": "sha512-gJNwtPDGEaOEgejbaseY6xMFu+CPltsc8/T+diUTTbOQLqD+bnrJq9ulH6WD69TqwqWmrfRAtUv30cCFZlbGTQ==", + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.5.tgz", + "integrity": "sha512-8c1vW4ocv3UOMp9K+gToY5zL2XiiVw3k7f1ksf4yO1FlDFQ1C2u72iACFnSOceJFsWskc2WZNqeRhFRPzv+wtQ==", "cpu": [ "arm" ], @@ -1398,9 +1362,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.26.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.26.0.tgz", - "integrity": "sha512-YJa5Gy8mEZgz5JquFruhJODMq3lTHWLm1fOy+HIANquLzfIOzE9RA5ie3JjCdVb9r46qfAQY/l947V0zfGJ0OQ==", + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.5.tgz", + "integrity": "sha512-mQGfsIEFcu21mvqkEKKu2dYmtuSZOBMmAl5CFlPGLY94Vlcm+zWApK7F/eocsNzp8tKmbeBP8yXyAbx0XHsFNA==", "cpu": [ "arm64" ], @@ -1412,9 +1376,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.26.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.26.0.tgz", - "integrity": "sha512-ErTASs8YKbqTBoPLp/kA1B1Um5YSom8QAc4rKhg7b9tyyVqDBlQxy7Bf2wW7yIlPGPg2UODDQcbkTlruPzDosw==", + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.5.tgz", + "integrity": "sha512-takF3CR71mCAGA+v794QUZ0b6ZSrgJkArC+gUiG6LB6TQty9T0Mqh3m2ImRBOxS2IeYBo4lKWIieSvnEk2OQWA==", "cpu": [ "arm64" ], @@ -1426,9 +1390,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.26.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.26.0.tgz", - "integrity": "sha512-wbgkYDHcdWW+NqP2mnf2NOuEbOLzDblalrOWcPyY6+BRbVhliavon15UploG7PpBRQ2bZJnbmh8o3yLoBvDIHA==", + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.5.tgz", + "integrity": "sha512-W901Pla8Ya95WpxDn//VF9K9u2JbocwV/v75TE0YIHNTbhqUTv9w4VuQ9MaWlNOkkEfFwkdNhXgcLqPSmHy0fA==", "cpu": [ "x64" ], @@ -1440,9 +1404,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.26.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.26.0.tgz", - "integrity": "sha512-Y9vpjfp9CDkAG4q/uwuhZk96LP11fBz/bYdyg9oaHYhtGZp7NrbkQrj/66DYMMP2Yo/QPAsVHkV891KyO52fhg==", + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.5.tgz", + "integrity": "sha512-QofO7i7JycsYOWxe0GFqhLmF6l1TqBswJMvICnRUjqCx8b47MTo46W8AoeQwiokAx3zVryVnxtBMcGcnX12LvA==", "cpu": [ "arm64" ], @@ -1454,9 +1418,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.26.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.26.0.tgz", - "integrity": "sha512-A/jvfCZ55EYPsqeaAt/yDAG4q5tt1ZboWMHEvKAH9Zl92DWvMIbnZe/f/eOXze65aJaaKbL+YeM0Hz4kLQvdwg==", + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.5.tgz", + "integrity": "sha512-jr21b/99ew8ujZubPo9skbrItHEIE50WdV86cdSoRkKtmWa+DDr6fu2c/xyRT0F/WazZpam6kk7IHBerSL7LDQ==", "cpu": [ "x64" ], @@ -1468,9 +1432,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.26.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.26.0.tgz", - "integrity": "sha512-paHF1bMXKDuizaMODm2bBTjRiHxESWiIyIdMugKeLnjuS1TCS54MF5+Y5Dx8Ui/1RBPVRE09i5OUlaLnv8OGnA==", + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.5.tgz", + "integrity": "sha512-PsNAbcyv9CcecAUagQefwX8fQn9LQ4nZkpDboBOttmyffnInRy8R8dSg6hxxl2Re5QhHBf6FYIDhIj5v982ATQ==", "cpu": [ "arm" ], @@ -1482,9 +1446,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.26.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.26.0.tgz", - "integrity": "sha512-cwxiHZU1GAs+TMxvgPfUDtVZjdBdTsQwVnNlzRXC5QzIJ6nhfB4I1ahKoe9yPmoaA/Vhf7m9dB1chGPpDRdGXg==", + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.5.tgz", + "integrity": "sha512-Fw4tysRutyQc/wwkmcyoqFtJhh0u31K+Q6jYjeicsGJJ7bbEq8LwPWV/w0cnzOqR2m694/Af6hpFayLJZkG2VQ==", "cpu": [ "arm" ], @@ -1496,9 +1460,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.26.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.26.0.tgz", - "integrity": "sha512-4daeEUQutGRCW/9zEo8JtdAgtJ1q2g5oHaoQaZbMSKaIWKDQwQ3Yx0/3jJNmpzrsScIPtx/V+1AfibLisb3AMQ==", + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.5.tgz", + "integrity": "sha512-a+3wVnAYdQClOTlyapKmyI6BLPAFYs0JM8HRpgYZQO02rMR09ZcV9LbQB+NL6sljzG38869YqThrRnfPMCDtZg==", "cpu": [ "arm64" ], @@ -1510,9 +1474,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.26.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.26.0.tgz", - "integrity": "sha512-eGkX7zzkNxvvS05ROzJ/cO/AKqNvR/7t1jA3VZDi2vRniLKwAWxUr85fH3NsvtxU5vnUUKFHKh8flIBdlo2b3Q==", + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.5.tgz", + "integrity": "sha512-AvttBOMwO9Pcuuf7m9PkC1PUIKsfaAJ4AYhy944qeTJgQOqJYJ9oVl2nYgY7Rk0mkbsuOpCAYSs6wLYB2Xiw0Q==", "cpu": [ "arm64" ], @@ -1523,10 +1487,24 @@ "linux" ] }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.26.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.26.0.tgz", - "integrity": "sha512-Odp/lgHbW/mAqw/pU21goo5ruWsytP7/HCC/liOt0zcGG0llYWKrd10k9Fj0pdj3prQ63N5yQLCLiE7HTX+MYw==", + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.5.tgz", + "integrity": "sha512-DkDk8pmXQV2wVrF6oq5tONK6UHLz/XcEVow4JTTerdeV1uqPeHxwcg7aFsfnSm9L+OO8WJsWotKM2JJPMWrQtA==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.5.tgz", + "integrity": "sha512-W/b9ZN/U9+hPQVvlGwjzi+Wy4xdoH2I8EjaCkMvzpI7wJUs8sWJ03Rq96jRnHkSrcHTpQe8h5Tg3ZzUPGauvAw==", "cpu": [ "ppc64" ], @@ -1538,9 +1516,23 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.26.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.26.0.tgz", - "integrity": "sha512-MBR2ZhCTzUgVD0OJdTzNeF4+zsVogIR1U/FsyuFerwcqjZGvg2nYe24SAHp8O5sN8ZkRVbHwlYeHqcSQ8tcYew==", + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.5.tgz", + "integrity": "sha512-sjQLr9BW7R/ZiXnQiWPkErNfLMkkWIoCz7YMn27HldKsADEKa5WYdobaa1hmN6slu9oWQbB6/jFpJ+P2IkVrmw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.5.tgz", + "integrity": "sha512-hq3jU/kGyjXWTvAh2awn8oHroCbrPm8JqM7RUpKjalIRWWXE01CQOf/tUNWNHjmbMHg/hmNCwc/Pz3k1T/j/Lg==", "cpu": [ "riscv64" ], @@ -1552,9 +1544,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.26.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.26.0.tgz", - "integrity": "sha512-YYcg8MkbN17fMbRMZuxwmxWqsmQufh3ZJFxFGoHjrE7bv0X+T6l3glcdzd7IKLiwhT+PZOJCblpnNlz1/C3kGQ==", + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.5.tgz", + "integrity": "sha512-gn8kHOrku8D4NGHMK1Y7NA7INQTRdVOntt1OCYypZPRt6skGbddska44K8iocdpxHTMMNui5oH4elPH4QOLrFQ==", "cpu": [ "s390x" ], @@ -1566,9 +1558,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.26.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.26.0.tgz", - "integrity": "sha512-ZuwpfjCwjPkAOxpjAEjabg6LRSfL7cAJb6gSQGZYjGhadlzKKywDkCUnJ+KEfrNY1jH5EEoSIKLCb572jSiglA==", + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.5.tgz", + "integrity": "sha512-hXGLYpdhiNElzN770+H2nlx+jRog8TyynpTVzdlc6bndktjKWyZyiCsuDAlpd+j+W+WNqfcyAWz9HxxIGfZm1Q==", "cpu": [ "x64" ], @@ -1580,9 +1572,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.26.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.26.0.tgz", - "integrity": "sha512-+HJD2lFS86qkeF8kNu0kALtifMpPCZU80HvwztIKnYwym3KnA1os6nsX4BGSTLtS2QVAGG1P3guRgsYyMA0Yhg==", + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.5.tgz", + "integrity": "sha512-arCGIcuNKjBoKAXD+y7XomR9gY6Mw7HnFBv5Rw7wQRvwYLR7gBAgV7Mb2QTyjXfTveBNFAtPt46/36vV9STLNg==", "cpu": [ "x64" ], @@ -1593,10 +1585,24 @@ "linux" ] }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.5.tgz", + "integrity": "sha512-QoFqB6+/9Rly/RiPjaomPLmR/13cgkIGfA40LHly9zcH1S0bN2HVFYk3a1eAyHQyjs3ZJYlXvIGtcCs5tko9Cw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.26.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.26.0.tgz", - "integrity": "sha512-WUQzVFWPSw2uJzX4j6YEbMAiLbs0BUysgysh8s817doAYhR5ybqTI1wtKARQKo6cGop3pHnrUJPFCsXdoFaimQ==", + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.5.tgz", + "integrity": "sha512-w0cDWVR6MlTstla1cIfOGyl8+qb93FlAVutcor14Gf5Md5ap5ySfQ7R9S/NjNaMLSFdUnKGEasmVnu3lCMqB7w==", "cpu": [ "arm64" ], @@ -1608,9 +1614,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.26.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.26.0.tgz", - "integrity": "sha512-D4CxkazFKBfN1akAIY6ieyOqzoOoBV1OICxgUblWxff/pSjCA2khXlASUx7mK6W1oP4McqhgcCsu6QaLj3WMWg==", + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.5.tgz", + "integrity": "sha512-Aufdpzp7DpOTULJCuvzqcItSGDH73pF3ko/f+ckJhxQyHtp67rHw3HMNxoIdDMUITJESNE6a8uh4Lo4SLouOUg==", "cpu": [ "ia32" ], @@ -1621,10 +1627,24 @@ "win32" ] }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.5.tgz", + "integrity": "sha512-UGBUGPFp1vkj6p8wCRraqNhqwX/4kNQPS57BCFc8wYh0g94iVIW33wJtQAx3G7vrjjNtRaxiMUylM0ktp/TRSQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.26.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.26.0.tgz", - "integrity": "sha512-2x8MO1rm4PGEP0xWbubJW5RtbNLk3puzAMaLQd3B3JHVw4KcHlmXcO+Wewx9zCoo7EUFiMlu/aZbCJ7VjMzAag==", + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.5.tgz", + "integrity": "sha512-TAcgQh2sSkykPRWLrdyy2AiceMckNf5loITqXxFI5VuQjS5tSuw3WlwdN8qv8vzjLAUTvYaH/mVjSFpbkFbpTg==", "cpu": [ "x64" ], @@ -1635,6 +1655,13 @@ "win32" ] }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true, + "license": "MIT" + }, "node_modules/@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", @@ -1683,9 +1710,9 @@ } }, "node_modules/@types/babel__generator": { - "version": "7.6.8", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", - "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", "dev": true, "license": "MIT", "dependencies": { @@ -1704,19 +1731,19 @@ } }, "node_modules/@types/babel__traverse": { - "version": "7.20.6", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", - "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.20.7" + "@babel/types": "^7.28.2" } }, "node_modules/@types/estree": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", - "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", "dev": true, "license": "MIT" }, @@ -1765,13 +1792,13 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "20.14.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz", - "integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==", + "version": "24.9.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.9.2.tgz", + "integrity": "sha512-uWN8YqxXxqFMX2RqGOrumsKeti4LlmIMIyV0lgut4jx7KQBcBiW6vkDtIBvHnHIquwNfJhk8v2OtmO8zXWHfPA==", "devOptional": true, "license": "MIT", "dependencies": { - "undici-types": "~5.26.4" + "undici-types": "~7.16.0" } }, "node_modules/@types/stack-utils": { @@ -1782,9 +1809,9 @@ "license": "MIT" }, "node_modules/@types/yargs": { - "version": "17.0.32", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", - "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "version": "17.0.34", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.34.tgz", + "integrity": "sha512-KExbHVa92aJpw9WDQvzBaGVE2/Pz+pLZQloT2hjL8IqsZnV62rlPOYvNnLmf/L2dyllfVUOVBj64M0z/46eR2A==", "dev": true, "license": "MIT", "dependencies": { @@ -1809,9 +1836,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" }, @@ -1829,9 +1856,9 @@ } }, "node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", "bin": { @@ -1852,13 +1879,10 @@ } }, "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": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", "license": "MIT", - "dependencies": { - "debug": "^4.3.4" - }, "engines": { "node": ">= 14" } @@ -1960,14 +1984,14 @@ "license": "Python-2.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==", + "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" @@ -1983,18 +2007,20 @@ "license": "MIT" }, "node_modules/array-includes": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", - "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", + "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.4", - "is-string": "^1.0.7" + "es-abstract": "^1.24.0", + "es-object-atoms": "^1.1.1", + "get-intrinsic": "^1.3.0", + "is-string": "^1.1.1", + "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -2004,18 +2030,19 @@ } }, "node_modules/array.prototype.findlastindex": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", - "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", + "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", + "es-abstract": "^1.23.9", "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-shim-unscopables": "^1.0.2" + "es-object-atoms": "^1.1.1", + "es-shim-unscopables": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -2025,16 +2052,16 @@ } }, "node_modules/array.prototype.flat": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", - "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -2044,16 +2071,16 @@ } }, "node_modules/array.prototype.flatmap": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", - "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -2063,20 +2090,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" @@ -2097,6 +2123,16 @@ "node": ">=4" } }, + "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/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -2120,10 +2156,18 @@ } }, "node_modules/b4a": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz", - "integrity": "sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==", - "license": "Apache-2.0" + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.7.3.tgz", + "integrity": "sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q==", + "license": "Apache-2.0", + "peerDependencies": { + "react-native-b4a": "*" + }, + "peerDependenciesMeta": { + "react-native-b4a": { + "optional": true + } + } }, "node_modules/babel-jest": { "version": "29.7.0", @@ -2198,27 +2242,30 @@ } }, "node_modules/babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz", + "integrity": "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==", "dev": true, "license": "MIT", "dependencies": { "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5" }, "peerDependencies": { - "@babel/core": "^7.0.0" + "@babel/core": "^7.0.0 || ^8.0.0-0" } }, "node_modules/babel-preset-jest": { @@ -2246,49 +2293,94 @@ "license": "MIT" }, "node_modules/bare-events": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.4.2.tgz", - "integrity": "sha512-qMKFd2qG/36aA4GwvKq8MxnPgCQAmBWmSyLWsJcbn8v03wvIPQ/hG1Ms8bPzndZxMDoHpxez5VOS+gC9Yi24/Q==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.8.1.tgz", + "integrity": "sha512-oxSAxTS1hRfnyit2CL5QpAOS5ixfBjj6ex3yTNvXyY/kE719jQ/IjuESJBK2w5v4wwQRAHGseVJXx9QBYOtFGQ==", "license": "Apache-2.0", - "optional": true + "peerDependencies": { + "bare-abort-controller": "*" + }, + "peerDependenciesMeta": { + "bare-abort-controller": { + "optional": true + } + } }, "node_modules/bare-fs": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.3.1.tgz", - "integrity": "sha512-W/Hfxc/6VehXlsgFtbB5B4xFcsCl+pAh30cYhoFyXErf6oGrwjh8SwiPAdHgpmWonKuYpZgGywN0SXt7dgsADA==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.5.0.tgz", + "integrity": "sha512-GljgCjeupKZJNetTqxKaQArLK10vpmK28or0+RwWjEl5Rk+/xG3wkpmkv+WrcBm3q1BwHKlnhXzR8O37kcvkXQ==", "license": "Apache-2.0", "optional": true, "dependencies": { - "bare-events": "^2.0.0", - "bare-path": "^2.0.0", - "bare-stream": "^2.0.0" + "bare-events": "^2.5.4", + "bare-path": "^3.0.0", + "bare-stream": "^2.6.4", + "bare-url": "^2.2.2", + "fast-fifo": "^1.3.2" + }, + "engines": { + "bare": ">=1.16.0" + }, + "peerDependencies": { + "bare-buffer": "*" + }, + "peerDependenciesMeta": { + "bare-buffer": { + "optional": true + } } }, "node_modules/bare-os": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.4.0.tgz", - "integrity": "sha512-v8DTT08AS/G0F9xrhyLtepoo9EJBJ85FRSMbu1pQUlAf6A8T0tEEQGMVObWeqpjhSPXsE0VGlluFBJu2fdoTNg==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.6.2.tgz", + "integrity": "sha512-T+V1+1srU2qYNBmJCXZkUY5vQ0B4FSlL3QDROnKQYOqeiQR8UbjNHlPa+TIbM4cuidiN9GaTaOZgSEgsvPbh5A==", "license": "Apache-2.0", - "optional": true + "optional": true, + "engines": { + "bare": ">=1.14.0" + } }, "node_modules/bare-path": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-2.1.3.tgz", - "integrity": "sha512-lh/eITfU8hrj9Ru5quUp0Io1kJWIk1bTjzo7JH1P5dWmQ2EL4hFUlfI8FonAhSlgIfhn63p84CDY/x+PisgcXA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz", + "integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==", "license": "Apache-2.0", "optional": true, "dependencies": { - "bare-os": "^2.1.0" + "bare-os": "^3.0.1" } }, "node_modules/bare-stream": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.1.3.tgz", - "integrity": "sha512-tiDAH9H/kP+tvNO5sczyn9ZAA7utrSMobyDchsnyyXBuUe2FSQWbxhtuHB8jwpHYYevVo2UJpcmvvjrbHboUUQ==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.7.0.tgz", + "integrity": "sha512-oyXQNicV1y8nc2aKffH+BUHFRXmx6VrPzlnaEvMhram0nPBrKcEdcyBg5r08D0i8VxngHFAiVyn1QKXpSG0B8A==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "streamx": "^2.21.0" + }, + "peerDependencies": { + "bare-buffer": "*", + "bare-events": "*" + }, + "peerDependenciesMeta": { + "bare-buffer": { + "optional": true + }, + "bare-events": { + "optional": true + } + } + }, + "node_modules/bare-url": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.3.1.tgz", + "integrity": "sha512-v2yl0TnaZTdEnelkKtXZGnotiV6qATBlnNuUMrHl6v9Lmmrh9mw9RYyImPU7/4RahumSwQS1k2oKXcRfXcbjJw==", "license": "Apache-2.0", "optional": true, "dependencies": { - "streamx": "^2.18.0" + "bare-path": "^3.0.0" } }, "node_modules/base64-js": { @@ -2311,6 +2403,16 @@ ], "license": "MIT" }, + "node_modules/baseline-browser-mapping": { + "version": "2.8.21", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.21.tgz", + "integrity": "sha512-JU0h5APyQNsHOlAM7HnQnPToSDQoEBZqzu/YBlqDnEeymPnZDREeXJA3KBMQee+dKteAxZ2AtvQEvVYdZf241Q==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, "node_modules/basic-ftp": { "version": "5.0.5", "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", @@ -2373,9 +2475,9 @@ "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": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", "dependencies": { @@ -2397,9 +2499,9 @@ } }, "node_modules/browserslist": { - "version": "4.23.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz", - "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==", + "version": "4.27.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.27.0.tgz", + "integrity": "sha512-AXVQwdhot1eqLihwasPElhX2tAZiBjWdJ9i/Zcj2S6QYIjkx62OKSfnobkriB81C3l4w0rVy3Nt4jaTBltYEpw==", "dev": true, "funding": [ { @@ -2417,10 +2519,11 @@ ], "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001629", - "electron-to-chromium": "^1.4.796", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.16" + "baseline-browser-mapping": "^2.8.19", + "caniuse-lite": "^1.0.30001751", + "electron-to-chromium": "^1.5.238", + "node-releases": "^2.0.26", + "update-browserslist-db": "^1.1.4" }, "bin": { "browserslist": "cli.js" @@ -2499,16 +2602,45 @@ } }, "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" + }, + "funding": { + "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==", + "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==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" }, "engines": { "node": ">= 0.4" @@ -2537,9 +2669,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001640", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001640.tgz", - "integrity": "sha512-lA4VMpW0PSUrFnkmVuEKBUovSWKhj7puyCg8StBChgu298N1AtuF1sKWEvfDuimSEDbhlb/KqPKC3fs1HbuQUA==", + "version": "1.0.30001751", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001751.tgz", + "integrity": "sha512-A0QJhug0Ly64Ii3eIqHu5X51ebln3k4yTUkY1j8drqpWHVreg/VLijN48cZ1bYPiqOQuqpkIKnzr/Ul8V+p6Cw==", "dev": true, "funding": [ { @@ -2623,9 +2755,9 @@ } }, "node_modules/chromium-bidi": { - "version": "0.5.24", - "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.5.24.tgz", - "integrity": "sha512-5xQNN2SVBdZv4TxeMLaI+PelrnZsHDhn8h2JtyriLr+0qHcZS8BMuo93qN6J1VmtmrgYP+rmcLHcbpnA8QJh+w==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.6.3.tgz", + "integrity": "sha512-qXlsCmpCZJAnoTYI83Iu6EdYQpMYdVkCfq08KDh2pmlVqK5t5IA9mGs4/LwCwp4fqisSOMXZxP3HIh8w8aRn0A==", "license": "Apache-2.0", "dependencies": { "mitt": "3.0.1", @@ -2636,6 +2768,15 @@ "devtools-protocol": "*" } }, + "node_modules/chromium-bidi/node_modules/zod": { + "version": "3.23.8", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", + "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, "node_modules/ci-info": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", @@ -2653,23 +2794,23 @@ } }, "node_modules/cjs-module-lexer": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.3.1.tgz", - "integrity": "sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==", + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", + "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", "dev": true, "license": "MIT" }, "node_modules/cli-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", - "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", "dev": true, "license": "MIT", "dependencies": { - "restore-cursor": "^4.0.0" + "restore-cursor": "^5.0.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -2764,9 +2905,9 @@ } }, "node_modules/collect-v8-coverage": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", - "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.3.tgz", + "integrity": "sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==", "dev": true, "license": "MIT" }, @@ -2817,9 +2958,9 @@ } }, "node_modules/commander": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", - "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz", + "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==", "dev": true, "license": "MIT", "engines": { @@ -2834,17 +2975,17 @@ "license": "MIT" }, "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==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", "engines": [ - "node >= 0.8" + "node >= 6.0" ], "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", - "readable-stream": "^2.2.2", + "readable-stream": "^3.0.2", "typedarray": "^0.0.6" } }, @@ -2891,12 +3032,6 @@ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", "license": "MIT" }, - "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==", - "license": "MIT" - }, "node_modules/cors": { "version": "2.8.5", "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", @@ -2959,9 +3094,9 @@ } }, "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": { @@ -2974,21 +3109,22 @@ } }, "node_modules/cssstyle": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.0.1.tgz", - "integrity": "sha512-8ZYiJ3A/3OkDd093CBT/0UKDWry7ak4BdPTFP2+QEP7cmhouyq/Up709ASSj2cK02BbZiMgk7kYjZNS4QP5qrQ==", + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.6.0.tgz", + "integrity": "sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==", "license": "MIT", "dependencies": { - "rrweb-cssom": "^0.6.0" + "@asamuzakjp/css-color": "^3.2.0", + "rrweb-cssom": "^0.8.0" }, "engines": { "node": ">=18" } }, "node_modules/cssstyle/node_modules/rrweb-cssom": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", - "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==", + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz", + "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==", "license": "MIT" }, "node_modules/data-uri-to-buffer": { @@ -3014,15 +3150,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" @@ -3032,31 +3168,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" }, @@ -3068,12 +3204,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.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -3085,15 +3221,15 @@ } }, "node_modules/decimal.js": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", - "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", "license": "MIT" }, "node_modules/dedent": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", - "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.0.tgz", + "integrity": "sha512-HGFtf8yhuhGhqO07SV79tRp+br4MnbdjeVxotpn1QBl30pcLLCQjX5b2295ll0fv8RKDKsmWYrl05usHM9CewQ==", "dev": true, "license": "MIT", "peerDependencies": { @@ -3126,6 +3262,7 @@ "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", @@ -3210,9 +3347,9 @@ } }, "node_modules/devtools-protocol": { - "version": "0.0.1299070", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1299070.tgz", - "integrity": "sha512-+qtL3eX50qsJ7c+qVyagqi7AWMoQCBGNfoyJZMwm/NSXVqLYbuitrWEEIzxfUmTNy7//Xe8yhMmQ+elj3uAqSg==", + "version": "0.0.1312386", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1312386.tgz", + "integrity": "sha512-DPnhUXvmvKT2dFA/j7B+riVLUt9Q6RKJlcppojL5CoRywJJKLDYnRlw0gTFKfgDPHP5E04UoB71SxoJlVZy8FA==", "license": "BSD-3-Clause" }, "node_modules/diff-sequences": { @@ -3241,13 +3378,12 @@ "node_modules/dompurify": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.5.tgz", - "integrity": "sha512-lwG+n5h8QNpxtyrJW/gJWckL+1/DQiYMX8f7t8Z2AZTPw1esVrqjI63i7Zc2Gz0aKzLVMYC1V1PL/ky+aY/NgA==", - "license": "(MPL-2.0 OR Apache-2.0)" + "integrity": "sha512-lwG+n5h8QNpxtyrJW/gJWckL+1/DQiYMX8f7t8Z2AZTPw1esVrqjI63i7Zc2Gz0aKzLVMYC1V1PL/ky+aY/NgA==" }, "node_modules/dotenv": { - "version": "16.4.5", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", - "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", "license": "BSD-2-Clause", "engines": { "node": ">=12" @@ -3256,6 +3392,20 @@ "url": "https://dotenvx.com" } }, + "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/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -3263,9 +3413,9 @@ "license": "MIT" }, "node_modules/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.244", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.244.tgz", + "integrity": "sha512-OszpBN7xZX4vWMPJwB9illkN/znA8M36GQqQxi6MNy9axWxhOfJyZZJtSLQCpEFLHP2xK33BiWx9aIuIEXVCcw==", "dev": true, "license": "ISC" }, @@ -3283,9 +3433,9 @@ } }, "node_modules/emoji-regex": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", - "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", "dev": true, "license": "MIT" }, @@ -3299,18 +3449,18 @@ } }, "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==", "license": "MIT", "dependencies": { "once": "^1.4.0" } }, "node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", "license": "BSD-2-Clause", "engines": { "node": ">=0.12" @@ -3328,68 +3478,89 @@ "node": ">=6" } }, + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "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==", "license": "MIT", "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==", + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz", + "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==", "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" @@ -3399,13 +3570,10 @@ } }, "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==", "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, "engines": { "node": ">= 0.4" } @@ -3420,10 +3588,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==", - "dev": true, + "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" @@ -3433,40 +3600,43 @@ } }, "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==", "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" } }, "node_modules/es-shim-unscopables": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", - "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", "dev": true, "license": "MIT", "dependencies": { - "hasown": "^2.0.0" + "hasown": "^2.0.2" + }, + "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==", + "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" @@ -3476,9 +3646,9 @@ } }, "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==", "license": "MIT", "engines": { "node": ">=6" @@ -3525,17 +3695,18 @@ } }, "node_modules/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==", + "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", "@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", @@ -3581,9 +3752,9 @@ } }, "node_modules/eslint-config-prettier": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", - "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.2.tgz", + "integrity": "sha512-iI1f+D2ViGn+uvv5HuHVUamg8ll4tN+JRHGc6IJi4TP9Kl976C57fzPXgseXNs8v0iA8aSJpHsTWjDb9QJamGQ==", "dev": true, "license": "MIT", "bin": { @@ -3616,9 +3787,9 @@ } }, "node_modules/eslint-module-utils": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", - "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz", + "integrity": "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==", "dev": true, "license": "MIT", "dependencies": { @@ -3644,35 +3815,37 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", - "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", + "version": "2.32.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz", + "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, "license": "MIT", "dependencies": { - "array-includes": "^3.1.7", - "array.prototype.findlastindex": "^1.2.3", - "array.prototype.flat": "^1.3.2", - "array.prototype.flatmap": "^1.3.2", + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.9", + "array.prototype.findlastindex": "^1.2.6", + "array.prototype.flat": "^1.3.3", + "array.prototype.flatmap": "^1.3.3", "debug": "^3.2.7", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.8.0", - "hasown": "^2.0.0", - "is-core-module": "^2.13.1", + "eslint-module-utils": "^2.12.1", + "hasown": "^2.0.2", + "is-core-module": "^2.16.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", - "object.fromentries": "^2.0.7", - "object.groupby": "^1.0.1", - "object.values": "^1.1.7", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.1", "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.9", "tsconfig-paths": "^3.15.0" }, "engines": { "node": ">=4" }, "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" } }, "node_modules/eslint-plugin-import/node_modules/debug": { @@ -3699,14 +3872,14 @@ } }, "node_modules/eslint-plugin-prettier": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.3.tgz", - "integrity": "sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==", + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.4.tgz", + "integrity": "sha512-swNtI95SToIz05YINMA6Ox5R057IMAmWZ26GqPxusAp1TZzj+IdY9tXNWWD3vkF/wEqydCONcwjTFpxybBqZsg==", "dev": true, "license": "MIT", "dependencies": { "prettier-linter-helpers": "^1.0.0", - "synckit": "^0.8.6" + "synckit": "^0.11.7" }, "engines": { "node": "^14.18.0 || >=16.0.0" @@ -3717,7 +3890,7 @@ "peerDependencies": { "@types/eslint": ">=8.0.0", "eslint": ">=8.0.0", - "eslint-config-prettier": "*", + "eslint-config-prettier": ">= 7.0.0 <10.0.0 || >=10.1.0", "prettier": ">=3.0.0" }, "peerDependenciesMeta": { @@ -3791,9 +3964,9 @@ } }, "node_modules/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, "license": "BSD-3-Clause", "dependencies": { @@ -3850,6 +4023,15 @@ "dev": true, "license": "MIT" }, + "node_modules/events-universal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz", + "integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==", + "license": "Apache-2.0", + "dependencies": { + "bare-events": "^2.7.0" + } + }, "node_modules/execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", @@ -3901,9 +4083,9 @@ } }, "node_modules/express": { - "version": "4.21.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", - "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", "license": "MIT", "dependencies": { "accepts": "~1.3.8", @@ -3925,7 +4107,7 @@ "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.10", + "path-to-regexp": "0.1.12", "proxy-addr": "~2.0.7", "qs": "6.13.0", "range-parser": "~1.2.1", @@ -3940,12 +4122,16 @@ }, "engines": { "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/express-rate-limit": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.3.1.tgz", - "integrity": "sha512-BbaryvkY4wEgDqLgD18/NSy2lDO2jTuT9Y8c1Mpx0X63Yz0sYd5zN6KPe7UvpuSVvV33T6RaE1o1IVZQjHMYgw==", + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.1.tgz", + "integrity": "sha512-7iN8iPMDzOMHPUYllBEsQdWVB6fPDMPqwjBaFrgr4Jgr/+okjvzAy+UHlYYL/Vs0OsOrMkwS6PJDkFlJwoxUnw==", "license": "MIT", "engines": { "node": ">= 16" @@ -3954,7 +4140,7 @@ "url": "https://github.com/sponsors/express-rate-limit" }, "peerDependencies": { - "express": "4 || 5 || ^5.0.0-beta.1" + "express": ">= 4.11" } }, "node_modules/express/node_modules/debug": { @@ -4042,9 +4228,9 @@ "license": "MIT" }, "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", "dev": true, "license": "ISC", "dependencies": { @@ -4162,30 +4348,38 @@ } }, "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.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", "dev": true, "license": "ISC" }, "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/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": { @@ -4210,20 +4404,6 @@ "node": ">= 0.6" } }, - "node_modules/fs-extra": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", - "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=14.14" - } - }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -4256,16 +4436,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" @@ -4284,6 +4466,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "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": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -4304,9 +4496,9 @@ } }, "node_modules/get-east-asian-width": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz", - "integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz", + "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==", "dev": true, "license": "MIT", "engines": { @@ -4317,16 +4509,21 @@ } }, "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==", "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" @@ -4345,6 +4542,19 @@ "node": ">=8.0.0" } }, + "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/get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", @@ -4359,15 +4569,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" @@ -4377,15 +4587,14 @@ } }, "node_modules/get-uri": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.3.tgz", - "integrity": "sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==", + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.5.tgz", + "integrity": "sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==", "license": "MIT", "dependencies": { "basic-ftp": "^5.0.2", "data-uri-to-buffer": "^6.0.2", - "debug": "^4.3.4", - "fs-extra": "^11.2.0" + "debug": "^4.3.4" }, "engines": { "node": ">= 14" @@ -4460,12 +4669,12 @@ } }, "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==", "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.1.3" + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -4475,6 +4684,7 @@ "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, "license": "ISC" }, "node_modules/graphemer": { @@ -4485,11 +4695,14 @@ "license": "MIT" }, "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" } @@ -4508,6 +4721,7 @@ "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, "license": "MIT", "dependencies": { "es-define-property": "^1.0.0" @@ -4517,10 +4731,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" }, @@ -4529,9 +4747,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==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -4544,7 +4762,6 @@ "version": "1.0.2", "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" @@ -4617,12 +4834,12 @@ } }, "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==", + "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.0.2", + "agent-base": "^7.1.2", "debug": "4" }, "engines": { @@ -4640,13 +4857,13 @@ } }, "node_modules/husky": { - "version": "9.0.11", - "resolved": "https://registry.npmjs.org/husky/-/husky-9.0.11.tgz", - "integrity": "sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==", + "version": "9.1.7", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", + "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==", "dev": true, "license": "MIT", "bin": { - "husky": "bin.mjs" + "husky": "bin.js" }, "engines": { "node": ">=18" @@ -4688,9 +4905,9 @@ "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": { @@ -4705,9 +4922,9 @@ "license": "ISC" }, "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==", "license": "MIT", "dependencies": { "parent-module": "^1.0.0", @@ -4721,9 +4938,9 @@ } }, "node_modules/import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", "dev": true, "license": "MIT", "dependencies": { @@ -4769,29 +4986,25 @@ "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" } }, "node_modules/ip-address": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", - "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.0.1.tgz", + "integrity": "sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==", "license": "MIT", - "dependencies": { - "jsbn": "1.1.0", - "sprintf-js": "^1.1.3" - }, "engines": { "node": ">= 12" } @@ -4806,14 +5019,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" @@ -4828,14 +5042,37 @@ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "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" @@ -4855,14 +5092,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" @@ -4885,9 +5122,9 @@ } }, "node_modules/is-core-module": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.14.0.tgz", - "integrity": "sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==", + "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": { @@ -4901,12 +5138,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": { @@ -4917,13 +5156,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" @@ -4942,6 +5182,22 @@ "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": "4.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", @@ -4965,6 +5221,26 @@ "node": ">=6" } }, + "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", @@ -4978,6 +5254,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-negative-zero": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", @@ -5002,13 +5291,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" @@ -5034,15 +5324,30 @@ "license": "MIT" }, "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" }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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" }, @@ -5051,13 +5356,13 @@ } }, "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" @@ -5080,13 +5385,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" @@ -5096,13 +5402,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" @@ -5112,13 +5420,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" @@ -5127,23 +5435,57 @@ "url": "https://github.com/sponsors/ljharb" } }, + "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-bind": "^1.0.2" + "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-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "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/isexe": { @@ -5181,9 +5523,9 @@ } }, "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", "dev": true, "license": "ISC", "bin": { @@ -5224,9 +5566,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": { @@ -5720,9 +6062,9 @@ } }, "node_modules/jest-snapshot/node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", "dev": true, "license": "ISC", "bin": { @@ -5851,16 +6193,10 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/jsbn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", - "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", - "license": "MIT" - }, "node_modules/jsdom": { - "version": "24.1.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-24.1.0.tgz", - "integrity": "sha512-6gpM7pRXCwIOKxX47cgOyvyQDN/Eh0f1MeKySBV2xGdKtqJBLj8P25eY3EVCWo2mglDDzozR2r2MW4T+JiNUZA==", + "version": "24.1.3", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-24.1.3.tgz", + "integrity": "sha512-MyL55p3Ut3cXbeBEG7Hcv0mVM8pp8PBNWxRqchZnSfAiES1v1mRnMeFfaHWIPULpwsYfvO+ZmMZz5tGCnjzDUQ==", "license": "MIT", "dependencies": { "cssstyle": "^4.0.1", @@ -5869,11 +6205,11 @@ "form-data": "^4.0.0", "html-encoding-sniffer": "^4.0.0", "http-proxy-agent": "^7.0.2", - "https-proxy-agent": "^7.0.4", + "https-proxy-agent": "^7.0.5", "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.10", + "nwsapi": "^2.2.12", "parse5": "^7.1.2", - "rrweb-cssom": "^0.7.0", + "rrweb-cssom": "^0.7.1", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", "tough-cookie": "^4.1.4", @@ -5882,7 +6218,7 @@ "whatwg-encoding": "^3.1.1", "whatwg-mimetype": "^4.0.0", "whatwg-url": "^14.0.0", - "ws": "^8.17.0", + "ws": "^8.18.0", "xml-name-validator": "^5.0.0" }, "engines": { @@ -5898,16 +6234,16 @@ } }, "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", "dev": true, "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, "engines": { - "node": ">=4" + "node": ">=6" } }, "node_modules/json-buffer": { @@ -5950,18 +6286,6 @@ "node": ">=6" } }, - "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "license": "MIT", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -6006,9 +6330,9 @@ } }, "node_modules/lilconfig": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", - "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", "dev": true, "license": "MIT", "engines": { @@ -6025,22 +6349,22 @@ "license": "MIT" }, "node_modules/lint-staged": { - "version": "15.2.7", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.2.7.tgz", - "integrity": "sha512-+FdVbbCZ+yoh7E/RosSdqKJyUM2OEjTciH0TFNkawKgvFp1zbGlEC39RADg+xKBG1R4mhoH2j85myBQZ5wR+lw==", + "version": "15.5.2", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.5.2.tgz", + "integrity": "sha512-YUSOLq9VeRNAo/CTaVmhGDKG+LBtA8KF1X4K5+ykMSwWST1vDxJRB2kv2COgLb1fvpCo+A/y9A0G0znNVmdx4w==", "dev": true, "license": "MIT", "dependencies": { - "chalk": "~5.3.0", - "commander": "~12.1.0", - "debug": "~4.3.4", - "execa": "~8.0.1", - "lilconfig": "~3.1.1", - "listr2": "~8.2.1", - "micromatch": "~4.0.7", - "pidtree": "~0.6.0", - "string-argv": "~0.3.2", - "yaml": "~2.4.2" + "chalk": "^5.4.1", + "commander": "^13.1.0", + "debug": "^4.4.0", + "execa": "^8.0.1", + "lilconfig": "^3.1.3", + "listr2": "^8.2.5", + "micromatch": "^4.0.8", + "pidtree": "^0.6.0", + "string-argv": "^0.3.2", + "yaml": "^2.7.0" }, "bin": { "lint-staged": "bin/lint-staged.js" @@ -6053,9 +6377,9 @@ } }, "node_modules/lint-staged/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", "dev": true, "license": "MIT", "engines": { @@ -6210,16 +6534,16 @@ } }, "node_modules/listr2": { - "version": "8.2.3", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.2.3.tgz", - "integrity": "sha512-Lllokma2mtoniUOS94CcOErHWAug5iu7HOmDrvWgpw8jyQH2fomgB+7lZS4HWZxytUuQwkGOwe49FvwVaA85Xw==", + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.3.3.tgz", + "integrity": "sha512-LWzX2KsqcB1wqQ4AHgYb4RsDXauQiqhjLk+6hjbaeHG4zpjjVAB6wC/gz6X0l+Du1cN3pUB5ZlrvTbhGSNnUQQ==", "dev": true, "license": "MIT", "dependencies": { "cli-truncate": "^4.0.0", "colorette": "^2.0.20", "eventemitter3": "^5.0.1", - "log-update": "^6.0.0", + "log-update": "^6.1.0", "rfdc": "^1.4.1", "wrap-ansi": "^9.0.0" }, @@ -6251,15 +6575,15 @@ "license": "MIT" }, "node_modules/log-update": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.0.0.tgz", - "integrity": "sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", + "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", "dev": true, "license": "MIT", "dependencies": { - "ansi-escapes": "^6.2.0", - "cli-cursor": "^4.0.0", - "slice-ansi": "^7.0.0", + "ansi-escapes": "^7.0.0", + "cli-cursor": "^5.0.0", + "slice-ansi": "^7.1.0", "strip-ansi": "^7.1.0", "wrap-ansi": "^9.0.0" }, @@ -6271,22 +6595,25 @@ } }, "node_modules/log-update/node_modules/ansi-escapes": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.1.tgz", - "integrity": "sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.1.1.tgz", + "integrity": "sha512-Zhl0ErHcSRUaVfGUeUdDuLgpkEo8KIFjB4Y9uAc46ScOpdDiU1Dbyplh7qWJeJ/ZHpbyMSM26+X3BySgnIz40Q==", "dev": true, "license": "MIT", + "dependencies": { + "environment": "^1.0.0" + }, "engines": { - "node": ">=14.16" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/log-update/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "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": { @@ -6297,9 +6624,9 @@ } }, "node_modules/log-update/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==", + "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": { @@ -6310,13 +6637,13 @@ } }, "node_modules/log-update/node_modules/is-fullwidth-code-point": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz", - "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", + "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", "dev": true, "license": "MIT", "dependencies": { - "get-east-asian-width": "^1.0.0" + "get-east-asian-width": "^1.3.1" }, "engines": { "node": ">=18" @@ -6326,9 +6653,9 @@ } }, "node_modules/log-update/node_modules/slice-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz", - "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz", + "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==", "dev": true, "license": "MIT", "dependencies": { @@ -6343,9 +6670,9 @@ } }, "node_modules/log-update/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.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", "dev": true, "license": "MIT", "dependencies": { @@ -6385,9 +6712,9 @@ } }, "node_modules/make-dir/node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", "dev": true, "license": "ISC", "bin": { @@ -6407,6 +6734,15 @@ "tmpl": "1.0.5" } }, + "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/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -6498,6 +6834,19 @@ "node": ">=6" } }, + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -6539,27 +6888,27 @@ } }, "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/multer": { - "version": "1.4.5-lts.1", - "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.5-lts.1.tgz", - "integrity": "sha512-ywPWvcDMeH+z9gQq5qYHCCy+ethsk4goepZ45GLD63fOu0YcNecQxi64nDs3qluZB+murG3/D4dJ7+dGctcCQQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/multer/-/multer-2.0.2.tgz", + "integrity": "sha512-u7f2xaZ/UG8oLXHvtF/oWTRvT44p9ecwBBqTwgJVq0+4BW1g8OW01TyMEGWBHbyMOYVHXslaut7qEQ1meATXgw==", "license": "MIT", "dependencies": { "append-field": "^1.0.0", - "busboy": "^1.0.0", - "concat-stream": "^1.5.2", - "mkdirp": "^0.5.4", + "busboy": "^1.6.0", + "concat-stream": "^2.0.0", + "mkdirp": "^0.5.6", "object-assign": "^4.1.1", - "type-is": "^1.6.4", - "xtend": "^4.0.0" + "type-is": "^1.6.18", + "xtend": "^4.0.2" }, "engines": { - "node": ">= 6.0.0" + "node": ">= 10.16.0" } }, "node_modules/natural-compare": { @@ -6595,16 +6944,16 @@ "license": "MIT" }, "node_modules/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.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", "dev": true, "license": "MIT" }, "node_modules/nodemon": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.4.tgz", - "integrity": "sha512-wjPBbFhtpJwmIeY2yP7QF+UKzPfltVGtfce1g/bB15/8vCGZj8uxD62b/b9M9/WVgme0NZudpownKN+c0plXlQ==", + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.10.tgz", + "integrity": "sha512-WDjw3pJ0/0jMFmyNDp3gvY2YizjLmmOUQo6DEBY+JgdvW/yQ9mEeSw6H5ythl5Ny2ytb7f9C2nIbjSxMNzbJXw==", "dev": true, "license": "MIT", "dependencies": { @@ -6641,9 +6990,9 @@ } }, "node_modules/nodemon/node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", "dev": true, "license": "ISC", "bin": { @@ -6690,9 +7039,9 @@ } }, "node_modules/nwsapi": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.10.tgz", - "integrity": "sha512-QK0sRs7MKv0tKe1+5uZIQk/C8XGza4DAnztJG8iD+TpJIORARrCxczA738awHrZoHeTjSSoHqao2teO0dC/gFQ==", + "version": "2.2.22", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.22.tgz", + "integrity": "sha512-ujSMe1OWVn55euT1ihwCI1ZcAaAU3nxUiDwfDQldc51ZXaB9m2AyOn6/jh1BLe2t/G8xd6uKG1UBF2aZJeg2SQ==", "license": "MIT" }, "node_modules/object-assign": { @@ -6705,9 +7054,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==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -6727,15 +7076,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": { @@ -6780,13 +7131,14 @@ } }, "node_modules/object.values": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", - "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" }, @@ -6852,6 +7204,24 @@ "node": ">= 0.8.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", @@ -6895,19 +7265,19 @@ } }, "node_modules/pac-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.2.tgz", - "integrity": "sha512-BFi3vZnO9X5Qt6NRz7ZOaPja3ic0PhlsmCRYLOpN11+mWBCR6XJDqW5RF3j8jm4WGGQZtBA+bTfxYzeKW73eHg==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.2.0.tgz", + "integrity": "sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==", "license": "MIT", "dependencies": { "@tootallnate/quickjs-emscripten": "^0.23.0", - "agent-base": "^7.0.2", + "agent-base": "^7.1.2", "debug": "^4.3.4", "get-uri": "^6.0.1", "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.5", + "https-proxy-agent": "^7.0.6", "pac-resolver": "^7.0.1", - "socks-proxy-agent": "^8.0.4" + "socks-proxy-agent": "^8.0.5" }, "engines": { "node": ">= 14" @@ -6957,12 +7327,12 @@ } }, "node_modules/parse5": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", - "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", "license": "MIT", "dependencies": { - "entities": "^4.4.0" + "entities": "^6.0.0" }, "funding": { "url": "https://github.com/inikulin/parse5?sponsor=1" @@ -7015,9 +7385,9 @@ "license": "MIT" }, "node_modules/path-to-regexp": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", - "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==", + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", "license": "MIT" }, "node_modules/pend": { @@ -7027,9 +7397,9 @@ "license": "MIT" }, "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "license": "ISC" }, "node_modules/picomatch": { @@ -7059,9 +7429,9 @@ } }, "node_modules/pirates": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", - "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", "dev": true, "license": "MIT", "engines": { @@ -7138,9 +7508,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": { @@ -7158,9 +7528,9 @@ } }, "node_modules/prettier": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz", - "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", + "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", "dev": true, "license": "MIT", "bin": { @@ -7214,12 +7584,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "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==", - "license": "MIT" - }, "node_modules/progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", @@ -7256,19 +7620,19 @@ } }, "node_modules/proxy-agent": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.4.0.tgz", - "integrity": "sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz", + "integrity": "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==", "license": "MIT", "dependencies": { - "agent-base": "^7.0.2", + "agent-base": "^7.1.2", "debug": "^4.3.4", "http-proxy-agent": "^7.0.1", - "https-proxy-agent": "^7.0.3", + "https-proxy-agent": "^7.0.6", "lru-cache": "^7.14.1", - "pac-proxy-agent": "^7.0.1", + "pac-proxy-agent": "^7.1.0", "proxy-from-env": "^1.1.0", - "socks-proxy-agent": "^8.0.2" + "socks-proxy-agent": "^8.0.5" }, "engines": { "node": ">= 14" @@ -7290,10 +7654,16 @@ "license": "MIT" }, "node_modules/psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "license": "MIT" + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", + "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==", + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "funding": { + "url": "https://github.com/sponsors/lupomontero" + } }, "node_modules/pstree.remy": { "version": "1.1.8", @@ -7303,9 +7673,9 @@ "license": "MIT" }, "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", + "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", "license": "MIT", "dependencies": { "end-of-stream": "^1.1.0", @@ -7322,16 +7692,17 @@ } }, "node_modules/puppeteer": { - "version": "22.12.1", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-22.12.1.tgz", - "integrity": "sha512-1GxY8dnEnHr1SLzdSDr0FCjM6JQfAh2E2I/EqzeF8a58DbGVk9oVjj4lFdqNoVbpgFSpAbz7VER9St7S1wDpNg==", + "version": "22.15.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-22.15.0.tgz", + "integrity": "sha512-XjCY1SiSEi1T7iSYuxS82ft85kwDJUS7wj1Z0eGVXKdtr5g4xnVcbjwxhq5xBnpK/E7x1VZZoJDxpjAOasHT4Q==", + "deprecated": "< 24.15.0 is no longer supported", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { - "@puppeteer/browsers": "2.2.3", + "@puppeteer/browsers": "2.3.0", "cosmiconfig": "^9.0.0", - "devtools-protocol": "0.0.1299070", - "puppeteer-core": "22.12.1" + "devtools-protocol": "0.0.1312386", + "puppeteer-core": "22.15.0" }, "bin": { "puppeteer": "lib/esm/puppeteer/node/cli.js" @@ -7341,16 +7712,16 @@ } }, "node_modules/puppeteer-core": { - "version": "22.12.1", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-22.12.1.tgz", - "integrity": "sha512-XmqeDPVdC5/3nGJys1jbgeoZ02wP0WV1GBlPtr/ULRbGXJFuqgXMcKQ3eeNtFpBzGRbpeoCGWHge1ZWKWl0Exw==", + "version": "22.15.0", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-22.15.0.tgz", + "integrity": "sha512-cHArnywCiAAVXa3t4GGL2vttNxh7GqXtIYGym99egkNJ3oG//wL9LkvO4WE8W1TJe95t1F1ocu9X4xWaGsOKOA==", "license": "Apache-2.0", "dependencies": { - "@puppeteer/browsers": "2.2.3", - "chromium-bidi": "0.5.24", - "debug": "^4.3.5", - "devtools-protocol": "0.0.1299070", - "ws": "^8.17.1" + "@puppeteer/browsers": "2.3.0", + "chromium-bidi": "0.6.3", + "debug": "^4.3.6", + "devtools-protocol": "0.0.1312386", + "ws": "^8.18.0" }, "engines": { "node": ">=18" @@ -7415,12 +7786,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==", - "license": "MIT" - }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -7463,26 +7828,19 @@ "license": "MIT" }, "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==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "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" + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" } }, - "node_modules/readable-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==", - "license": "MIT" - }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -7490,23 +7848,48 @@ "dev": true, "license": "MIT", "dependencies": { - "picomatch": "^2.2.1" + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.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": ">=8.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "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.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.6", + "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-errors": "^1.3.0", - "set-function-name": "^2.0.1" + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -7531,19 +7914,22 @@ "license": "MIT" }, "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" } @@ -7581,9 +7967,9 @@ } }, "node_modules/resolve.exports": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", - "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz", + "integrity": "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==", "dev": true, "license": "MIT", "engines": { @@ -7591,26 +7977,55 @@ } }, "node_modules/restore-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", - "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", "dev": true, "license": "MIT", "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/restore-cursor/node_modules/onetime": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-function": "^5.0.0" + }, + "engines": { + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/restore-cursor/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, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "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": { @@ -7643,13 +8058,13 @@ } }, "node_modules/rollup": { - "version": "4.26.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.26.0.tgz", - "integrity": "sha512-ilcl12hnWonG8f+NxU6BlgysVA0gvY2l8N0R84S1HcINbW20bvwuCngJkkInV6LXhwRpucsW5k1ovDwEdBVrNg==", + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.5.tgz", + "integrity": "sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw==", "dev": true, "license": "MIT", "dependencies": { - "@types/estree": "1.0.6" + "@types/estree": "1.0.8" }, "bin": { "rollup": "dist/bin/rollup" @@ -7659,24 +8074,28 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.26.0", - "@rollup/rollup-android-arm64": "4.26.0", - "@rollup/rollup-darwin-arm64": "4.26.0", - "@rollup/rollup-darwin-x64": "4.26.0", - "@rollup/rollup-freebsd-arm64": "4.26.0", - "@rollup/rollup-freebsd-x64": "4.26.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.26.0", - "@rollup/rollup-linux-arm-musleabihf": "4.26.0", - "@rollup/rollup-linux-arm64-gnu": "4.26.0", - "@rollup/rollup-linux-arm64-musl": "4.26.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.26.0", - "@rollup/rollup-linux-riscv64-gnu": "4.26.0", - "@rollup/rollup-linux-s390x-gnu": "4.26.0", - "@rollup/rollup-linux-x64-gnu": "4.26.0", - "@rollup/rollup-linux-x64-musl": "4.26.0", - "@rollup/rollup-win32-arm64-msvc": "4.26.0", - "@rollup/rollup-win32-ia32-msvc": "4.26.0", - "@rollup/rollup-win32-x64-msvc": "4.26.0", + "@rollup/rollup-android-arm-eabi": "4.52.5", + "@rollup/rollup-android-arm64": "4.52.5", + "@rollup/rollup-darwin-arm64": "4.52.5", + "@rollup/rollup-darwin-x64": "4.52.5", + "@rollup/rollup-freebsd-arm64": "4.52.5", + "@rollup/rollup-freebsd-x64": "4.52.5", + "@rollup/rollup-linux-arm-gnueabihf": "4.52.5", + "@rollup/rollup-linux-arm-musleabihf": "4.52.5", + "@rollup/rollup-linux-arm64-gnu": "4.52.5", + "@rollup/rollup-linux-arm64-musl": "4.52.5", + "@rollup/rollup-linux-loong64-gnu": "4.52.5", + "@rollup/rollup-linux-ppc64-gnu": "4.52.5", + "@rollup/rollup-linux-riscv64-gnu": "4.52.5", + "@rollup/rollup-linux-riscv64-musl": "4.52.5", + "@rollup/rollup-linux-s390x-gnu": "4.52.5", + "@rollup/rollup-linux-x64-gnu": "4.52.5", + "@rollup/rollup-linux-x64-musl": "4.52.5", + "@rollup/rollup-openharmony-arm64": "4.52.5", + "@rollup/rollup-win32-arm64-msvc": "4.52.5", + "@rollup/rollup-win32-ia32-msvc": "4.52.5", + "@rollup/rollup-win32-x64-gnu": "4.52.5", + "@rollup/rollup-win32-x64-msvc": "4.52.5", "fsevents": "~2.3.2" } }, @@ -7711,15 +8130,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": { @@ -7729,13 +8149,6 @@ "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, - "license": "MIT" - }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -7756,16 +8169,33 @@ ], "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-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" @@ -7850,12 +8280,6 @@ "node": ">= 0.8" } }, - "node_modules/send/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==", - "license": "MIT" - }, "node_modules/serialize-javascript": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", @@ -7885,6 +8309,7 @@ "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", @@ -7914,6 +8339,21 @@ "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/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -7944,15 +8384,69 @@ } }, "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==", "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==", + "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==", + "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==", + "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" @@ -7982,9 +8476,9 @@ } }, "node_modules/simple-update-notifier/node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", "dev": true, "license": "ISC", "bin": { @@ -8028,9 +8522,9 @@ } }, "node_modules/slice-ansi/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==", + "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": { @@ -8058,12 +8552,12 @@ "license": "MIT" }, "node_modules/socks": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", - "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", + "version": "2.8.7", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.7.tgz", + "integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==", "license": "MIT", "dependencies": { - "ip-address": "^9.0.5", + "ip-address": "^10.0.1", "smart-buffer": "^4.2.0" }, "engines": { @@ -8072,12 +8566,12 @@ } }, "node_modules/socks-proxy-agent": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.4.tgz", - "integrity": "sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw==", + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", + "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", "license": "MIT", "dependencies": { - "agent-base": "^7.1.1", + "agent-base": "^7.1.2", "debug": "^4.3.4", "socks": "^2.8.3" }, @@ -8107,9 +8601,10 @@ } }, "node_modules/sprintf-js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", - "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, "license": "BSD-3-Clause" }, "node_modules/stack-utils": { @@ -8144,6 +8639,20 @@ "node": ">= 0.8" } }, + "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/streamsearch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", @@ -8153,34 +8662,25 @@ } }, "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.23.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.23.0.tgz", + "integrity": "sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==", "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": { - "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": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "license": "MIT", "dependencies": { - "safe-buffer": "~5.1.0" + "safe-buffer": "~5.2.0" } }, - "node_modules/string_decoder/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==", - "license": "MIT" - }, "node_modules/string-argv": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", @@ -8224,9 +8724,9 @@ } }, "node_modules/string-width/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "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": { @@ -8237,9 +8737,9 @@ } }, "node_modules/string-width/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.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", "dev": true, "license": "MIT", "dependencies": { @@ -8253,16 +8753,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" @@ -8272,16 +8775,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" } @@ -8382,34 +8889,33 @@ "license": "MIT" }, "node_modules/synckit": { - "version": "0.8.8", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.8.tgz", - "integrity": "sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==", + "version": "0.11.11", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.11.tgz", + "integrity": "sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==", "dev": true, "license": "MIT", "dependencies": { - "@pkgr/core": "^0.1.0", - "tslib": "^2.6.2" + "@pkgr/core": "^0.2.9" }, "engines": { "node": "^14.18.0 || >=16.0.0" }, "funding": { - "url": "https://opencollective.com/unts" + "url": "https://opencollective.com/synckit" } }, "node_modules/tar-fs": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.5.tgz", - "integrity": "sha512-JOgGAmZyMgbqpLwct7ZV8VzkEB6pxXFBVErLtb+XCOqzc6w1xiWKI9GVd6bwk68EX7eJ4DWmfXVmq8K2ziZTGg==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.1.tgz", + "integrity": "sha512-LZA0oaPOc2fVo82Txf3gw+AkEd38szODlptMYejQUhndHMLQ9M059uXR+AfS7DNo0NpINvSqDsvyaCrBVkptWg==", "license": "MIT", "dependencies": { "pump": "^3.0.0", "tar-stream": "^3.1.5" }, "optionalDependencies": { - "bare-fs": "^2.1.1", - "bare-path": "^2.1.0" + "bare-fs": "^4.0.1", + "bare-path": "^3.0.0" } }, "node_modules/tar-stream": { @@ -8433,14 +8939,14 @@ } }, "node_modules/terser": { - "version": "5.31.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.1.tgz", - "integrity": "sha512-37upzU1+viGvuFtBo9NPufCb9dwM0+l9hMxYyWfBA+fbwrPqNJAhbZ6W47bBFnZHKHTUBnMvi87434qq+qnxOg==", + "version": "5.44.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.44.0.tgz", + "integrity": "sha512-nIVck8DK+GM/0Frwd+nIhZ84pR/BX7rmXMfYwyg+Sri5oGVE99/E3KvXqpC2xHFxyqXyGHTKBSioxxplrO4I4w==", "dev": true, "license": "BSD-2-Clause", "dependencies": { "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", + "acorn": "^8.15.0", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, @@ -8485,9 +8991,9 @@ } }, "node_modules/text-decoder": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.1.0.tgz", - "integrity": "sha512-TmLJNj6UgX8xcUZo4UDStGQtDiTzF7BzWlzn9g7UWrjkpHr5uJTK1ld16wZ3LXb2vb6jH8qU89dW5whuMdXYdw==", + "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==", "license": "Apache-2.0", "dependencies": { "b4a": "^1.6.4" @@ -8513,16 +9019,6 @@ "dev": true, "license": "BSD-3-Clause" }, - "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, - "license": "MIT", - "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", @@ -8570,19 +9066,10 @@ "node": ">=6" } }, - "node_modules/tough-cookie/node_modules/universalify": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", - "license": "MIT", - "engines": { - "node": ">= 4.0.0" - } - }, "node_modules/tr46": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz", - "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz", + "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==", "license": "MIT", "dependencies": { "punycode": "^2.3.1" @@ -8628,9 +9115,9 @@ } }, "node_modules/tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", + "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/type-check": { @@ -8683,32 +9170,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" @@ -8718,18 +9205,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" @@ -8739,18 +9227,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" @@ -8766,16 +9254,19 @@ "license": "MIT" }, "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" @@ -8799,19 +9290,19 @@ "license": "MIT" }, "node_modules/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": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", "devOptional": true, "license": "MIT" }, "node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", "license": "MIT", "engines": { - "node": ">= 10.0.0" + "node": ">= 4.0.0" } }, "node_modules/unpipe": { @@ -8824,9 +9315,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", - "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz", + "integrity": "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==", "dev": true, "funding": [ { @@ -8844,8 +9335,8 @@ ], "license": "MIT", "dependencies": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" + "escalade": "^3.2.0", + "picocolors": "^1.1.1" }, "bin": { "update-browserslist-db": "cli.js" @@ -8997,12 +9488,12 @@ } }, "node_modules/whatwg-url": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.0.0.tgz", - "integrity": "sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==", + "version": "14.2.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", + "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==", "license": "MIT", "dependencies": { - "tr46": "^5.0.0", + "tr46": "^5.1.0", "webidl-conversions": "^7.0.0" }, "engines": { @@ -9026,33 +9517,85 @@ } }, "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-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" } }, "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.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", "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": { @@ -9073,9 +9616,9 @@ } }, "node_modules/wrap-ansi": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", - "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", "dev": true, "license": "MIT", "dependencies": { @@ -9091,9 +9634,9 @@ } }, "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "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": { @@ -9104,9 +9647,9 @@ } }, "node_modules/wrap-ansi/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==", + "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": { @@ -9117,9 +9660,9 @@ } }, "node_modules/wrap-ansi/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.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", "dev": true, "license": "MIT", "dependencies": { @@ -9153,9 +9696,9 @@ } }, "node_modules/ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", "license": "MIT", "engines": { "node": ">=10.0.0" @@ -9214,16 +9757,16 @@ "license": "ISC" }, "node_modules/yaml": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz", - "integrity": "sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz", + "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==", "dev": true, "license": "ISC", "bin": { "yaml": "bin.mjs" }, "engines": { - "node": ">= 14" + "node": ">= 14.6" } }, "node_modules/yargs": { @@ -9306,9 +9849,9 @@ } }, "node_modules/zod": { - "version": "3.23.8", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", - "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" diff --git a/package.json b/package.json index ff281633..4379e996 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ "express-rate-limit": "^7.3.1", "https-proxy-agent": "^7.0.5", "jsdom": "^24.1.0", - "multer": "^1.4.5-lts.1", + "multer": "^2.0.2", "prompts": "^2.4.2", "puppeteer": "^22.12.1", "tarn": "^3.0.2", From f390c24679b14dea469a9764bd2d699c31fa7dea Mon Sep 17 00:00:00 2001 From: vikpeni Date: Fri, 31 Oct 2025 10:22:25 -0400 Subject: [PATCH 2/2] Updating Multer to ^2.0.2 --- dist/index.cjs | 4 ++-- dist/index.esm.js | 2 +- dist/index.esm.js.map | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dist/index.cjs b/dist/index.cjs index 3617a540..fb414cea 100644 --- a/dist/index.cjs +++ b/dist/index.cjs @@ -1,2 +1,2 @@ -"use strict";require("colors");var e=require("fs"),t=require("path"),r=require("https-proxy-agent"),o=require("prompts"),i=require("dotenv"),s=require("zod"),n=require("url"),a=require("http"),l=require("https"),c=require("tarn"),p=require("uuid"),h=require("puppeteer"),u=require("jsdom"),d=require("dompurify"),g=require("cors"),m=require("express"),f=require("multer"),v=require("express-rate-limit"),y="undefined"!=typeof document?document.currentScript:null;const b={core:["highcharts","highcharts-more","highcharts-3d"],modules:["stock","map","gantt","exporting","parallel-coordinates","accessibility","boost-canvas","boost","data","data-tools","draggable-points","static-scale","broken-axis","heatmap","tilemap","tiledwebmap","timeline","treemap","treegraph","item-series","drilldown","histogram-bellcurve","bullet","funnel","funnel3d","geoheatmap","pyramid3d","networkgraph","overlapping-datalabels","pareto","pattern-fill","pictorial","price-indicator","sankey","arc-diagram","dependency-wheel","series-label","series-on-point","solid-gauge","sonification","streamgraph","sunburst","variable-pie","variwide","vector","venn","windbarb","wordcloud","xrange","no-data-to-display","drag-panes","debugger","dumbbell","lollipop","cylinder","organization","dotplot","marker-clusters","hollowcandlestick","heikinashi","flowmap","export-data","navigator","textpath"],indicators:["indicators-all"],custom:["https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.30.1/moment.min.js","https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.45/moment-timezone-with-data.min.js"]},w={puppeteer:{args:{value:["--allow-running-insecure-content","--ash-no-nudges","--autoplay-policy=user-gesture-required","--block-new-web-contents","--disable-accelerated-2d-canvas","--disable-background-networking","--disable-background-timer-throttling","--disable-backgrounding-occluded-windows","--disable-breakpad","--disable-checker-imaging","--disable-client-side-phishing-detection","--disable-component-extensions-with-background-pages","--disable-component-update","--disable-default-apps","--disable-dev-shm-usage","--disable-domain-reliability","--disable-extensions","--disable-features=CalculateNativeWinOcclusion,InterestFeedContentSuggestions,WebOTP","--disable-hang-monitor","--disable-ipc-flooding-protection","--disable-logging","--disable-notifications","--disable-offer-store-unmasked-wallet-cards","--disable-popup-blocking","--disable-print-preview","--disable-prompt-on-repost","--disable-renderer-backgrounding","--disable-search-engine-choice-screen","--disable-session-crashed-bubble","--disable-setuid-sandbox","--disable-site-isolation-trials","--disable-speech-api","--disable-sync","--enable-unsafe-webgpu","--hide-crash-restore-bubble","--hide-scrollbars","--metrics-recording-only","--mute-audio","--no-default-browser-check","--no-first-run","--no-pings","--pipe","--no-startup-window","--password-store=basic","--process-per-tab","--use-mock-keychain"],type:"string[]",description:"Arguments array to send to Puppeteer."},tempDir:{value:"./tmp/",type:"string",envLink:"PUPPETEER_TEMP_DIR",description:"The directory for Puppeteer to store temporary files."}},highcharts:{version:{value:"latest",type:"string",envLink:"HIGHCHARTS_VERSION",description:"The Highcharts version to be used."},cdnURL:{value:"https://code.highcharts.com/",type:"string",envLink:"HIGHCHARTS_CDN_URL",description:"The CDN URL for Highcharts scripts to be used."},coreScripts:{value:b.core,type:"string[]",envLink:"HIGHCHARTS_CORE_SCRIPTS",description:"The core Highcharts scripts to fetch."},moduleScripts:{value:b.modules,type:"string[]",envLink:"HIGHCHARTS_MODULE_SCRIPTS",description:"The modules of Highcharts to fetch."},indicatorScripts:{value:b.indicators,type:"string[]",envLink:"HIGHCHARTS_INDICATOR_SCRIPTS",description:"The indicators of Highcharts to fetch."},customScripts:{value:b.custom,type:"string[]",description:"Additional custom scripts or dependencies to fetch."},forceFetch:{value:!1,type:"boolean",envLink:"HIGHCHARTS_FORCE_FETCH",description:"The flag to determine whether to refetch all scripts after each server rerun."},cachePath:{value:".cache",type:"string",envLink:"HIGHCHARTS_CACHE_PATH",description:"The path to the cache directory. It is used to store the Highcharts scripts and custom scripts."}},export:{infile:{value:!1,type:"string",description:"The input file should include a name and a type (json or svg). It must be correctly formatted as a JSON or SVG file."},instr:{value:!1,type:"string",description:"Input, provided in the form of a stringified JSON or SVG file, will override the --infile option."},options:{value:!1,type:"string",description:"An alias for the --instr option."},outfile:{value:!1,type:"string",description:"The output filename along with a type (jpeg, png, pdf, or svg). This will ignore the --type flag."},type:{value:"png",type:"string",envLink:"EXPORT_TYPE",description:"The file export format. It can be jpeg, png, pdf, or svg."},constr:{value:"chart",type:"string",envLink:"EXPORT_CONSTR",description:"The constructor to use. Can be chart, stockChart, mapChart, or ganttChart."},defaultHeight:{value:400,type:"number",envLink:"EXPORT_DEFAULT_HEIGHT",description:"the default height of the exported chart. Used when no value is set."},defaultWidth:{value:600,type:"number",envLink:"EXPORT_DEFAULT_WIDTH",description:"The default width of the exported chart. Used when no value is set."},defaultScale:{value:1,type:"number",envLink:"EXPORT_DEFAULT_SCALE",description:"The default scale of the exported chart. Used when no value is set."},height:{value:!1,type:"number",description:"The height of the exported chart, overriding the option in the chart settings."},width:{value:!1,type:"number",description:"The width of the exported chart, overriding the option in the chart settings."},scale:{value:!1,type:"number",description:"The scale of the exported chart, overriding the option in the chart settings. Ranges between 0.1 and 5.0."},globalOptions:{value:!1,type:"string",description:"Either a stringified JSON or a filename containing options to be passed into the Highcharts.setOptions."},themeOptions:{value:!1,type:"string",description:"Either a stringified JSON or a filename containing theme options to be passed into the Highcharts.setOptions."},batch:{value:!1,type:"string",description:'Initiates a batch job with a string containing input/output pairs: "in=out;in=out;...".'},rasterizationTimeout:{value:1500,type:"number",envLink:"EXPORT_RASTERIZATION_TIMEOUT",description:"The duration in milliseconds to wait for rendering a webpage."}},customLogic:{allowCodeExecution:{value:!1,type:"boolean",envLink:"CUSTOM_LOGIC_ALLOW_CODE_EXECUTION",description:"Controls whether the execution of arbitrary code is allowed during the exporting process."},allowFileResources:{value:!1,type:"boolean",envLink:"CUSTOM_LOGIC_ALLOW_FILE_RESOURCES",description:"Controls the ability to inject resources from the filesystem. This setting has no effect when running as a server."},customCode:{value:!1,type:"string",description:"Custom code to execute before chart initialization. It can be a function, code wrapped within a function, or a filename with the .js extension."},callback:{value:!1,type:"string",description:"JavaScript code to run during construction. It can be a function or a filename with the .js extension."},resources:{value:!1,type:"string",description:"Additional resource in the form of a stringified JSON, which may contain files, js, and css sections."},loadConfig:{value:!1,type:"string",legacyName:"fromFile",description:"A file containing a pre-defined configuration to use."},createConfig:{value:!1,type:"string",description:"Enables setting options through a prompt and saving them in a provided config file."}},server:{maxUploadSize:{value:3,type:"number",envLink:"SERVER_MAX_UPLOAD_SIZE",description:"The maximum upload size, in MB, for the server."},enable:{value:!1,type:"boolean",envLink:"SERVER_ENABLE",cliName:"enableServer",description:"When set to true, the server starts on the local IP address 0.0.0.0."},host:{value:"0.0.0.0",type:"string",envLink:"SERVER_HOST",description:"The hostname of the server. Additionally, it starts a server on the provided hostname."},port:{value:7801,type:"number",envLink:"SERVER_PORT",description:"The server port when enabled."},benchmarking:{value:!1,type:"boolean",envLink:"SERVER_BENCHMARKING",cliName:"serverBenchmarking",description:"Indicates whether to display the duration, in milliseconds, of specific actions that occur on the server while serving a request."},proxy:{host:{value:!1,type:"string",envLink:"SERVER_PROXY_HOST",cliName:"proxyHost",description:"The host of the proxy server to use, if it exists."},port:{value:8080,type:"number",envLink:"SERVER_PROXY_PORT",cliName:"proxyPort",description:"The port of the proxy server to use, if it exists."},username:{value:!1,type:"string",envLink:"SERVER_PROXY_USERNAME",cliName:"proxyUsername",description:"The username for the proxy server, if it exists."},password:{value:!1,type:"string",envLink:"SERVER_PROXY_PASSWORD",cliName:"proxyPassword",description:"The password for the proxy server, if it exists."},timeout:{value:5e3,type:"number",envLink:"SERVER_PROXY_TIMEOUT",cliName:"proxyTimeout",description:"The timeout for the proxy server to use, if it exists."}},rateLimiting:{enable:{value:!1,type:"boolean",envLink:"SERVER_RATE_LIMITING_ENABLE",cliName:"enableRateLimiting",description:"Enables rate limiting for the server."},maxRequests:{value:10,type:"number",envLink:"SERVER_RATE_LIMITING_MAX_REQUESTS",legacyName:"rateLimit",description:"The maximum number of requests allowed in one minute."},window:{value:1,type:"number",envLink:"SERVER_RATE_LIMITING_WINDOW",description:"The time window, in minutes, for the rate limiting."},delay:{value:0,type:"number",envLink:"SERVER_RATE_LIMITING_DELAY",description:"The delay duration for each successive request before reaching the maximum limit."},trustProxy:{value:!1,type:"boolean",envLink:"SERVER_RATE_LIMITING_TRUST_PROXY",description:"Set this to true if the server is behind a load balancer."},skipKey:{value:!1,type:"string",envLink:"SERVER_RATE_LIMITING_SKIP_KEY",description:"Allows bypassing the rate limiter and should be provided with the skipToken argument."},skipToken:{value:!1,type:"string",envLink:"SERVER_RATE_LIMITING_SKIP_TOKEN",description:"Allows bypassing the rate limiter and should be provided with the skipKey argument."}},ssl:{enable:{value:!1,type:"boolean",envLink:"SERVER_SSL_ENABLE",cliName:"enableSsl",description:"Enables or disables the SSL protocol."},force:{value:!1,type:"boolean",envLink:"SERVER_SSL_FORCE",cliName:"sslForce",legacyName:"sslOnly",description:"When set to true, the server is forced to serve only over HTTPS."},port:{value:443,type:"number",envLink:"SERVER_SSL_PORT",cliName:"sslPort",description:"The port on which to run the SSL server."},certPath:{value:!1,type:"string",envLink:"SERVER_SSL_CERT_PATH",legacyName:"sslPath",description:"The path to the SSL certificate/key file."}}},pool:{minWorkers:{value:4,type:"number",envLink:"POOL_MIN_WORKERS",description:"The number of minimum and initial pool workers to spawn."},maxWorkers:{value:8,type:"number",envLink:"POOL_MAX_WORKERS",legacyName:"workers",description:"The number of maximum pool workers to spawn."},workLimit:{value:40,type:"number",envLink:"POOL_WORK_LIMIT",description:"The number of work pieces that can be performed before restarting the worker process."},acquireTimeout:{value:5e3,type:"number",envLink:"POOL_ACQUIRE_TIMEOUT",description:"The duration, in milliseconds, to wait for acquiring a resource."},createTimeout:{value:5e3,type:"number",envLink:"POOL_CREATE_TIMEOUT",description:"The duration, in milliseconds, to wait for creating a resource."},destroyTimeout:{value:5e3,type:"number",envLink:"POOL_DESTROY_TIMEOUT",description:"The duration, in milliseconds, to wait for destroying a resource."},idleTimeout:{value:3e4,type:"number",envLink:"POOL_IDLE_TIMEOUT",description:"The duration, in milliseconds, after which an idle resource is destroyed."},createRetryInterval:{value:200,type:"number",envLink:"POOL_CREATE_RETRY_INTERVAL",description:"The duration, in milliseconds, to wait before retrying the create process in case of a failure."},reaperInterval:{value:1e3,type:"number",envLink:"POOL_REAPER_INTERVAL",description:"The duration, in milliseconds, after which the check for idle resources to destroy is triggered."},benchmarking:{value:!1,type:"boolean",envLink:"POOL_BENCHMARKING",cliName:"poolBenchmarking",description:"Indicate whether to show statistics for the pool of resources or not."}},logging:{level:{value:4,type:"number",envLink:"LOGGING_LEVEL",cliName:"logLevel",description:"The logging level to be used."},file:{value:"highcharts-export-server.log",type:"string",envLink:"LOGGING_FILE",cliName:"logFile",description:"The name of a log file. The `logToFile` and `logDest` options also need to be set to enable file logging."},dest:{value:"log/",type:"string",envLink:"LOGGING_DEST",cliName:"logDest",description:"The path to store log files. The `logToFile` option also needs to be set to enable file logging."},toConsole:{value:!0,type:"boolean",envLink:"LOGGING_TO_CONSOLE",cliName:"logToConsole",description:"Enables or disables showing logs in the console."},toFile:{value:!0,type:"boolean",envLink:"LOGGING_TO_FILE",cliName:"logToFile",description:"Enables or disables creation of the log directory and saving the log into a .log file."}},ui:{enable:{value:!1,type:"boolean",envLink:"UI_ENABLE",cliName:"enableUi",description:"Enables or disables the user interface (UI) for the export server."},route:{value:"/",type:"string",envLink:"UI_ROUTE",cliName:"uiRoute",description:"The endpoint route to which the user interface (UI) should be attached."}},other:{nodeEnv:{value:"production",type:"string",envLink:"OTHER_NODE_ENV",description:"The type of Node.js environment."},listenToProcessExits:{value:!0,type:"boolean",envLink:"OTHER_LISTEN_TO_PROCESS_EXITS",description:"Decides whether or not to attach process.exit handlers."},noLogo:{value:!1,type:"boolean",envLink:"OTHER_NO_LOGO",description:"Skip printing the logo on a startup. Will be replaced by a simple text."},hardResetPage:{value:!1,type:"boolean",envLink:"OTHER_HARD_RESET_PAGE",description:"Decides if the page content should be reset entirely."},browserShellMode:{value:!0,type:"boolean",envLink:"OTHER_BROWSER_SHELL_MODE",description:"Decides if the browser runs in the shell mode."}},debug:{enable:{value:!1,type:"boolean",envLink:"DEBUG_ENABLE",cliName:"enableDebug",description:"Enables or disables debug mode for the underlying browser."},headless:{value:!0,type:"boolean",envLink:"DEBUG_HEADLESS",description:"Controls the mode in which the browser is launched when in the debug mode."},devtools:{value:!1,type:"boolean",envLink:"DEBUG_DEVTOOLS",description:"Decides whether to enable DevTools when the browser is in a headful state."},listenToConsole:{value:!1,type:"boolean",envLink:"DEBUG_LISTEN_TO_CONSOLE",description:"Decides whether to enable a listener for console messages sent from the browser."},dumpio:{value:!1,type:"boolean",envLink:"DEBUG_DUMPIO",description:"Redirects browser process stdout and stderr to process.stdout and process.stderr."},slowMo:{value:0,type:"number",envLink:"DEBUG_SLOW_MO",description:"Slows down Puppeteer operations by the specified number of milliseconds."},debuggingPort:{value:9222,type:"number",envLink:"DEBUG_DEBUGGING_PORT",description:"Specifies the debugging port."}}},E={puppeteer:[{type:"list",name:"args",message:"Puppeteer arguments",initial:w.puppeteer.args.value.join(","),separator:","}],highcharts:[{type:"text",name:"version",message:"Highcharts version",initial:w.highcharts.version.value},{type:"text",name:"cdnURL",message:"The URL of CDN",initial:w.highcharts.cdnURL.value},{type:"multiselect",name:"coreScripts",message:"Available core scripts",instructions:"Space: Select specific, A: Select all, Enter: Confirm.",choices:w.highcharts.coreScripts.value},{type:"multiselect",name:"moduleScripts",message:"Available module scripts",instructions:"Space: Select specific, A: Select all, Enter: Confirm.",choices:w.highcharts.moduleScripts.value},{type:"multiselect",name:"indicatorScripts",message:"Available indicator scripts",instructions:"Space: Select specific, A: Select all, Enter: Confirm.",choices:w.highcharts.indicatorScripts.value},{type:"list",name:"customScripts",message:"Custom scripts",initial:w.highcharts.customScripts.value.join(","),separator:","},{type:"toggle",name:"forceFetch",message:"Force re-fetch the scripts",initial:w.highcharts.forceFetch.value},{type:"text",name:"cachePath",message:"The path to the cache directory",initial:w.highcharts.cachePath.value}],export:[{type:"select",name:"type",message:"The default export file type",hint:`Default: ${w.export.type.value}`,initial:0,choices:["png","jpeg","pdf","svg"]},{type:"select",name:"constr",message:"The default constructor for Highcharts",hint:`Default: ${w.export.constr.value}`,initial:0,choices:["chart","stockChart","mapChart","ganttChart"]},{type:"number",name:"defaultHeight",message:"The default fallback height of the exported chart",initial:w.export.defaultHeight.value},{type:"number",name:"defaultWidth",message:"The default fallback width of the exported chart",initial:w.export.defaultWidth.value},{type:"number",name:"defaultScale",message:"The default fallback scale of the exported chart",initial:w.export.defaultScale.value,min:.1,max:5},{type:"number",name:"rasterizationTimeout",message:"The rendering webpage timeout in milliseconds",initial:w.export.rasterizationTimeout.value}],customLogic:[{type:"toggle",name:"allowCodeExecution",message:"Enable execution of custom code",initial:w.customLogic.allowCodeExecution.value},{type:"toggle",name:"allowFileResources",message:"Enable file resources",initial:w.customLogic.allowFileResources.value}],server:[{type:"toggle",name:"enable",message:"Starts the server on 0.0.0.0",initial:w.server.enable.value},{type:"text",name:"host",message:"Server hostname",initial:w.server.host.value},{type:"number",name:"port",message:"Server port",initial:w.server.port.value},{type:"toggle",name:"benchmarking",message:"Enable server benchmarking",initial:w.server.benchmarking.value},{type:"text",name:"proxy.host",message:"The host of the proxy server to use",initial:w.server.proxy.host.value},{type:"number",name:"proxy.port",message:"The port of the proxy server to use",initial:w.server.proxy.port.value},{type:"number",name:"proxy.timeout",message:"The timeout for the proxy server to use",initial:w.server.proxy.timeout.value},{type:"toggle",name:"rateLimiting.enable",message:"Enable rate limiting",initial:w.server.rateLimiting.enable.value},{type:"number",name:"rateLimiting.maxRequests",message:"The maximum requests allowed per minute",initial:w.server.rateLimiting.maxRequests.value},{type:"number",name:"rateLimiting.window",message:"The rate-limiting time window in minutes",initial:w.server.rateLimiting.window.value},{type:"number",name:"rateLimiting.delay",message:"The delay for each successive request before reaching the maximum",initial:w.server.rateLimiting.delay.value},{type:"toggle",name:"rateLimiting.trustProxy",message:"Set to true if behind a load balancer",initial:w.server.rateLimiting.trustProxy.value},{type:"text",name:"rateLimiting.skipKey",message:"Allows bypassing the rate limiter when provided with the skipToken argument",initial:w.server.rateLimiting.skipKey.value},{type:"text",name:"rateLimiting.skipToken",message:"Allows bypassing the rate limiter when provided with the skipKey argument",initial:w.server.rateLimiting.skipToken.value},{type:"toggle",name:"ssl.enable",message:"Enable SSL protocol",initial:w.server.ssl.enable.value},{type:"toggle",name:"ssl.force",message:"Force serving only over HTTPS",initial:w.server.ssl.force.value},{type:"number",name:"ssl.port",message:"SSL server port",initial:w.server.ssl.port.value},{type:"text",name:"ssl.certPath",message:"The path to find the SSL certificate/key",initial:w.server.ssl.certPath.value}],pool:[{type:"number",name:"minWorkers",message:"The initial number of workers to spawn",initial:w.pool.minWorkers.value},{type:"number",name:"maxWorkers",message:"The maximum number of workers to spawn",initial:w.pool.maxWorkers.value},{type:"number",name:"workLimit",message:"The pieces of work that can be performed before restarting a Puppeteer process",initial:w.pool.workLimit.value},{type:"number",name:"acquireTimeout",message:"The number of milliseconds to wait for acquiring a resource",initial:w.pool.acquireTimeout.value},{type:"number",name:"createTimeout",message:"The number of milliseconds to wait for creating a resource",initial:w.pool.createTimeout.value},{type:"number",name:"destroyTimeout",message:"The number of milliseconds to wait for destroying a resource",initial:w.pool.destroyTimeout.value},{type:"number",name:"idleTimeout",message:"The number of milliseconds after an idle resource is destroyed",initial:w.pool.idleTimeout.value},{type:"number",name:"createRetryInterval",message:"The retry interval in milliseconds after a create process fails",initial:w.pool.createRetryInterval.value},{type:"number",name:"reaperInterval",message:"The reaper interval in milliseconds after triggering the check for idle resources to destroy",initial:w.pool.reaperInterval.value},{type:"toggle",name:"benchmarking",message:"Enable benchmarking for a resource pool",initial:w.pool.benchmarking.value}],logging:[{type:"number",name:"level",message:"The log level (0: silent, 1: error, 2: warning, 3: notice, 4: verbose, 5: benchmark)",initial:w.logging.level.value,round:0,min:0,max:5},{type:"text",name:"file",message:"A log file name. Set with --toFile and --logDest to enable file logging",initial:w.logging.file.value},{type:"text",name:"dest",message:"The path to a log file when the file logging is enabled",initial:w.logging.dest.value},{type:"toggle",name:"toConsole",message:"Enable logging to the console",initial:w.logging.toConsole.value},{type:"toggle",name:"toFile",message:"Enables logging to a file",initial:w.logging.toFile.value}],ui:[{type:"toggle",name:"enable",message:"Enable UI for the export server",initial:w.ui.enable.value},{type:"text",name:"route",message:"A route to attach the UI",initial:w.ui.route.value}],other:[{type:"text",name:"nodeEnv",message:"The type of Node.js environment",initial:w.other.nodeEnv.value},{type:"toggle",name:"listenToProcessExits",message:"Set to false to skip attaching process.exit handlers",initial:w.other.listenToProcessExits.value},{type:"toggle",name:"noLogo",message:"Skip printing the logo on startup. Replaced by simple text",initial:w.other.noLogo.value},{type:"toggle",name:"hardResetPage",message:"Decides if the page content should be reset entirely",initial:w.other.hardResetPage.value},{type:"toggle",name:"browserShellMode",message:"Decides if the browser runs in the shell mode",initial:w.other.browserShellMode.value}],debug:[{type:"toggle",name:"enable",message:"Enables debug mode for the browser instance",initial:w.debug.enable.value},{type:"toggle",name:"headless",message:"The mode setting for the browser",initial:w.debug.headless.value},{type:"toggle",name:"devtools",message:"The DevTools for the headful browser",initial:w.debug.devtools.value},{type:"toggle",name:"listenToConsole",message:"The event listener for console messages from the browser",initial:w.debug.listenToConsole.value},{type:"toggle",name:"dumpio",message:"Redirects the browser stdout and stderr to NodeJS process",initial:w.debug.dumpio.value},{type:"number",name:"slowMo",message:"Puppeteer operations slow down in milliseconds",initial:w.debug.slowMo.value},{type:"number",name:"debuggingPort",message:"The port number for debugging",initial:w.debug.debuggingPort.value}]},T=["options","globalOptions","themeOptions","resources","payload"],S={},x=(e,t="")=>{Object.keys(e).forEach((r=>{if(!["puppeteer","highcharts"].includes(r)){const o=e[r];void 0===o.value?x(o,`${t}.${r}`):(S[o.cliName||r]=`${t}.${r}`.substring(1),void 0!==o.legacyName&&(S[o.legacyName]=`${t}.${r}`.substring(1)))}}))};x(w),i.config();const R=e=>s.z.string().transform((t=>t.split(",").map((e=>e.trim())).filter((t=>e.includes(t))))).transform((e=>e.length?e:void 0)),_=()=>s.z.enum(["true","false",""]).transform((e=>""!==e?"true"===e:void 0)),O=e=>s.z.enum([...e,""]).transform((e=>""!==e?e:void 0)),L=()=>s.z.string().trim().refine((e=>!["false","undefined","null","NaN"].includes(e)||""===e),(e=>({message:`The string contains forbidden values, received '${e}'`}))).transform((e=>""!==e?e:void 0)),k=()=>s.z.string().trim().refine((e=>/^(\.\/|\.\.\/|\/|[a-zA-Z]:\\|[a-zA-Z]:\/)?((?:[\w-]+)[\\/]?)+$/.test(e)),{},{message:"The string is an invalid path directory string."}),I=()=>s.z.string().trim().refine((e=>""===e||!isNaN(parseFloat(e))&&parseFloat(e)>0),(e=>({message:`The value must be numeric and positive, received '${e}'`}))).transform((e=>""!==e?parseFloat(e):void 0)),C=()=>s.z.string().trim().refine((e=>""===e||!isNaN(parseFloat(e))&&parseFloat(e)>=0),(e=>({message:`The value must be numeric and non-negative, received '${e}'`}))).transform((e=>""!==e?parseFloat(e):void 0)),N=s.z.object({PUPPETEER_TEMP_DIR:k(),HIGHCHARTS_VERSION:s.z.string().trim().refine((e=>/^(latest|\d+(\.\d+){0,2})$/.test(e)||""===e),(e=>({message:`HIGHCHARTS_VERSION must be 'latest', a major version, or in the form XX.YY.ZZ, received '${e}'`}))).transform((e=>""!==e?e:void 0)),HIGHCHARTS_CDN_URL:s.z.string().trim().refine((e=>e.startsWith("https://")||e.startsWith("http://")||""===e),(e=>({message:`Invalid value for HIGHCHARTS_CDN_URL. It should start with http:// or https://, received '${e}'`}))).transform((e=>""!==e?e:void 0)),HIGHCHARTS_CORE_SCRIPTS:R(b.core),HIGHCHARTS_MODULE_SCRIPTS:R(b.modules),HIGHCHARTS_INDICATOR_SCRIPTS:R(b.indicators),HIGHCHARTS_FORCE_FETCH:_(),HIGHCHARTS_CACHE_PATH:L(),HIGHCHARTS_ADMIN_TOKEN:L(),EXPORT_TYPE:O(["jpeg","png","pdf","svg"]),EXPORT_CONSTR:O(["chart","stockChart","mapChart","ganttChart"]),EXPORT_DEFAULT_HEIGHT:I(),EXPORT_DEFAULT_WIDTH:I(),EXPORT_DEFAULT_SCALE:I(),EXPORT_RASTERIZATION_TIMEOUT:C(),CUSTOM_LOGIC_ALLOW_CODE_EXECUTION:_(),CUSTOM_LOGIC_ALLOW_FILE_RESOURCES:_(),SERVER_ENABLE:_(),SERVER_HOST:L(),SERVER_PORT:I(),SERVER_MAX_UPLOAD_SIZE:I(),SERVER_BENCHMARKING:_(),SERVER_PROXY_HOST:L(),SERVER_PROXY_PORT:I(),SERVER_PROXY_USERNAME:L(),SERVER_PROXY_PASSWORD:L(),SERVER_PROXY_TIMEOUT:C(),SERVER_RATE_LIMITING_ENABLE:_(),SERVER_RATE_LIMITING_MAX_REQUESTS:C(),SERVER_RATE_LIMITING_WINDOW:C(),SERVER_RATE_LIMITING_DELAY:C(),SERVER_RATE_LIMITING_TRUST_PROXY:_(),SERVER_RATE_LIMITING_SKIP_KEY:L(),SERVER_RATE_LIMITING_SKIP_TOKEN:L(),SERVER_SSL_ENABLE:_(),SERVER_SSL_FORCE:_(),SERVER_SSL_PORT:I(),SERVER_SSL_CERT_PATH:L(),POOL_MIN_WORKERS:C(),POOL_MAX_WORKERS:C(),POOL_WORK_LIMIT:I(),POOL_ACQUIRE_TIMEOUT:C(),POOL_CREATE_TIMEOUT:C(),POOL_DESTROY_TIMEOUT:C(),POOL_IDLE_TIMEOUT:C(),POOL_CREATE_RETRY_INTERVAL:C(),POOL_REAPER_INTERVAL:C(),POOL_BENCHMARKING:_(),LOGGING_LEVEL:s.z.string().trim().refine((e=>""===e||!isNaN(parseFloat(e))&&parseFloat(e)>=0&&parseFloat(e)<=5),(e=>({message:`Invalid value for LOGGING_LEVEL. We only accept values from 0 to 5 as logging levels, received '${e}'`}))).transform((e=>""!==e?parseFloat(e):void 0)),LOGGING_FILE:L(),LOGGING_DEST:L(),LOGGING_TO_CONSOLE:_(),LOGGING_TO_FILE:_(),UI_ENABLE:_(),UI_ROUTE:L(),OTHER_NODE_ENV:O(["development","production","test"]),OTHER_LISTEN_TO_PROCESS_EXITS:_(),OTHER_NO_LOGO:_(),OTHER_HARD_RESET_PAGE:_(),OTHER_BROWSER_SHELL_MODE:_(),OTHER_ALLOW_XLINK:_(),DEBUG_ENABLE:_(),DEBUG_HEADLESS:_(),DEBUG_DEVTOOLS:_(),DEBUG_LISTEN_TO_CONSOLE:_(),DEBUG_DUMPIO:_(),DEBUG_SLOW_MO:C(),DEBUG_DEBUGGING_PORT:I()}).partial().parse(process.env),A=["red","yellow","blue","gray","green"];let P={toConsole:!0,toFile:!1,pathCreated:!1,levelsDesc:[{title:"error",color:A[0]},{title:"warning",color:A[1]},{title:"notice",color:A[2]},{title:"verbose",color:A[3]},{title:"benchmark",color:A[4]}],listeners:[]};const H=(t,r)=>{P.pathCreated||(!e.existsSync(P.dest)&&e.mkdirSync(P.dest),P.pathCreated=!0),e.appendFile(`${P.dest}${P.file}`,[r].concat(t).join(" ")+"\n",(e=>{e&&(console.log(`[logger] Unable to write to log file: ${e}`),P.toFile=!1)}))},$=(...e)=>{const[t,...r]=e,{levelsDesc:o,level:i}=P;if(5!==t&&(0===t||t>i||i>o.length))return;const s=`${(new Date).toString().split("(")[0].trim()} [${o[t-1].title}] -`;P.listeners.forEach((e=>{e(s,r.join(" "))})),P.toConsole&&console.log.apply(void 0,[s.toString()[P.levelsDesc[t-1].color]].concat(r)),P.toFile&&H(r,s)},D=(e,t,r)=>{const o=r||t.message,{level:i,levelsDesc:s}=P;if(0===e||e>i||i>s.length)return;const n=`${(new Date).toString().split("(")[0].trim()} [${s[e-1].title}] -`,a=t.message!==t.stackMessage||void 0===t.stackMessage?t.stack:t.stack.split("\n").slice(1).join("\n"),l=[o,"\n",a];P.toConsole&&console.log.apply(void 0,[n.toString()[P.levelsDesc[e-1].color]].concat([o[A[e-1]],"\n",a])),P.listeners.forEach((e=>{e(n,l.join(" "))})),P.toFile&&H(l,n)},U=e=>{e>=0&&e<=P.levelsDesc.length&&(P.level=e)},G=(e,t)=>{if(P={...P,dest:e||P.dest,file:t||P.file,toFile:!0},0===P.dest.length)return $(1,"[logger] File logging initialization: no path supplied.");P.dest.endsWith("/")||(P.dest+="/")},F=n.fileURLToPath(new URL("../.","undefined"==typeof document?require("url").pathToFileURL(__filename).href:y&&"SCRIPT"===y.tagName.toUpperCase()&&y.src||new URL("index.cjs",document.baseURI).href)),j=(e,t)=>{const r=["png","jpeg","pdf","svg"];if(t){const o=t.split(".").pop();"jpg"===o?e="jpeg":r.includes(o)&&e!==o&&(e=o)}return{"image/png":"png","image/jpeg":"jpeg","application/pdf":"pdf","image/svg+xml":"svg"}[e]||r.find((t=>t===e))||"png"},M=(t=!1,r)=>{const o=["js","css","files"];let i=t,s=!1;if(r&&t.endsWith(".json"))try{i=V(e.readFileSync(t,"utf8"))}catch(e){return D(2,e,"[cli] No resources found.")}else i=V(t),i&&!r&&delete i.files;for(const e in i)o.includes(e)?s||(s=!0):delete i[e];return s?(i.files&&(i.files=i.files.map((e=>e.trim())),(!i.files||i.files.length<=0)&&delete i.files),i):$(3,"[cli] No resources found.")};function V(e,t){try{const r=JSON.parse("string"!=typeof e?JSON.stringify(e):e);return"string"!=typeof r&&t?JSON.stringify(r):r}catch{return!1}}const W=e=>{if(null===e||"object"!=typeof e)return e;const t=Array.isArray(e)?[]:{};for(const r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=W(e[r]));return t},q=(e,t)=>JSON.stringify(e,((e,r)=>("string"==typeof r&&((r=r.trim()).startsWith("function(")||r.startsWith("function ("))&&r.endsWith("}")&&(r=t?`EXP_FUN${(r+"").replaceAll(/\n|\t|\r/g," ")}EXP_FUN`:void 0),"function"==typeof r?`EXP_FUN${(r+"").replaceAll(/\n|\t|\r/g," ")}EXP_FUN`:r))).replaceAll(/"EXP_FUN|EXP_FUN"/g,"");function B(){console.log("\nUsage of CLI arguments:".bold,"\n------",`\nFor more detailed information, visit the readme at: ${"https://github.com/highcharts/node-export-server#readme".bold.yellow}.`);const e=t=>{for(const[r,o]of Object.entries(t))if(Object.prototype.hasOwnProperty.call(o,"value")){let e=` --${o.cliName||r} ${("<"+o.type+">").green} `;if(e.length<48)for(let t=e.length;t<48;t++)e+=".";console.log(e,o.description,`[Default: ${o.value.toString().bold}]`.blue)}else e(o)};Object.keys(w).forEach((t=>{["puppeteer","highcharts"].includes(t)||(console.log(`\n${t.toUpperCase()}`.red),e(w[t]))})),console.log("\n")}const X=e=>!["false","undefined","null","NaN","0",""].includes(e)&&!!e,z=(t,r)=>{if(t&&"string"==typeof t)return(t=t.trim()).endsWith(".js")?!!r&&z(e.readFileSync(t,"utf8")):t.startsWith("function()")||t.startsWith("function ()")||t.startsWith("()=>")||t.startsWith("() =>")?`(${t})()`:t.replace(/;$/,"")},K=()=>{const e=process.hrtime.bigint();return()=>Number(process.hrtime.bigint()-e)/1e6};let J={};const Y=()=>J,Z=(e,t,r=[])=>{const o=W(e);for(const[e,s]of Object.entries(t))o[e]="object"!=typeof(i=s)||Array.isArray(i)||null===i||r.includes(e)||void 0===o[e]?void 0!==s?s:o[e]:Z(o[e],s,r);var i;return o};function Q(e,t={},r=""){Object.keys(e).forEach((o=>{const i=e[o],s=t&&t[o];void 0===i.value?Q(i,s,`${r}.${o}`):(void 0!==s&&(i.value=s),i.envLink in N&&void 0!==N[i.envLink]&&(i.value=N[i.envLink]))}))}function ee(e){let t={};for(const[r,o]of Object.entries(e))t[r]=Object.prototype.hasOwnProperty.call(o,"value")?o.value:ee(o);return t}function te(e,t,r){for(;t.length>1;){const o=t.shift();return Object.prototype.hasOwnProperty.call(e,o)||(e[o]={}),e[o]=te(Object.assign({},e[o]),t,r),e}return e[t[0]]=r,e}async function re(e,t={}){return new Promise(((r,o)=>{const i=(e=>e.startsWith("https")?l:a)(e);i.get(e,Object.assign({headers:{"User-Agent":"highcharts/export",Referer:"highcharts.export"}},t||{}),(e=>{let t="";e.on("data",(e=>{t+=e})),e.on("end",(()=>{t||o("Nothing was fetched from the URL."),e.text=t,r(e)}))})).on("error",(e=>{o(e)}))}))}class oe extends Error{constructor(e){super(),this.message=e,this.stackMessage=e}setError(e){return this.error=e,e.name&&(this.name=e.name),e.statusCode&&(this.statusCode=e.statusCode),e.stack&&(this.stackMessage=e.message,this.stack=e.stack),this}}const ie={cdnURL:"https://code.highcharts.com/",activeManifest:{},sources:"",hcVersion:""},se=e=>e.sources.substring(0,e.sources.indexOf("*/")).replace("/*","").replace("*/","").replace(/\n/g,"").trim(),ne=async(e,t,r,o=!1)=>{e.endsWith(".js")&&(e=e.substring(0,e.length-3)),$(4,`[cache] Fetching script - ${e}.js`);const i=await re(`${e}.js`,t);if(200===i.statusCode&&"string"==typeof i.text){if(r){r[e.replace(/(.*)\/|(.*)modules\/|stock\/(.*)indicators\/|maps\/(.*)modules\//gi,"")]=1}return i.text}if(o)throw new oe(`Could not fetch the ${e}.js. The script might not exist in the requested version (status code: ${i.statusCode}).`).setError(i);return $(2,`[cache] Could not fetch the ${e}.js. The script might not exist in the requested version.`),""},ae=async(t,o,i)=>{const s=t.version,n="latest"!==s&&s?`${s}/`:"",a=t.cdnURL||ie.cdnURL;$(3,`[cache] Updating cache version to Highcharts: ${n||"latest"}.`);const l={};try{return ie.sources=await(async(e,t,o,i,s)=>{let n;const{host:a,port:l,username:c,password:p}=i;if(a&&l)try{n=new r.HttpsProxyAgent({host:a,port:l,...c&&p?{username:c,password:p}:{}})}catch(e){throw new oe("[cache] Could not create a Proxy Agent.").setError(e)}const h=n?{agent:n,timeout:N.SERVER_PROXY_TIMEOUT}:{},u=[...e.map((e=>ne(`${e}`,h,s,!0))),...t.map((e=>ne(`${e}`,h,s))),...o.map((e=>ne(`${e}`,h)))];return(await Promise.all(u)).join(";\n")})([...t.coreScripts.map((e=>`${a}${n}${e}`))],[...t.moduleScripts.map((e=>"map"===e?`${a}maps/${n}modules/${e}`:`${a}${n}modules/${e}`)),...t.indicatorScripts.map((e=>`${a}stock/${n}indicators/${e}`))],t.customScripts,o,l),ie.hcVersion=se(ie),e.writeFileSync(i,ie.sources),l}catch(e){throw new oe("[cache] Unable to update the local Highcharts cache.").setError(e)}},le=async r=>{const{highcharts:o,server:i}=r,s=t.join(F,o.cachePath);let n;const a=t.join(s,"manifest.json"),l=t.join(s,"sources.js");if(!e.existsSync(s)&&e.mkdirSync(s),!e.existsSync(a)||o.forceFetch)$(3,"[cache] Fetching and caching Highcharts dependencies."),n=await ae(o,i.proxy,l);else{let t=!1;const r=JSON.parse(e.readFileSync(a));if(r.modules&&Array.isArray(r.modules)){const e={};r.modules.forEach((t=>e[t]=1)),r.modules=e}const{coreScripts:s,moduleScripts:c,indicatorScripts:p}=o,h=s.length+c.length+p.length;r.version!==o.version?($(2,"[cache] A Highcharts version mismatch in the cache, need to re-fetch."),t=!0):Object.keys(r.modules||{}).length!==h?($(2,"[cache] The cache and the requested modules do not match, need to re-fetch."),t=!0):t=(c||[]).some((e=>{if(!r.modules[e])return $(2,`[cache] The ${e} is missing in the cache, need to re-fetch.`),!0})),t?n=await ae(o,i.proxy,l):($(3,"[cache] Dependency cache is up to date, proceeding."),ie.sources=e.readFileSync(l,"utf8"),n=r.modules,ie.hcVersion=se(ie))}await(async(r,o)=>{const i={version:r.version,modules:o||{}};ie.activeManifest=i,$(3,"[cache] Writing a new manifest.");try{e.writeFileSync(t.join(F,r.cachePath,"manifest.json"),JSON.stringify(i),"utf8")}catch(e){throw new oe("[cache] Error writing the cache manifest.").setError(e)}})(o,n)},ce=()=>t.join(F,Y().highcharts.cachePath),pe=()=>ie.hcVersion;function he(){Highcharts.animObject=function(){return{duration:0}}}async function ue(e,t,r){window._displayErrors=r;const{getOptions:o,merge:i,setOptions:s,wrap:n}=Highcharts;Highcharts.setOptionsObj=i(!1,{},o());const a={animation:!1};t.export.strInj&&(a.height=e.chart.height,a.width=e.chart.width),window.isRenderComplete=!1,n(Highcharts.Chart.prototype,"init",(function(e,t,r){((t=i(t,{exporting:{enabled:!1},plotOptions:{series:{label:{enabled:!1}}},tooltip:{}})).series||[]).forEach((function(e){e.animation=!1})),window.onHighchartsRender||(window.onHighchartsRender=Highcharts.addEvent(this,"render",(()=>{window.isRenderComplete=!0}))),e.apply(this,[t,r])})),n(Highcharts.Series.prototype,"init",(function(e,t,r){e.apply(this,[t,r])}));const l=t.export.strInj?new Function(`return ${t.export.strInj}`)():e;t.customLogic.customCode&&new Function("options",t.customLogic.customCode)(l);const c=i(!1,JSON.parse(t.export.themeOptions),l,{chart:a}),p=t.customLogic.callback?new Function(`return ${t.customLogic.callback}`)():void 0,h=JSON.parse(t.export.globalOptions);h&&s(h);let u=t.export.constr||"chart";u=void 0!==Highcharts[u]?u:"chart",Highcharts[u]("container",c,p);const d=o();for(const e in d)"function"!=typeof d[e]&&delete d[e];s(Highcharts.setOptionsObj),Highcharts.setOptionsObj={}}const de=e.readFileSync(F+"/templates/template.html","utf8");let ge;async function me(){if(!ge)return!1;const e=await ge.newPage();return await e.setCacheEnabled(!1),await ve(e),function(e){const{debug:t}=Y();t.enable&&t.listenToConsole&&e.on("console",(e=>{console.log(`[debug] ${e.text()}`)}));e.on("pageerror",(async t=>{e.isClosed()||await e.$eval("#container",((e,t)=>{window._displayErrors&&(e.innerHTML=t)}),`

Chart input data error:

${t.toString()}`)}))}(e),e}async function fe(e,t){try{for(const e of t)await e.dispose();await e.evaluate((()=>{if("undefined"!=typeof Highcharts){const e=Highcharts.charts;if(Array.isArray(e)&&e.length)for(const t of e)t&&t.destroy(),Highcharts.charts.shift()}const[...e]=document.getElementsByTagName("script"),[,...t]=document.getElementsByTagName("style"),[...r]=document.getElementsByTagName("link");for(const o of[...e,...t,...r])o.remove()}))}catch(e){D(2,e,"[browser] Could not clear page's resources.")}}async function ve(e){await e.setContent(de,{waitUntil:"domcontentloaded"}),await e.addScriptTag({path:`${ce()}/sources.js`}),await e.evaluate(he)}const ye=async(e,t,r,o)=>{r.export.instr=null,r.export.infile=null;const i=Buffer.byteLength(r.export?.strInj?r.export?.strInj:JSON.stringify(t),"utf-8");if($(4,`[export] The current total size of data passed to a page is around ${(i/1048576).toFixed(2)} MB`),i>=104857600)throw new oe("[export] The data passed to a page exceeded 100MB.");return e.evaluate(ue,t,r,o)};var be=async(r,o,i)=>{let s=[];try{$(4,"[export] Determining export path.");const n=i.export,a=n?.options?.chart?.displayErrors&&ie.activeManifest.modules.debugger;let l;if(o.indexOf&&(o.indexOf("=0||o.indexOf("=0)){if($(4,"[export] Treating as SVG."),"svg"===n.type)return o;l=!0,await r.setContent((e=>`\n\n\n \n \n Highcharts Export\n \n \n \n
\n ${e}\n
\n \n\n\n`)(o),{waitUntil:"domcontentloaded"})}else $(4,"[export] Treating as config."),n.strInj?await ye(r,{chart:{height:n.height,width:n.width}},i,a):(o.chart.height=n.height,o.chart.width=n.width,await ye(r,o,i,a));s=await async function(r,o){const i=[],s=o.customLogic.resources;if(s){const n=[];if(s.js&&n.push({content:s.js}),s.files)for(const t of s.files){const r=!t.startsWith("http");n.push(r?{content:e.readFileSync(t,"utf8")}:{url:t})}for(const e of n)try{i.push(await r.addScriptTag(e))}catch(e){D(2,e,"[export] The JS resource cannot be loaded.")}n.length=0;const a=[];if(s.css){let e=s.css.match(/@import\s*([^;]*);/g);if(e)for(let r of e)r&&(r=r.replace("url(","").replace("@import","").replace(/"/g,"").replace(/'/g,"").replace(/;/,"").replace(/\)/g,"").trim(),r.startsWith("http")?a.push({url:r}):o.customLogic.allowFileResources&&a.push({path:t.join(F,r)}));a.push({content:s.css.replace(/@import\s*([^;]*);/g,"")||" "});for(const e of a)try{i.push(await r.addStyleTag(e))}catch(e){D(2,e,"[export] The CSS resource cannot be loaded.")}a.length=0}}return i}(r,i);const c=l?await r.evaluate((e=>{const t=document.querySelector("#chart-container svg:first-of-type"),r=t.height.baseVal.value*e,o=t.width.baseVal.value*e;return document.body.style.zoom=e,document.body.style.margin="0px",{chartHeight:r,chartWidth:o}}),parseFloat(n.scale)):await r.evaluate((()=>{const{chartHeight:e,chartWidth:t}=window.Highcharts.charts[0];return document.body.style.zoom=1,{chartHeight:e,chartWidth:t}})),p=Math.abs(Math.ceil(c.chartHeight||n.height)),h=Math.abs(Math.ceil(c.chartWidth||n.width)),{x:u,y:d}=await(e=>e.$eval("#chart-container",(e=>{const{x:t,y:r,width:o,height:i}=e.getBoundingClientRect();return{x:t,y:r,width:o,height:Math.trunc(i>1?i:500)}})))(r);let g;if(await r.setViewport({height:p,width:h,deviceScaleFactor:l?1:parseFloat(n.scale)}),"svg"===n.type)g=await(e=>e.$eval("#container svg:first-of-type",(e=>e.outerHTML)))(r);else if(["png","jpeg"].includes(n.type))g=await((e,t,r,o,i)=>Promise.race([e.screenshot({type:t,encoding:r,clip:o,captureBeyondViewport:!0,fullPage:!1,optimizeForSpeed:!0,..."png"!==t?{quality:80}:{},omitBackground:"png"==t}),new Promise(((e,t)=>setTimeout((()=>t(new oe("Rasterization timeout"))),i||1500)))]))(r,n.type,"base64",{width:h,height:p,x:u,y:d},n.rasterizationTimeout);else{if("pdf"!==n.type)throw new oe(`[export] Unsupported output format ${n.type}.`);g=await(async(e,t,r,o,i)=>(await e.emulateMediaType("screen"),e.pdf({height:t+1,width:r,encoding:o,timeout:i||1500})))(r,p,h,"base64",n.rasterizationTimeout)}return await fe(r,s),g}catch(e){return await fe(r,s),e}};let we=!1;const Ee={performedExports:0,exportAttempts:0,exportFromSvgAttempts:0,timeSpent:0,droppedExports:0,spentAverage:0};let Te={};const Se={create:async()=>{let e=!1;const t=p.v4(),r=(new Date).getTime();try{if(e=await me(),!e||e.isClosed())throw new oe("The page is invalid or closed.");$(3,`[pool] Successfully created a worker ${t} - took ${(new Date).getTime()-r} ms.`)}catch(e){throw new oe("Error encountered when creating a new page.").setError(e)}return{id:t,page:e,workCount:Math.round(Math.random()*(Te.workLimit/2))}},validate:async e=>!(!e.page||e.page?.isClosed())&&(!(Te.workLimit&&++e.workCount>Te.workLimit)||($(3,`[pool] Worker failed validation: exceeded work limit (limit is ${Te.workLimit}).`),!1)),destroy:async e=>{$(3,`[pool] Destroying pool entry ${e.id}.`),e.page&&!e.page.isClosed()&&await e.page.close()}},xe=async e=>{if(Te=e&&e.pool?{...e.pool}:{},await async function(e){const{puppeteer:t,debug:r,other:o}=Y(),{enable:i,...s}=r,n={headless:!o.browserShellMode||"shell",userDataDir:t.tempDir||"./tmp/",args:e,handleSIGINT:!1,handleSIGTERM:!1,handleSIGHUP:!1,waitForInitialPage:!1,defaultViewport:null,...i&&s};if(!ge){const e=25;let t=0;const r=async()=>{try{$(3,`[browser] Attempting to get a browser instance (try ${++t}).`),ge=await h.launch(n)}catch(o){if(D(2,o,`[browser] Failed to launch a browser instance - retrying (attempt ${t}/${e}).`),!(t<25))throw o;$(3,`[browser] Retry to open a browser (attempt ${t}/${e}).`),await new Promise((e=>setTimeout(e,4e3))),await r()}};try{await r(),"shell"===n.headless&&$(3,"[browser] Launched browser in shell mode."),i&&$(3,"[browser] Launched browser in debug mode.")}catch(e){throw new oe("[browser] Maximum retries to open a browser instance reached.").setError(e)}if(!ge)throw new oe("[browser] Cannot find a browser to open.")}return ge}(e.puppeteerArgs),$(3,`[pool] Initializing pool with workers: min ${Te.minWorkers}, max ${Te.maxWorkers}.`),we)return $(4,"[pool] Already initialized, please kill it before creating a new one.");parseInt(Te.minWorkers)>parseInt(Te.maxWorkers)&&(Te.minWorkers=Te.maxWorkers);try{we=new c.Pool({...Se,min:parseInt(Te.minWorkers),max:parseInt(Te.maxWorkers),acquireTimeoutMillis:Te.acquireTimeout,createTimeoutMillis:Te.createTimeout,destroyTimeoutMillis:Te.destroyTimeout,idleTimeoutMillis:Te.idleTimeout,createRetryIntervalMillis:Te.createRetryInterval,reapIntervalMillis:Te.reaperInterval,propagateCreateError:!1}),we.on("release",(async e=>{const t=await async function(e,t=!1){try{if(e&&!e.isClosed())return t?(await e.goto("about:blank",{waitUntil:"domcontentloaded"}),await ve(e)):await e.evaluate((()=>{document.body.innerHTML='
'})),!0}catch(e){D(2,e,"[browser] Could not clear the content of the page.")}return!1}(e.page,!1);$(4,`[pool] Releasing a worker with ID ${e.id}. Clear page status: ${t}.`)})),we.on("destroySuccess",((e,t)=>{$(4,`[pool] Destroyed a worker with ID ${t.id}.`),t.page=null}));const e=[];for(let t=0;t{we.release(e)})),$(3,"[pool] The pool is ready"+(e.length?` with ${e.length} initial resources waiting.`:"."))}catch(e){throw new oe("[pool] Could not create the pool of workers.").setError(e)}};async function Re(){if($(3,"[pool] Killing pool with all workers and closing browser."),we){for(const e of we.used)we.release(e.resource);we.destroyed||(await we.destroy(),$(4,"[browser] Destroyed the pool of resources."))}await async function(){ge?.connected&&await ge.close(),$(4,"[browser] Closed the browser.")}()}const _e=async(e,t)=>{let r;try{if($(4,"[pool] Work received, starting to process."),++Ee.exportAttempts,Te.benchmarking&&Le(),!we)throw new oe("Work received, but pool has not been started.");const o=K();try{$(4,"[pool] Acquiring a worker handle."),r=await we.acquire().promise,t.server.benchmarking&&$(5,t.payload?.requestId?`[benchmark] Request with ID ${t.payload?.requestId} -`:"[benchmark]",`Acquired a worker handle: ${o()}ms.`)}catch(e){throw new oe((t.payload?.requestId?`For request with ID ${t.payload?.requestId} - `:"")+`Error encountered when acquiring an available entry: ${o()}ms.`).setError(e)}if($(4,"[pool] Acquired a worker handle."),!r.page)throw new oe("Resolved worker page is invalid: the pool setup is wonky.");let i=(new Date).getTime();$(4,`[pool] Starting work on pool entry with ID ${r.id}.`);const s=K(),n=await be(r.page,e,t);if(n instanceof Error)throw"Rasterization timeout"===n.message&&(r.workCount=Te.workLimit+1,r.page=null),"TimeoutError"===n.name||"Rasterization timeout"===n.message?new oe("Rasterization timeout: your chart may be too complex or large, and failed to render within the allotted time.").setError(n):new oe((t.payload?.requestId?`For request with ID ${t.payload?.requestId} - `:"")+`Error encountered during export: ${s()}ms.`).setError(n);t.server.benchmarking&&$(5,t.payload?.requestId?`[benchmark] Request with ID ${t.payload?.requestId} -`:"[benchmark]",`Exported a chart sucessfully: ${s()}ms.`),we.release(r);const a=(new Date).getTime()-i;return Ee.timeSpent+=a,Ee.spentAverage=Ee.timeSpent/++Ee.performedExports,$(4,`[pool] Work completed in ${a} ms.`),{result:n,options:t}}catch(e){throw++Ee.droppedExports,r&&we.release(r),new oe(`[pool] In pool.postWork: ${e.message}`).setError(e)}},Oe=()=>({min:we.min,max:we.max,all:we.numFree()+we.numUsed(),available:we.numFree(),used:we.numUsed(),pending:we.numPendingAcquires()});function Le(){const{min:e,max:t,all:r,available:o,used:i,pending:s}=Oe();$(5,`[pool] The minimum number of resources allowed by pool: ${e}.`),$(5,`[pool] The maximum number of resources allowed by pool: ${t}.`),$(5,`[pool] The number of all created resources: ${r}.`),$(5,`[pool] The number of available resources: ${o}.`),$(5,`[pool] The number of acquired resources: ${i}.`),$(5,`[pool] The number of resources waiting to be acquired: ${s}.`)}var ke=Oe,Ie=()=>Ee;let Ce=!1;const Ne=async(t,r)=>{$(4,"[chart] Starting the exporting process.");const o=((e,t={})=>{let r={};return e.svg?(r=W(t),r.export.type=e.type||e.export.type,r.export.scale=e.scale||e.export.scale,r.export.outfile=e.outfile||e.export.outfile,r.payload={svg:e.svg}):r=Z(t,e,T),r.export.outfile=r.export?.outfile||`chart.${r.export?.type||"png"}`,r})(t,Y()),i=o.export;if(o.payload?.svg&&""!==o.payload.svg)try{$(4,"[chart] Attempting to export from a SVG input.");const e=$e(function(e){const t=[];N.OTHER_ALLOW_XLINK||t.push("xlink:href");const r=new u.JSDOM("").window;return d(r).sanitize(e,{ADD_TAGS:["foreignObject"],FORBID_ATTR:t})}(o.payload.svg),o,r);return++Ee.exportFromSvgAttempts,e}catch(e){return r(new oe("[chart] Error loading SVG input.").setError(e))}if(i.infile&&i.infile.length)try{return $(4,"[chart] Attempting to export from an input file."),o.export.instr=e.readFileSync(i.infile,"utf8"),$e(o.export.instr.trim(),o,r)}catch(e){return r(new oe("[chart] Error loading input file.").setError(e))}if(i.instr&&""!==i.instr||i.options&&""!==i.options)try{return $(4,"[chart] Attempting to export from a raw input."),i.instr=i.instr||i.options,X(o.customLogic?.allowCodeExecution)?He(o,r):"string"==typeof i.instr?$e(i.instr.trim(),o,r):Pe(o,i.instr||i.options,r)}catch(e){return r(new oe("[chart] Error loading raw input.").setError(e))}return r(new oe("[chart] No valid input specified. Check if at least one of the following parameters is correctly set: 'infile', 'instr', 'options', or 'svg'."))},Ae=e=>{const{chart:t,exporting:r}=e.export?.options||V(e.export?.instr),o=V(e.export?.globalOptions);let i=e.export?.scale||r?.scale||o?.exporting?.scale||e.export?.defaultScale||1;i=Math.max(.1,Math.min(i,5)),i=((e,t=1)=>{const r=Math.pow(10,t||0);return Math.round(+e*r)/r})(i,2);const s={height:e.export?.height||r?.sourceHeight||t?.height||o?.exporting?.sourceHeight||o?.chart?.height||e.export?.defaultHeight||400,width:e.export?.width||r?.sourceWidth||t?.width||o?.exporting?.sourceWidth||o?.chart?.width||e.export?.defaultWidth||600,scale:i};for(let[e,t]of Object.entries(s))s[e]="string"==typeof t?+t.replace(/px|%/gi,""):t;return s},Pe=async(t,r,o,i)=>{let{export:s,customLogic:n}=t;const a="boolean"==typeof n.allowCodeExecution?n.allowCodeExecution:Ce;if(n){if(a)if("string"==typeof t.customLogic.resources)t.customLogic.resources=M(t.customLogic.resources,X(t.customLogic.allowFileResources));else if(!t.customLogic.resources)try{const r=e.readFileSync("resources.json","utf8");t.customLogic.resources=M(r,X(t.customLogic.allowFileResources))}catch(e){$(2,"[chart] Unable to load the default resources.json file.")}}else n=t.customLogic={};if(!a&&n){if(n.callback||n.resources||n.customCode)return o(new oe("[chart] The 'callback', 'resources' and 'customCode' options have been disabled for this server."));n.callback=!1,n.resources=!1,n.customCode=!1}if(r&&(r.chart=r.chart||{},r.exporting=r.exporting||{},r.exporting.enabled=!1),s.constr=s.constr||"chart",s.type=j(s.type,s.outfile),"svg"===s.type&&(s.width=!1),["globalOptions","themeOptions"].forEach((t=>{try{s&&s[t]&&("string"==typeof s[t]&&s[t].endsWith(".json")?s[t]=V(e.readFileSync(s[t],"utf8"),!0):s[t]=V(s[t],!0))}catch(e){s[t]={},D(2,e,`[chart] The '${t}' cannot be loaded.`)}})),n.allowCodeExecution)try{n.customCode=z(n.customCode,n.allowFileResources)}catch(e){D(2,e,"[chart] The 'customCode' cannot be loaded.")}if(n&&n.callback&&n.callback?.indexOf("{")<0)if(n.allowFileResources)try{n.callback=e.readFileSync(n.callback,"utf8")}catch(e){n.callback=!1,D(2,e,"[chart] The 'callback' cannot be loaded.")}else n.callback=!1;t.export={...t.export,...Ae(t)};try{return o(!1,await _e(s.strInj||r||i,t))}catch(e){return o(e)}},He=(e,t)=>{try{let r,o=e.export.instr||e.export.options;return"string"!=typeof o&&(r=o=q(o,e.customLogic?.allowCodeExecution)),r=o.replaceAll(/\t|\n|\r/g,"").trim(),";"===r[r.length-1]&&(r=r.substring(0,r.length-1)),e.export.strInj=r,Pe(e,!1,t)}catch(r){return t(new oe(`[chart] Malformed input detected for ${e.export?.requestId||"?"}. Please make sure that your JSON/JavaScript options are sent using the "options" attribute, and that if you're using SVG, it is unescaped.`).setError(r))}},$e=(e,t,r)=>{const{allowCodeExecution:o}=t.customLogic;if(e.indexOf("=0||e.indexOf("=0)return $(4,"[chart] Parsing input as SVG."),Pe(t,!1,r,e);try{const o=JSON.parse(e.replaceAll(/\t|\n|\r/g," "));return Pe(t,o,r)}catch(e){return X(o)?He(t,r):r(new oe("[chart] Only JSON configurations and SVG are allowed for this server. If this is your server, JavaScript custom code can be enabled by starting the server with the --allowCodeExecution flag.").setError(e))}},De=[],Ue=()=>{$(4,"[server] Clearing all registered intervals.");for(const e of De)clearInterval(e)},Ge=(e,t,r,o)=>{D(1,e),"development"!==N.OTHER_NODE_ENV&&delete e.stack,o(e)},Fe=(e,t,r,o)=>{const{statusCode:i,status:s,message:n,stack:a}=e,l=i||s||400;r.status(l).json({statusCode:l,message:n,stack:a})};var je=(e,t)=>{const r="Too many requests, you have been rate limited. Please try again later.",o={max:t.maxRequests||30,window:t.window||1,delay:t.delay||0,trustProxy:t.trustProxy||!1,skipKey:t.skipKey||!1,skipToken:t.skipToken||!1};o.trustProxy&&e.enable("trust proxy");const i=v({windowMs:60*o.window*1e3,max:o.max,delayMs:o.delay,handler:(e,t)=>{t.format({json:()=>{t.status(429).send({message:r})},default:()=>{t.status(429).send(r)}})},skip:e=>!1!==o.skipKey&&!1!==o.skipToken&&e.query.key===o.skipKey&&e.query.access_token===o.skipToken&&($(4,"[rate limiting] Skipping rate limiter."),!0)});e.use(i),$(3,`[rate limiting] Enabled rate limiting with ${o.max} requests per ${o.window} minute for each IP, trusting proxy: ${o.trustProxy}.`)};class Me extends oe{constructor(e,t){super(e),this.status=this.statusCode=t}setStatus(e){return this.status=e,this}}var Ve=e=>!!e&&e.post("/version/change/:newVersion",(async(e,t,r)=>{try{const r=N.HIGHCHARTS_ADMIN_TOKEN;if(!r||!r.length)throw new Me("The server is not configured to perform run-time version changes: HIGHCHARTS_ADMIN_TOKEN is not set.",401);const o=e.get("hc-auth");if(!o||o!==r)throw new Me("Invalid or missing token: Set the token in the hc-auth header.",401);const i=e.params.newVersion;if(!i)throw new Me("No new version supplied.",400);try{await(async e=>{const t=Y();t?.highcharts&&(t.highcharts.version=e),await le(t)})(i)}catch(e){throw new Me(`Version change: ${e.message}`,e.statusCode).setError(e)}t.status(200).send({statusCode:200,version:pe(),message:`Successfully updated Highcharts to version: ${i}.`})}catch(e){r(e)}}));const We={png:"image/png",jpeg:"image/jpeg",gif:"image/gif",pdf:"application/pdf",svg:"image/svg+xml"};let qe=0;const Be=[],Xe=[],ze=(e,t,r,o)=>{let i=!0;const{id:s,uniqueId:n,type:a,body:l}=o;return e.some((e=>{if(e){let o=e(t,r,s,n,a,l);return void 0!==o&&!0!==o&&(i=o),!0}})),i},Ke=async(e,t,r)=>{try{const r=K(),i=p.v4().replace(/-/g,""),s=Y(),n=e.body,a=++qe;let l=j(n.type);if(!n||"object"==typeof(o=n)&&!Array.isArray(o)&&null!==o&&0===Object.keys(o).length)throw new Me("The request body is required. Please ensure that your Content-Type header is correct (accepted types are application/json and multipart/form-data).",400);let c=V(n.infile||n.options||n.data);if(!c&&!n.svg)throw $(2,`The request with ID ${i} from ${e.headers["x-forwarded-for"]||e.connection.remoteAddress} was incorrect:\n Content-Type: ${e.headers["content-type"]}. \n Chart constructor: ${n.constr}.\n Dimensions: ${n.width}x${n.height} @ ${n.scale} scale.\n Type: ${l}.\n Is SVG set? ${void 0!==n.svg}.\n B64? ${void 0!==n.b64}.\n No download? ${void 0!==n.noDownload}.\n\n Payload received: ${JSON.stringify(n.infile||n.options||n.data||n.svg)}\n\n `),new Me("No correct chart data found. Ensure that you are using either application/json or multipart/form-data headers. If sending JSON, make sure the chart data is in the 'infile', 'options', or 'data' attribute. If sending SVG, ensure it is in the 'svg' attribute.",400);let h=!1;if(h=ze(Be,e,t,{id:a,uniqueId:i,type:l,body:n}),!0!==h)return t.send(h);let u=!1;e.socket.on("close",(e=>{e&&(u=!0)})),$(4,`[export] Got an incoming HTTP request with ID ${i}.`),n.constr="string"==typeof n.constr&&n.constr||"chart";const d={export:{instr:c,type:l,constr:n.constr[0].toLowerCase()+n.constr.substr(1),height:n.height,width:n.width,scale:n.scale||s.export.scale,globalOptions:V(n.globalOptions,!0),themeOptions:V(n.themeOptions,!0)},customLogic:{allowCodeExecution:Ce,allowFileResources:!1,resources:V(n.resources,!0),callback:n.callback,customCode:n.customCode}};c&&(d.export.instr=q(c,d.customLogic.allowCodeExecution));const g=Z(s,d);if(g.export.options=c,g.payload={svg:n.svg||!1,b64:n.b64||!1,noDownload:n.noDownload||!1,requestId:i},n.svg&&(e=>[/xlink:href="(?:http:\/\/|https:\/\/)?localhost\b/,/xlink:href="(?:http:\/\/|https:\/\/)?10\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/,/xlink:href="(?:http:\/\/|https:\/\/)?127\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/,/xlink:href="(?:http:\/\/|https:\/\/)?172\.(1[6-9]|2[0-9]|3[0-1])\.\d{1,3}\.\d{1,3}\b/,/xlink:href="(?:http:\/\/|https:\/\/)?192\.168\.\d{1,3}\.\d{1,3}\b/].some((t=>t.test(e))))(g.payload.svg))throw new Me("SVG potentially contain at least one forbidden URL in xlink:href element. Please review the SVG content and ensure that all referenced URLs comply with security policies.",400);await Ne(g,((o,c)=>{if(e.socket.removeAllListeners("close"),s.server.benchmarking&&$(5,`[benchmark] Request with ID ${i} - After the whole exporting process: ${r()}ms.`),u)return $(3,"[export] The client closed the connection before the chart finished processing.");if(o)throw o;if(!c||!c.result)throw new Me(`Unexpected return from chart generation. Please check your request data. For the request with ID ${i}, the result is ${c.result}.`,400);return l=c.options.export.type,ze(Xe,e,t,{id:a,body:c.result}),c.result?n.b64?"pdf"===l||"svg"==l?t.send(Buffer.from(c.result,"utf8").toString("base64")):t.send(c.result):(t.header("Content-Type",We[l]||"image/png"),n.noDownload||t.attachment(`${e.params.filename||e.body.filename||"chart"}.${l||"png"}`),"svg"===l?t.send(c.result):t.send(Buffer.from(c.result,"base64"))):void 0}))}catch(e){r(e)}var o};const Je=JSON.parse(e.readFileSync(t.join(F,"package.json"))),Ye=new Date,Ze=[];function Qe(e){if(!e)return!1;var t;t=setInterval((()=>{const e=Ie(),t=0===e.exportAttempts?1:e.performedExports/e.exportAttempts*100;Ze.push(t),Ze.length>30&&Ze.shift()}),6e4),De.push(t),e.get("/health",((e,t)=>{const r=Ie(),o=Ze.length,i=Ze.reduce(((e,t)=>e+t),0)/Ze.length;$(4,"[health.js] GET /health [200] - returning server health."),t.send({status:"OK",bootTime:Ye,uptime:Math.floor(((new Date).getTime()-Ye.getTime())/1e3/60)+" minutes",version:Je.version,highchartsVersion:pe(),averageProcessingTime:r.spentAverage,performedExports:r.performedExports,failedExports:r.droppedExports,exportAttempts:r.exportAttempts,sucessRatio:r.performedExports/r.exportAttempts*100,pool:ke(),period:o,movingAverage:i,message:isNaN(i)||!Ze.length?"Too early to report. No exports made yet. Please check back soon.":`Last ${o} minutes had a success rate of ${i.toFixed(2)}%.`,svgExportAttempts:r.exportFromSvgAttempts,jsonExportAttempts:r.performedExports-r.exportFromSvgAttempts})}))}const et=new Map,tt=m();tt.disable("x-powered-by"),tt.use(g()),tt.use(((e,t,r)=>{t.set("Accept-Ranges","none"),r()}));const rt=e=>{e.on("clientError",((e,t)=>{D(1,e,`[server] Client error: ${e.message}, destroying socket.`),t.destroy()})),e.on("error",(e=>{D(1,e,`[server] Server error: ${e.message}`)})),e.on("connection",(e=>{e.on("error",(e=>{D(1,e,`[server] Socket error: ${e.message}`)}))}))},ot=async r=>{try{const o=1024*(r.maxUploadSize||3)*1024,i=f.memoryStorage(),s=f({storage:i,limits:{fieldSize:o}});if(tt.use(m.json({limit:o})),tt.use(m.urlencoded({extended:!0,limit:o})),tt.use(s.none()),!r.enable)return!1;if(!r.ssl.force){const e=a.createServer(tt);rt(e),e.listen(r.port,r.host),et.set(r.port,e),$(3,`[server] Started HTTP server on ${r.host}:${r.port}.`)}if(r.ssl.enable){let o,i;try{o=await e.promises.readFile(t.posix.join(r.ssl.certPath,"server.key"),"utf8"),i=await e.promises.readFile(t.posix.join(r.ssl.certPath,"server.crt"),"utf8")}catch(e){$(2,`[server] Unable to load key/certificate from the '${r.ssl.certPath}' path. Could not run secured layer server.`)}if(o&&i){const e=l.createServer({key:o,cert:i},tt);rt(e),e.listen(r.ssl.port,r.host),et.set(r.ssl.port,e),$(3,`[server] Started HTTPS server on ${r.host}:${r.ssl.port}.`)}}r.rateLimiting&&r.rateLimiting.enable&&![0,NaN].includes(r.rateLimiting.maxRequests)&&je(tt,r.rateLimiting),tt.use(m.static(t.posix.join(F,"public"))),Qe(tt),(e=>{e.post("/",Ke),e.post("/:filename",Ke)})(tt),(e=>{!!e&&e.get("/",((e,r)=>{r.sendFile(t.join(F,"public","index.html"),{acceptRanges:!1})}))})(tt),Ve(tt),(e=>{e.use(Ge),e.use(Fe)})(tt)}catch(e){throw new oe("[server] Could not configure and start the server.").setError(e)}},it=()=>{$(4,"[server] Closing all servers.");for(const[e,t]of et)t.close((()=>{et.delete(e),$(4,`[server] Closed server on port: ${e}.`)}))};var st={startServer:ot,closeServers:it,getServers:()=>et,enableRateLimiting:e=>je(tt,e),getExpress:()=>m,getApp:()=>tt,use:(e,...t)=>{tt.use(e,...t)},get:(e,...t)=>{tt.get(e,...t)},post:(e,...t)=>{tt.post(e,...t)}};const nt=async e=>{await Promise.allSettled([Ue(),it(),Re()]),process.exit(e)};var at={server:st,startServer:ot,initExport:async e=>{var t;return t=e.customLogic&&e.customLogic.allowCodeExecution,Ce=X(t),(e=>{for(const[t,r]of Object.entries(e))P[t]=r;U(e&&parseInt(e.level)),e&&e.dest&&e.toFile&&G(e.dest,e.file||"highcharts-export-server.log")})(e.logging),e.other.listenToProcessExits&&($(3,"[process] Attaching exit listeners to the process."),process.on("exit",(e=>{$(4,`Process exited with code ${e}.`)})),process.on("SIGINT",(async(e,t)=>{$(4,`The ${e} event with code: ${t}.`),await nt(0)})),process.on("SIGTERM",(async(e,t)=>{$(4,`The ${e} event with code: ${t}.`),await nt(0)})),process.on("SIGHUP",(async(e,t)=>{$(4,`The ${e} event with code: ${t}.`),await nt(0)})),process.on("uncaughtException",(async(e,t)=>{D(1,e,`The ${t} error.`),await nt(1)}))),await le(e),await xe({pool:e.pool||{minWorkers:1,maxWorkers:1},puppeteerArgs:e.puppeteer.args||[]}),e},singleExport:async t=>{t.export.instr=t.export.instr||t.export.options,await Ne(t,(async(t,r)=>{if(t)throw t;const{outfile:o,type:i}=r.options.export;e.writeFileSync(o||`chart.${i}`,"svg"!==i?Buffer.from(r.result,"base64"):r.result),await Re()}))},batchExport:async t=>{const r=[];for(let o of t.export.batch.split(";"))o=o.split("="),2===o.length&&r.push(Ne({...t,export:{...t.export,infile:o[0],outfile:o[1]}},((t,r)=>{if(t)throw t;e.writeFileSync(r.options.export.outfile,"svg"!==r.options.export.type?Buffer.from(r.result,"base64"):r.result)})));try{await Promise.all(r),await Re()}catch(e){throw new oe("[chart] Error encountered during batch export.").setError(e)}},startExport:Ne,initPool:xe,killPool:Re,setOptions:(t,r)=>(r?.length&&(J=function(t){const r=t.findIndex((e=>"loadConfig"===e.replace(/-/g,"")));if(r>-1&&t[r+1]){const o=t[r+1];try{if(o&&o.endsWith(".json"))return JSON.parse(e.readFileSync(o))}catch(e){D(2,e,`[config] Unable to load the configuration from the ${o} file.`)}}return{}}(r)),Q(w,J),J=ee(w),t&&(J=Z(J,t,T)),r?.length&&(J=function(e,t,r){let o=!1;for(let i=0;i(n.length-1===r&&(a=e[t].type),e[t])),r),n.reduce(((e,r,l)=>(n.length-1===l&&void 0!==e[r]&&(t[++i]?"boolean"===a?e[r]=X(t[i]):"number"===a?e[r]=+t[i]:a.indexOf("]")>=0?e[r]=t[i].split(","):e[r]=t[i]:($(2,`[config] Missing value for the '${s}' argument. Using the default value.`),o=!0)),e[r])),e)}o&&B();return e}(J,r,w)),J),shutdownCleanUp:nt,log:$,logWithStack:D,setLogLevel:U,enableFileLogging:G,mapToNewConfig:e=>{const t={};for(const[r,o]of Object.entries(e)){const e=S[r]?S[r].split("."):[];e.reduce(((t,r,i)=>t[r]=e.length-1===i?o:t[r]||{}),t)}return t},manualConfig:async t=>{let r={};e.existsSync(t)&&(r=JSON.parse(e.readFileSync(t,"utf8")));const i=Object.keys(E).map((e=>({title:`${e} options`,value:e})));return o({type:"multiselect",name:"category",message:"Which category do you want to configure?",hint:"Space: Select specific, A: Select all, Enter: Confirm.",instructions:"",choices:i},{onSubmit:async(i,s)=>{let n=0,a=[];for(const e of s)E[e]=E[e].map((t=>({...t,section:e}))),a=[...a,...E[e]];return await o(a,{onSubmit:async(o,i)=>{if("moduleScripts"===o.name?(i=i.length?i.map((e=>o.choices[e])):o.choices,r[o.section][o.name]=i):r[o.section]=te(Object.assign({},r[o.section]||{}),o.name.split("."),o.choices?o.choices[i]:i),++n===a.length){try{await e.promises.writeFile(t,JSON.stringify(r,null,2),"utf8")}catch(e){D(1,e,`[config] An error occurred while creating the ${t} file.`)}return!0}}}),!0}})},printLogo:r=>{const o=JSON.parse(e.readFileSync(t.join(F,"package.json"))).version;r?console.log(`Starting Highcharts Export Server v${o}...`):console.log(e.readFileSync(F+"/msg/startup.msg").toString().bold.yellow,`v${o}\n`.bold)},printUsage:B};module.exports=at; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguY2pzIiwic291cmNlcyI6WyIuLi9saWIvc2NoZW1hcy9jb25maWcuanMiLCIuLi9saWIvZW52cy5qcyIsIi4uL2xpYi9sb2dnZXIuanMiLCIuLi9saWIvdXRpbHMuanMiLCIuLi9saWIvY29uZmlnLmpzIiwiLi4vbGliL2ZldGNoLmpzIiwiLi4vbGliL2Vycm9ycy9FeHBvcnRFcnJvci5qcyIsIi4uL2xpYi9jYWNoZS5qcyIsIi4uL2xpYi9oaWdoY2hhcnRzLmpzIiwiLi4vbGliL2Jyb3dzZXIuanMiLCIuLi9saWIvZXhwb3J0LmpzIiwiLi4vdGVtcGxhdGVzL3N2Z19leHBvcnQvc3ZnX2V4cG9ydC5qcyIsIi4uL2xpYi9wb29sLmpzIiwiLi4vbGliL2NoYXJ0LmpzIiwiLi4vbGliL3Nhbml0aXplLmpzIiwiLi4vbGliL2ludGVydmFscy5qcyIsIi4uL2xpYi9zZXJ2ZXIvZXJyb3IuanMiLCIuLi9saWIvc2VydmVyL3JhdGVfbGltaXQuanMiLCIuLi9saWIvZXJyb3JzL0h0dHBFcnJvci5qcyIsIi4uL2xpYi9zZXJ2ZXIvcm91dGVzL2NoYW5nZV9oY192ZXJzaW9uLmpzIiwiLi4vbGliL3NlcnZlci9yb3V0ZXMvZXhwb3J0LmpzIiwiLi4vbGliL3NlcnZlci9yb3V0ZXMvaGVhbHRoLmpzIiwiLi4vbGliL3NlcnZlci9zZXJ2ZXIuanMiLCIuLi9saWIvc2VydmVyL3JvdXRlcy91aS5qcyIsIi4uL2xpYi9yZXNvdXJjZV9yZWxlYXNlLmpzIiwiLi4vbGliL2luZGV4LmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG5cbkhpZ2hjaGFydHMgRXhwb3J0IFNlcnZlclxuXG5Db3B5cmlnaHQgKGMpIDIwMTYtMjAyNCwgSGlnaHNvZnRcblxuTGljZW5jZWQgdW5kZXIgdGhlIE1JVCBsaWNlbmNlLlxuXG5BZGRpdGlvbmFsbHkgYSB2YWxpZCBIaWdoY2hhcnRzIGxpY2Vuc2UgaXMgcmVxdWlyZWQgZm9yIHVzZS5cblxuU2VlIExJQ0VOU0UgZmlsZSBpbiByb290IGZvciBkZXRhaWxzLlxuXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG4vLyBQb3NzaWJsZSBuYW1lcyBmb3IgSGlnaGNoYXJ0cyBzY3JpcHRzXG5leHBvcnQgY29uc3Qgc2NyaXB0c05hbWVzID0ge1xuICBjb3JlOiBbJ2hpZ2hjaGFydHMnLCAnaGlnaGNoYXJ0cy1tb3JlJywgJ2hpZ2hjaGFydHMtM2QnXSxcbiAgbW9kdWxlczogW1xuICAgICdzdG9jaycsXG4gICAgJ21hcCcsXG4gICAgJ2dhbnR0JyxcbiAgICAnZXhwb3J0aW5nJyxcbiAgICAncGFyYWxsZWwtY29vcmRpbmF0ZXMnLFxuICAgICdhY2Nlc3NpYmlsaXR5JyxcbiAgICAvLyAnYW5ub3RhdGlvbnMtYWR2YW5jZWQnLFxuICAgICdib29zdC1jYW52YXMnLFxuICAgICdib29zdCcsXG4gICAgJ2RhdGEnLFxuICAgICdkYXRhLXRvb2xzJyxcbiAgICAnZHJhZ2dhYmxlLXBvaW50cycsXG4gICAgJ3N0YXRpYy1zY2FsZScsXG4gICAgJ2Jyb2tlbi1heGlzJyxcbiAgICAnaGVhdG1hcCcsXG4gICAgJ3RpbGVtYXAnLFxuICAgICd0aWxlZHdlYm1hcCcsXG4gICAgJ3RpbWVsaW5lJyxcbiAgICAndHJlZW1hcCcsXG4gICAgJ3RyZWVncmFwaCcsXG4gICAgJ2l0ZW0tc2VyaWVzJyxcbiAgICAnZHJpbGxkb3duJyxcbiAgICAnaGlzdG9ncmFtLWJlbGxjdXJ2ZScsXG4gICAgJ2J1bGxldCcsXG4gICAgJ2Z1bm5lbCcsXG4gICAgJ2Z1bm5lbDNkJyxcbiAgICAnZ2VvaGVhdG1hcCcsXG4gICAgJ3B5cmFtaWQzZCcsXG4gICAgJ25ldHdvcmtncmFwaCcsXG4gICAgJ292ZXJsYXBwaW5nLWRhdGFsYWJlbHMnLFxuICAgICdwYXJldG8nLFxuICAgICdwYXR0ZXJuLWZpbGwnLFxuICAgICdwaWN0b3JpYWwnLFxuICAgICdwcmljZS1pbmRpY2F0b3InLFxuICAgICdzYW5rZXknLFxuICAgICdhcmMtZGlhZ3JhbScsXG4gICAgJ2RlcGVuZGVuY3ktd2hlZWwnLFxuICAgICdzZXJpZXMtbGFiZWwnLFxuICAgICdzZXJpZXMtb24tcG9pbnQnLFxuICAgICdzb2xpZC1nYXVnZScsXG4gICAgJ3NvbmlmaWNhdGlvbicsXG4gICAgLy8gJ3N0b2NrLXRvb2xzJyxcbiAgICAnc3RyZWFtZ3JhcGgnLFxuICAgICdzdW5idXJzdCcsXG4gICAgJ3ZhcmlhYmxlLXBpZScsXG4gICAgJ3Zhcml3aWRlJyxcbiAgICAndmVjdG9yJyxcbiAgICAndmVubicsXG4gICAgJ3dpbmRiYXJiJyxcbiAgICAnd29yZGNsb3VkJyxcbiAgICAneHJhbmdlJyxcbiAgICAnbm8tZGF0YS10by1kaXNwbGF5JyxcbiAgICAnZHJhZy1wYW5lcycsXG4gICAgJ2RlYnVnZ2VyJyxcbiAgICAnZHVtYmJlbGwnLFxuICAgICdsb2xsaXBvcCcsXG4gICAgJ2N5bGluZGVyJyxcbiAgICAnb3JnYW5pemF0aW9uJyxcbiAgICAnZG90cGxvdCcsXG4gICAgJ21hcmtlci1jbHVzdGVycycsXG4gICAgJ2hvbGxvd2NhbmRsZXN0aWNrJyxcbiAgICAnaGVpa2luYXNoaScsXG4gICAgJ2Zsb3dtYXAnLFxuICAgICdleHBvcnQtZGF0YScsXG4gICAgJ25hdmlnYXRvcicsXG4gICAgJ3RleHRwYXRoJ1xuICBdLFxuICBpbmRpY2F0b3JzOiBbJ2luZGljYXRvcnMtYWxsJ10sXG4gIGN1c3RvbTogW1xuICAgICdodHRwczovL2NkbmpzLmNsb3VkZmxhcmUuY29tL2FqYXgvbGlicy9tb21lbnQuanMvMi4zMC4xL21vbWVudC5taW4uanMnLFxuICAgICdodHRwczovL2NkbmpzLmNsb3VkZmxhcmUuY29tL2FqYXgvbGlicy9tb21lbnQtdGltZXpvbmUvMC41LjQ1L21vbWVudC10aW1lem9uZS13aXRoLWRhdGEubWluLmpzJ1xuICBdXG59O1xuXG4vLyBUaGlzIGlzIHRoZSBjb25maWd1cmF0aW9uIG9iamVjdCB3aXRoIGFsbCBvcHRpb25zIGFuZCB0aGVpciBkZWZhdWx0IHZhbHVlcyxcbi8vIGFsc28gZnJvbSB0aGUgLmVudiBmaWxlIGlmIG9uZSBleGlzdHNcbmV4cG9ydCBjb25zdCBkZWZhdWx0Q29uZmlnID0ge1xuICBwdXBwZXRlZXI6IHtcbiAgICBhcmdzOiB7XG4gICAgICB2YWx1ZTogW1xuICAgICAgICAnLS1hbGxvdy1ydW5uaW5nLWluc2VjdXJlLWNvbnRlbnQnLFxuICAgICAgICAnLS1hc2gtbm8tbnVkZ2VzJyxcbiAgICAgICAgJy0tYXV0b3BsYXktcG9saWN5PXVzZXItZ2VzdHVyZS1yZXF1aXJlZCcsXG4gICAgICAgICctLWJsb2NrLW5ldy13ZWItY29udGVudHMnLFxuICAgICAgICAnLS1kaXNhYmxlLWFjY2VsZXJhdGVkLTJkLWNhbnZhcycsXG4gICAgICAgICctLWRpc2FibGUtYmFja2dyb3VuZC1uZXR3b3JraW5nJyxcbiAgICAgICAgJy0tZGlzYWJsZS1iYWNrZ3JvdW5kLXRpbWVyLXRocm90dGxpbmcnLFxuICAgICAgICAnLS1kaXNhYmxlLWJhY2tncm91bmRpbmctb2NjbHVkZWQtd2luZG93cycsXG4gICAgICAgICctLWRpc2FibGUtYnJlYWtwYWQnLFxuICAgICAgICAnLS1kaXNhYmxlLWNoZWNrZXItaW1hZ2luZycsXG4gICAgICAgICctLWRpc2FibGUtY2xpZW50LXNpZGUtcGhpc2hpbmctZGV0ZWN0aW9uJyxcbiAgICAgICAgJy0tZGlzYWJsZS1jb21wb25lbnQtZXh0ZW5zaW9ucy13aXRoLWJhY2tncm91bmQtcGFnZXMnLFxuICAgICAgICAnLS1kaXNhYmxlLWNvbXBvbmVudC11cGRhdGUnLFxuICAgICAgICAnLS1kaXNhYmxlLWRlZmF1bHQtYXBwcycsXG4gICAgICAgICctLWRpc2FibGUtZGV2LXNobS11c2FnZScsXG4gICAgICAgICctLWRpc2FibGUtZG9tYWluLXJlbGlhYmlsaXR5JyxcbiAgICAgICAgJy0tZGlzYWJsZS1leHRlbnNpb25zJyxcbiAgICAgICAgJy0tZGlzYWJsZS1mZWF0dXJlcz1DYWxjdWxhdGVOYXRpdmVXaW5PY2NsdXNpb24sSW50ZXJlc3RGZWVkQ29udGVudFN1Z2dlc3Rpb25zLFdlYk9UUCcsXG4gICAgICAgICctLWRpc2FibGUtaGFuZy1tb25pdG9yJyxcbiAgICAgICAgJy0tZGlzYWJsZS1pcGMtZmxvb2RpbmctcHJvdGVjdGlvbicsXG4gICAgICAgICctLWRpc2FibGUtbG9nZ2luZycsXG4gICAgICAgICctLWRpc2FibGUtbm90aWZpY2F0aW9ucycsXG4gICAgICAgICctLWRpc2FibGUtb2ZmZXItc3RvcmUtdW5tYXNrZWQtd2FsbGV0LWNhcmRzJyxcbiAgICAgICAgJy0tZGlzYWJsZS1wb3B1cC1ibG9ja2luZycsXG4gICAgICAgICctLWRpc2FibGUtcHJpbnQtcHJldmlldycsXG4gICAgICAgICctLWRpc2FibGUtcHJvbXB0LW9uLXJlcG9zdCcsXG4gICAgICAgICctLWRpc2FibGUtcmVuZGVyZXItYmFja2dyb3VuZGluZycsXG4gICAgICAgICctLWRpc2FibGUtc2VhcmNoLWVuZ2luZS1jaG9pY2Utc2NyZWVuJyxcbiAgICAgICAgJy0tZGlzYWJsZS1zZXNzaW9uLWNyYXNoZWQtYnViYmxlJyxcbiAgICAgICAgJy0tZGlzYWJsZS1zZXR1aWQtc2FuZGJveCcsXG4gICAgICAgICctLWRpc2FibGUtc2l0ZS1pc29sYXRpb24tdHJpYWxzJyxcbiAgICAgICAgJy0tZGlzYWJsZS1zcGVlY2gtYXBpJyxcbiAgICAgICAgJy0tZGlzYWJsZS1zeW5jJyxcbiAgICAgICAgJy0tZW5hYmxlLXVuc2FmZS13ZWJncHUnLFxuICAgICAgICAnLS1oaWRlLWNyYXNoLXJlc3RvcmUtYnViYmxlJyxcbiAgICAgICAgJy0taGlkZS1zY3JvbGxiYXJzJyxcbiAgICAgICAgJy0tbWV0cmljcy1yZWNvcmRpbmctb25seScsXG4gICAgICAgICctLW11dGUtYXVkaW8nLFxuICAgICAgICAnLS1uby1kZWZhdWx0LWJyb3dzZXItY2hlY2snLFxuICAgICAgICAnLS1uby1maXJzdC1ydW4nLFxuICAgICAgICAnLS1uby1waW5ncycsXG4gICAgICAgICctLXBpcGUnLFxuICAgICAgICAvLyAnLS1uby1zYW5kYm94JyxcbiAgICAgICAgJy0tbm8tc3RhcnR1cC13aW5kb3cnLFxuICAgICAgICAvLyAnLS1uby16eWdvdGUnLFxuICAgICAgICAnLS1wYXNzd29yZC1zdG9yZT1iYXNpYycsXG4gICAgICAgICctLXByb2Nlc3MtcGVyLXRhYicsXG4gICAgICAgICctLXVzZS1tb2NrLWtleWNoYWluJ1xuICAgICAgXSxcbiAgICAgIHR5cGU6ICdzdHJpbmdbXScsXG4gICAgICBkZXNjcmlwdGlvbjogJ0FyZ3VtZW50cyBhcnJheSB0byBzZW5kIHRvIFB1cHBldGVlci4nXG4gICAgfSxcbiAgICB0ZW1wRGlyOiB7XG4gICAgICB2YWx1ZTogJy4vdG1wLycsXG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIGVudkxpbms6ICdQVVBQRVRFRVJfVEVNUF9ESVInLFxuICAgICAgZGVzY3JpcHRpb246ICdUaGUgZGlyZWN0b3J5IGZvciBQdXBwZXRlZXIgdG8gc3RvcmUgdGVtcG9yYXJ5IGZpbGVzLidcbiAgICB9XG4gIH0sXG4gIGhpZ2hjaGFydHM6IHtcbiAgICB2ZXJzaW9uOiB7XG4gICAgICB2YWx1ZTogJ2xhdGVzdCcsXG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIGVudkxpbms6ICdISUdIQ0hBUlRTX1ZFUlNJT04nLFxuICAgICAgZGVzY3JpcHRpb246ICdUaGUgSGlnaGNoYXJ0cyB2ZXJzaW9uIHRvIGJlIHVzZWQuJ1xuICAgIH0sXG4gICAgY2RuVVJMOiB7XG4gICAgICB2YWx1ZTogJ2h0dHBzOi8vY29kZS5oaWdoY2hhcnRzLmNvbS8nLFxuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICBlbnZMaW5rOiAnSElHSENIQVJUU19DRE5fVVJMJyxcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhlIENETiBVUkwgZm9yIEhpZ2hjaGFydHMgc2NyaXB0cyB0byBiZSB1c2VkLidcbiAgICB9LFxuICAgIGNvcmVTY3JpcHRzOiB7XG4gICAgICB2YWx1ZTogc2NyaXB0c05hbWVzLmNvcmUsXG4gICAgICB0eXBlOiAnc3RyaW5nW10nLFxuICAgICAgZW52TGluazogJ0hJR0hDSEFSVFNfQ09SRV9TQ1JJUFRTJyxcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhlIGNvcmUgSGlnaGNoYXJ0cyBzY3JpcHRzIHRvIGZldGNoLidcbiAgICB9LFxuICAgIG1vZHVsZVNjcmlwdHM6IHtcbiAgICAgIHZhbHVlOiBzY3JpcHRzTmFtZXMubW9kdWxlcyxcbiAgICAgIHR5cGU6ICdzdHJpbmdbXScsXG4gICAgICBlbnZMaW5rOiAnSElHSENIQVJUU19NT0RVTEVfU0NSSVBUUycsXG4gICAgICBkZXNjcmlwdGlvbjogJ1RoZSBtb2R1bGVzIG9mIEhpZ2hjaGFydHMgdG8gZmV0Y2guJ1xuICAgIH0sXG4gICAgaW5kaWNhdG9yU2NyaXB0czoge1xuICAgICAgdmFsdWU6IHNjcmlwdHNOYW1lcy5pbmRpY2F0b3JzLFxuICAgICAgdHlwZTogJ3N0cmluZ1tdJyxcbiAgICAgIGVudkxpbms6ICdISUdIQ0hBUlRTX0lORElDQVRPUl9TQ1JJUFRTJyxcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhlIGluZGljYXRvcnMgb2YgSGlnaGNoYXJ0cyB0byBmZXRjaC4nXG4gICAgfSxcbiAgICBjdXN0b21TY3JpcHRzOiB7XG4gICAgICB2YWx1ZTogc2NyaXB0c05hbWVzLmN1c3RvbSxcbiAgICAgIHR5cGU6ICdzdHJpbmdbXScsXG4gICAgICBkZXNjcmlwdGlvbjogJ0FkZGl0aW9uYWwgY3VzdG9tIHNjcmlwdHMgb3IgZGVwZW5kZW5jaWVzIHRvIGZldGNoLidcbiAgICB9LFxuICAgIGZvcmNlRmV0Y2g6IHtcbiAgICAgIHZhbHVlOiBmYWxzZSxcbiAgICAgIHR5cGU6ICdib29sZWFuJyxcbiAgICAgIGVudkxpbms6ICdISUdIQ0hBUlRTX0ZPUkNFX0ZFVENIJyxcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnVGhlIGZsYWcgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgdG8gcmVmZXRjaCBhbGwgc2NyaXB0cyBhZnRlciBlYWNoIHNlcnZlciByZXJ1bi4nXG4gICAgfSxcbiAgICBjYWNoZVBhdGg6IHtcbiAgICAgIHZhbHVlOiAnLmNhY2hlJyxcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgZW52TGluazogJ0hJR0hDSEFSVFNfQ0FDSEVfUEFUSCcsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoZSBwYXRoIHRvIHRoZSBjYWNoZSBkaXJlY3RvcnkuIEl0IGlzIHVzZWQgdG8gc3RvcmUgdGhlIEhpZ2hjaGFydHMgc2NyaXB0cyBhbmQgY3VzdG9tIHNjcmlwdHMuJ1xuICAgIH1cbiAgfSxcbiAgZXhwb3J0OiB7XG4gICAgaW5maWxlOiB7XG4gICAgICB2YWx1ZTogZmFsc2UsXG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnVGhlIGlucHV0IGZpbGUgc2hvdWxkIGluY2x1ZGUgYSBuYW1lIGFuZCBhIHR5cGUgKGpzb24gb3Igc3ZnKS4gSXQgbXVzdCBiZSBjb3JyZWN0bHkgZm9ybWF0dGVkIGFzIGEgSlNPTiBvciBTVkcgZmlsZS4nXG4gICAgfSxcbiAgICBpbnN0cjoge1xuICAgICAgdmFsdWU6IGZhbHNlLFxuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ0lucHV0LCBwcm92aWRlZCBpbiB0aGUgZm9ybSBvZiBhIHN0cmluZ2lmaWVkIEpTT04gb3IgU1ZHIGZpbGUsIHdpbGwgb3ZlcnJpZGUgdGhlIC0taW5maWxlIG9wdGlvbi4nXG4gICAgfSxcbiAgICBvcHRpb25zOiB7XG4gICAgICB2YWx1ZTogZmFsc2UsXG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIGRlc2NyaXB0aW9uOiAnQW4gYWxpYXMgZm9yIHRoZSAtLWluc3RyIG9wdGlvbi4nXG4gICAgfSxcbiAgICBvdXRmaWxlOiB7XG4gICAgICB2YWx1ZTogZmFsc2UsXG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnVGhlIG91dHB1dCBmaWxlbmFtZSBhbG9uZyB3aXRoIGEgdHlwZSAoanBlZywgcG5nLCBwZGYsIG9yIHN2ZykuIFRoaXMgd2lsbCBpZ25vcmUgdGhlIC0tdHlwZSBmbGFnLidcbiAgICB9LFxuICAgIHR5cGU6IHtcbiAgICAgIHZhbHVlOiAncG5nJyxcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgZW52TGluazogJ0VYUE9SVF9UWVBFJyxcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhlIGZpbGUgZXhwb3J0IGZvcm1hdC4gSXQgY2FuIGJlIGpwZWcsIHBuZywgcGRmLCBvciBzdmcuJ1xuICAgIH0sXG4gICAgY29uc3RyOiB7XG4gICAgICB2YWx1ZTogJ2NoYXJ0JyxcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgZW52TGluazogJ0VYUE9SVF9DT05TVFInLFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdUaGUgY29uc3RydWN0b3IgdG8gdXNlLiBDYW4gYmUgY2hhcnQsIHN0b2NrQ2hhcnQsIG1hcENoYXJ0LCBvciBnYW50dENoYXJ0LidcbiAgICB9LFxuICAgIGRlZmF1bHRIZWlnaHQ6IHtcbiAgICAgIHZhbHVlOiA0MDAsXG4gICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICAgIGVudkxpbms6ICdFWFBPUlRfREVGQVVMVF9IRUlHSFQnLFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICd0aGUgZGVmYXVsdCBoZWlnaHQgb2YgdGhlIGV4cG9ydGVkIGNoYXJ0LiBVc2VkIHdoZW4gbm8gdmFsdWUgaXMgc2V0LidcbiAgICB9LFxuICAgIGRlZmF1bHRXaWR0aDoge1xuICAgICAgdmFsdWU6IDYwMCxcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgZW52TGluazogJ0VYUE9SVF9ERUZBVUxUX1dJRFRIJyxcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnVGhlIGRlZmF1bHQgd2lkdGggb2YgdGhlIGV4cG9ydGVkIGNoYXJ0LiBVc2VkIHdoZW4gbm8gdmFsdWUgaXMgc2V0LidcbiAgICB9LFxuICAgIGRlZmF1bHRTY2FsZToge1xuICAgICAgdmFsdWU6IDEsXG4gICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICAgIGVudkxpbms6ICdFWFBPUlRfREVGQVVMVF9TQ0FMRScsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoZSBkZWZhdWx0IHNjYWxlIG9mIHRoZSBleHBvcnRlZCBjaGFydC4gVXNlZCB3aGVuIG5vIHZhbHVlIGlzIHNldC4nXG4gICAgfSxcbiAgICBoZWlnaHQ6IHtcbiAgICAgIHZhbHVlOiBmYWxzZSxcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdUaGUgaGVpZ2h0IG9mIHRoZSBleHBvcnRlZCBjaGFydCwgb3ZlcnJpZGluZyB0aGUgb3B0aW9uIGluIHRoZSBjaGFydCBzZXR0aW5ncy4nXG4gICAgfSxcbiAgICB3aWR0aDoge1xuICAgICAgdmFsdWU6IGZhbHNlLFxuICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoZSB3aWR0aCBvZiB0aGUgZXhwb3J0ZWQgY2hhcnQsIG92ZXJyaWRpbmcgdGhlIG9wdGlvbiBpbiB0aGUgY2hhcnQgc2V0dGluZ3MuJ1xuICAgIH0sXG4gICAgc2NhbGU6IHtcbiAgICAgIHZhbHVlOiBmYWxzZSxcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdUaGUgc2NhbGUgb2YgdGhlIGV4cG9ydGVkIGNoYXJ0LCBvdmVycmlkaW5nIHRoZSBvcHRpb24gaW4gdGhlIGNoYXJ0IHNldHRpbmdzLiBSYW5nZXMgYmV0d2VlbiAwLjEgYW5kIDUuMC4nXG4gICAgfSxcbiAgICBnbG9iYWxPcHRpb25zOiB7XG4gICAgICB2YWx1ZTogZmFsc2UsXG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnRWl0aGVyIGEgc3RyaW5naWZpZWQgSlNPTiBvciBhIGZpbGVuYW1lIGNvbnRhaW5pbmcgb3B0aW9ucyB0byBiZSBwYXNzZWQgaW50byB0aGUgSGlnaGNoYXJ0cy5zZXRPcHRpb25zLidcbiAgICB9LFxuICAgIHRoZW1lT3B0aW9uczoge1xuICAgICAgdmFsdWU6IGZhbHNlLFxuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ0VpdGhlciBhIHN0cmluZ2lmaWVkIEpTT04gb3IgYSBmaWxlbmFtZSBjb250YWluaW5nIHRoZW1lIG9wdGlvbnMgdG8gYmUgcGFzc2VkIGludG8gdGhlIEhpZ2hjaGFydHMuc2V0T3B0aW9ucy4nXG4gICAgfSxcbiAgICBiYXRjaDoge1xuICAgICAgdmFsdWU6IGZhbHNlLFxuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ0luaXRpYXRlcyBhIGJhdGNoIGpvYiB3aXRoIGEgc3RyaW5nIGNvbnRhaW5pbmcgaW5wdXQvb3V0cHV0IHBhaXJzOiBcImluPW91dDtpbj1vdXQ7Li4uXCIuJ1xuICAgIH0sXG4gICAgcmFzdGVyaXphdGlvblRpbWVvdXQ6IHtcbiAgICAgIHZhbHVlOiAxNTAwLFxuICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICBlbnZMaW5rOiAnRVhQT1JUX1JBU1RFUklaQVRJT05fVElNRU9VVCcsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoZSBkdXJhdGlvbiBpbiBtaWxsaXNlY29uZHMgdG8gd2FpdCBmb3IgcmVuZGVyaW5nIGEgd2VicGFnZS4nXG4gICAgfVxuICB9LFxuICBjdXN0b21Mb2dpYzoge1xuICAgIGFsbG93Q29kZUV4ZWN1dGlvbjoge1xuICAgICAgdmFsdWU6IGZhbHNlLFxuICAgICAgdHlwZTogJ2Jvb2xlYW4nLFxuICAgICAgZW52TGluazogJ0NVU1RPTV9MT0dJQ19BTExPV19DT0RFX0VYRUNVVElPTicsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ0NvbnRyb2xzIHdoZXRoZXIgdGhlIGV4ZWN1dGlvbiBvZiBhcmJpdHJhcnkgY29kZSBpcyBhbGxvd2VkIGR1cmluZyB0aGUgZXhwb3J0aW5nIHByb2Nlc3MuJ1xuICAgIH0sXG4gICAgYWxsb3dGaWxlUmVzb3VyY2VzOiB7XG4gICAgICB2YWx1ZTogZmFsc2UsXG4gICAgICB0eXBlOiAnYm9vbGVhbicsXG4gICAgICBlbnZMaW5rOiAnQ1VTVE9NX0xPR0lDX0FMTE9XX0ZJTEVfUkVTT1VSQ0VTJyxcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnQ29udHJvbHMgdGhlIGFiaWxpdHkgdG8gaW5qZWN0IHJlc291cmNlcyBmcm9tIHRoZSBmaWxlc3lzdGVtLiBUaGlzIHNldHRpbmcgaGFzIG5vIGVmZmVjdCB3aGVuIHJ1bm5pbmcgYXMgYSBzZXJ2ZXIuJ1xuICAgIH0sXG4gICAgY3VzdG9tQ29kZToge1xuICAgICAgdmFsdWU6IGZhbHNlLFxuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ0N1c3RvbSBjb2RlIHRvIGV4ZWN1dGUgYmVmb3JlIGNoYXJ0IGluaXRpYWxpemF0aW9uLiBJdCBjYW4gYmUgYSBmdW5jdGlvbiwgY29kZSB3cmFwcGVkIHdpdGhpbiBhIGZ1bmN0aW9uLCBvciBhIGZpbGVuYW1lIHdpdGggdGhlIC5qcyBleHRlbnNpb24uJ1xuICAgIH0sXG4gICAgY2FsbGJhY2s6IHtcbiAgICAgIHZhbHVlOiBmYWxzZSxcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdKYXZhU2NyaXB0IGNvZGUgdG8gcnVuIGR1cmluZyBjb25zdHJ1Y3Rpb24uIEl0IGNhbiBiZSBhIGZ1bmN0aW9uIG9yIGEgZmlsZW5hbWUgd2l0aCB0aGUgLmpzIGV4dGVuc2lvbi4nXG4gICAgfSxcbiAgICByZXNvdXJjZXM6IHtcbiAgICAgIHZhbHVlOiBmYWxzZSxcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdBZGRpdGlvbmFsIHJlc291cmNlIGluIHRoZSBmb3JtIG9mIGEgc3RyaW5naWZpZWQgSlNPTiwgd2hpY2ggbWF5IGNvbnRhaW4gZmlsZXMsIGpzLCBhbmQgY3NzIHNlY3Rpb25zLidcbiAgICB9LFxuICAgIGxvYWRDb25maWc6IHtcbiAgICAgIHZhbHVlOiBmYWxzZSxcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgbGVnYWN5TmFtZTogJ2Zyb21GaWxlJyxcbiAgICAgIGRlc2NyaXB0aW9uOiAnQSBmaWxlIGNvbnRhaW5pbmcgYSBwcmUtZGVmaW5lZCBjb25maWd1cmF0aW9uIHRvIHVzZS4nXG4gICAgfSxcbiAgICBjcmVhdGVDb25maWc6IHtcbiAgICAgIHZhbHVlOiBmYWxzZSxcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdFbmFibGVzIHNldHRpbmcgb3B0aW9ucyB0aHJvdWdoIGEgcHJvbXB0IGFuZCBzYXZpbmcgdGhlbSBpbiBhIHByb3ZpZGVkIGNvbmZpZyBmaWxlLidcbiAgICB9XG4gIH0sXG4gIHNlcnZlcjoge1xuICAgIG1heFVwbG9hZFNpemU6IHtcbiAgICAgIHZhbHVlOiAzLFxuICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICBlbnZMaW5rOiAnU0VSVkVSX01BWF9VUExPQURfU0laRScsXG4gICAgICBkZXNjcmlwdGlvbjogJ1RoZSBtYXhpbXVtIHVwbG9hZCBzaXplLCBpbiBNQiwgZm9yIHRoZSBzZXJ2ZXIuJ1xuICAgIH0sXG4gICAgZW5hYmxlOiB7XG4gICAgICB2YWx1ZTogZmFsc2UsXG4gICAgICB0eXBlOiAnYm9vbGVhbicsXG4gICAgICBlbnZMaW5rOiAnU0VSVkVSX0VOQUJMRScsXG4gICAgICBjbGlOYW1lOiAnZW5hYmxlU2VydmVyJyxcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnV2hlbiBzZXQgdG8gdHJ1ZSwgdGhlIHNlcnZlciBzdGFydHMgb24gdGhlIGxvY2FsIElQIGFkZHJlc3MgMC4wLjAuMC4nXG4gICAgfSxcbiAgICBob3N0OiB7XG4gICAgICB2YWx1ZTogJzAuMC4wLjAnLFxuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICBlbnZMaW5rOiAnU0VSVkVSX0hPU1QnLFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdUaGUgaG9zdG5hbWUgb2YgdGhlIHNlcnZlci4gQWRkaXRpb25hbGx5LCBpdCBzdGFydHMgYSBzZXJ2ZXIgb24gdGhlIHByb3ZpZGVkIGhvc3RuYW1lLidcbiAgICB9LFxuICAgIHBvcnQ6IHtcbiAgICAgIHZhbHVlOiA3ODAxLFxuICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICBlbnZMaW5rOiAnU0VSVkVSX1BPUlQnLFxuICAgICAgZGVzY3JpcHRpb246ICdUaGUgc2VydmVyIHBvcnQgd2hlbiBlbmFibGVkLidcbiAgICB9LFxuICAgIGJlbmNobWFya2luZzoge1xuICAgICAgdmFsdWU6IGZhbHNlLFxuICAgICAgdHlwZTogJ2Jvb2xlYW4nLFxuICAgICAgZW52TGluazogJ1NFUlZFUl9CRU5DSE1BUktJTkcnLFxuICAgICAgY2xpTmFtZTogJ3NlcnZlckJlbmNobWFya2luZycsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ0luZGljYXRlcyB3aGV0aGVyIHRvIGRpc3BsYXkgdGhlIGR1cmF0aW9uLCBpbiBtaWxsaXNlY29uZHMsIG9mIHNwZWNpZmljIGFjdGlvbnMgdGhhdCBvY2N1ciBvbiB0aGUgc2VydmVyIHdoaWxlIHNlcnZpbmcgYSByZXF1ZXN0LidcbiAgICB9LFxuICAgIHByb3h5OiB7XG4gICAgICBob3N0OiB7XG4gICAgICAgIHZhbHVlOiBmYWxzZSxcbiAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgIGVudkxpbms6ICdTRVJWRVJfUFJPWFlfSE9TVCcsXG4gICAgICAgIGNsaU5hbWU6ICdwcm94eUhvc3QnLFxuICAgICAgICBkZXNjcmlwdGlvbjogJ1RoZSBob3N0IG9mIHRoZSBwcm94eSBzZXJ2ZXIgdG8gdXNlLCBpZiBpdCBleGlzdHMuJ1xuICAgICAgfSxcbiAgICAgIHBvcnQ6IHtcbiAgICAgICAgdmFsdWU6IDgwODAsXG4gICAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgICBlbnZMaW5rOiAnU0VSVkVSX1BST1hZX1BPUlQnLFxuICAgICAgICBjbGlOYW1lOiAncHJveHlQb3J0JyxcbiAgICAgICAgZGVzY3JpcHRpb246ICdUaGUgcG9ydCBvZiB0aGUgcHJveHkgc2VydmVyIHRvIHVzZSwgaWYgaXQgZXhpc3RzLidcbiAgICAgIH0sXG4gICAgICB1c2VybmFtZToge1xuICAgICAgICB2YWx1ZTogZmFsc2UsXG4gICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICBlbnZMaW5rOiAnU0VSVkVSX1BST1hZX1VTRVJOQU1FJyxcbiAgICAgICAgY2xpTmFtZTogJ3Byb3h5VXNlcm5hbWUnLFxuICAgICAgICBkZXNjcmlwdGlvbjogJ1RoZSB1c2VybmFtZSBmb3IgdGhlIHByb3h5IHNlcnZlciwgaWYgaXQgZXhpc3RzLidcbiAgICAgIH0sXG4gICAgICBwYXNzd29yZDoge1xuICAgICAgICB2YWx1ZTogZmFsc2UsXG4gICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICBlbnZMaW5rOiAnU0VSVkVSX1BST1hZX1BBU1NXT1JEJyxcbiAgICAgICAgY2xpTmFtZTogJ3Byb3h5UGFzc3dvcmQnLFxuICAgICAgICBkZXNjcmlwdGlvbjogJ1RoZSBwYXNzd29yZCBmb3IgdGhlIHByb3h5IHNlcnZlciwgaWYgaXQgZXhpc3RzLidcbiAgICAgIH0sXG4gICAgICB0aW1lb3V0OiB7XG4gICAgICAgIHZhbHVlOiA1MDAwLFxuICAgICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICAgICAgZW52TGluazogJ1NFUlZFUl9QUk9YWV9USU1FT1VUJyxcbiAgICAgICAgY2xpTmFtZTogJ3Byb3h5VGltZW91dCcsXG4gICAgICAgIGRlc2NyaXB0aW9uOiAnVGhlIHRpbWVvdXQgZm9yIHRoZSBwcm94eSBzZXJ2ZXIgdG8gdXNlLCBpZiBpdCBleGlzdHMuJ1xuICAgICAgfVxuICAgIH0sXG4gICAgcmF0ZUxpbWl0aW5nOiB7XG4gICAgICBlbmFibGU6IHtcbiAgICAgICAgdmFsdWU6IGZhbHNlLFxuICAgICAgICB0eXBlOiAnYm9vbGVhbicsXG4gICAgICAgIGVudkxpbms6ICdTRVJWRVJfUkFURV9MSU1JVElOR19FTkFCTEUnLFxuICAgICAgICBjbGlOYW1lOiAnZW5hYmxlUmF0ZUxpbWl0aW5nJyxcbiAgICAgICAgZGVzY3JpcHRpb246ICdFbmFibGVzIHJhdGUgbGltaXRpbmcgZm9yIHRoZSBzZXJ2ZXIuJ1xuICAgICAgfSxcbiAgICAgIG1heFJlcXVlc3RzOiB7XG4gICAgICAgIHZhbHVlOiAxMCxcbiAgICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICAgIGVudkxpbms6ICdTRVJWRVJfUkFURV9MSU1JVElOR19NQVhfUkVRVUVTVFMnLFxuICAgICAgICBsZWdhY3lOYW1lOiAncmF0ZUxpbWl0JyxcbiAgICAgICAgZGVzY3JpcHRpb246ICdUaGUgbWF4aW11bSBudW1iZXIgb2YgcmVxdWVzdHMgYWxsb3dlZCBpbiBvbmUgbWludXRlLidcbiAgICAgIH0sXG4gICAgICB3aW5kb3c6IHtcbiAgICAgICAgdmFsdWU6IDEsXG4gICAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgICBlbnZMaW5rOiAnU0VSVkVSX1JBVEVfTElNSVRJTkdfV0lORE9XJyxcbiAgICAgICAgZGVzY3JpcHRpb246ICdUaGUgdGltZSB3aW5kb3csIGluIG1pbnV0ZXMsIGZvciB0aGUgcmF0ZSBsaW1pdGluZy4nXG4gICAgICB9LFxuICAgICAgZGVsYXk6IHtcbiAgICAgICAgdmFsdWU6IDAsXG4gICAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgICBlbnZMaW5rOiAnU0VSVkVSX1JBVEVfTElNSVRJTkdfREVMQVknLFxuICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAnVGhlIGRlbGF5IGR1cmF0aW9uIGZvciBlYWNoIHN1Y2Nlc3NpdmUgcmVxdWVzdCBiZWZvcmUgcmVhY2hpbmcgdGhlIG1heGltdW0gbGltaXQuJ1xuICAgICAgfSxcbiAgICAgIHRydXN0UHJveHk6IHtcbiAgICAgICAgdmFsdWU6IGZhbHNlLFxuICAgICAgICB0eXBlOiAnYm9vbGVhbicsXG4gICAgICAgIGVudkxpbms6ICdTRVJWRVJfUkFURV9MSU1JVElOR19UUlVTVF9QUk9YWScsXG4gICAgICAgIGRlc2NyaXB0aW9uOiAnU2V0IHRoaXMgdG8gdHJ1ZSBpZiB0aGUgc2VydmVyIGlzIGJlaGluZCBhIGxvYWQgYmFsYW5jZXIuJ1xuICAgICAgfSxcbiAgICAgIHNraXBLZXk6IHtcbiAgICAgICAgdmFsdWU6IGZhbHNlLFxuICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgZW52TGluazogJ1NFUlZFUl9SQVRFX0xJTUlUSU5HX1NLSVBfS0VZJyxcbiAgICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICAgJ0FsbG93cyBieXBhc3NpbmcgdGhlIHJhdGUgbGltaXRlciBhbmQgc2hvdWxkIGJlIHByb3ZpZGVkIHdpdGggdGhlIHNraXBUb2tlbiBhcmd1bWVudC4nXG4gICAgICB9LFxuICAgICAgc2tpcFRva2VuOiB7XG4gICAgICAgIHZhbHVlOiBmYWxzZSxcbiAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgIGVudkxpbms6ICdTRVJWRVJfUkFURV9MSU1JVElOR19TS0lQX1RPS0VOJyxcbiAgICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICAgJ0FsbG93cyBieXBhc3NpbmcgdGhlIHJhdGUgbGltaXRlciBhbmQgc2hvdWxkIGJlIHByb3ZpZGVkIHdpdGggdGhlIHNraXBLZXkgYXJndW1lbnQuJ1xuICAgICAgfVxuICAgIH0sXG4gICAgc3NsOiB7XG4gICAgICBlbmFibGU6IHtcbiAgICAgICAgdmFsdWU6IGZhbHNlLFxuICAgICAgICB0eXBlOiAnYm9vbGVhbicsXG4gICAgICAgIGVudkxpbms6ICdTRVJWRVJfU1NMX0VOQUJMRScsXG4gICAgICAgIGNsaU5hbWU6ICdlbmFibGVTc2wnLFxuICAgICAgICBkZXNjcmlwdGlvbjogJ0VuYWJsZXMgb3IgZGlzYWJsZXMgdGhlIFNTTCBwcm90b2NvbC4nXG4gICAgICB9LFxuICAgICAgZm9yY2U6IHtcbiAgICAgICAgdmFsdWU6IGZhbHNlLFxuICAgICAgICB0eXBlOiAnYm9vbGVhbicsXG4gICAgICAgIGVudkxpbms6ICdTRVJWRVJfU1NMX0ZPUkNFJyxcbiAgICAgICAgY2xpTmFtZTogJ3NzbEZvcmNlJyxcbiAgICAgICAgbGVnYWN5TmFtZTogJ3NzbE9ubHknLFxuICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAnV2hlbiBzZXQgdG8gdHJ1ZSwgdGhlIHNlcnZlciBpcyBmb3JjZWQgdG8gc2VydmUgb25seSBvdmVyIEhUVFBTLidcbiAgICAgIH0sXG4gICAgICBwb3J0OiB7XG4gICAgICAgIHZhbHVlOiA0NDMsXG4gICAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgICBlbnZMaW5rOiAnU0VSVkVSX1NTTF9QT1JUJyxcbiAgICAgICAgY2xpTmFtZTogJ3NzbFBvcnQnLFxuICAgICAgICBkZXNjcmlwdGlvbjogJ1RoZSBwb3J0IG9uIHdoaWNoIHRvIHJ1biB0aGUgU1NMIHNlcnZlci4nXG4gICAgICB9LFxuICAgICAgY2VydFBhdGg6IHtcbiAgICAgICAgdmFsdWU6IGZhbHNlLFxuICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgZW52TGluazogJ1NFUlZFUl9TU0xfQ0VSVF9QQVRIJyxcbiAgICAgICAgbGVnYWN5TmFtZTogJ3NzbFBhdGgnLFxuICAgICAgICBkZXNjcmlwdGlvbjogJ1RoZSBwYXRoIHRvIHRoZSBTU0wgY2VydGlmaWNhdGUva2V5IGZpbGUuJ1xuICAgICAgfVxuICAgIH1cbiAgfSxcbiAgcG9vbDoge1xuICAgIG1pbldvcmtlcnM6IHtcbiAgICAgIHZhbHVlOiA0LFxuICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICBlbnZMaW5rOiAnUE9PTF9NSU5fV09SS0VSUycsXG4gICAgICBkZXNjcmlwdGlvbjogJ1RoZSBudW1iZXIgb2YgbWluaW11bSBhbmQgaW5pdGlhbCBwb29sIHdvcmtlcnMgdG8gc3Bhd24uJ1xuICAgIH0sXG4gICAgbWF4V29ya2Vyczoge1xuICAgICAgdmFsdWU6IDgsXG4gICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICAgIGVudkxpbms6ICdQT09MX01BWF9XT1JLRVJTJyxcbiAgICAgIGxlZ2FjeU5hbWU6ICd3b3JrZXJzJyxcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhlIG51bWJlciBvZiBtYXhpbXVtIHBvb2wgd29ya2VycyB0byBzcGF3bi4nXG4gICAgfSxcbiAgICB3b3JrTGltaXQ6IHtcbiAgICAgIHZhbHVlOiA0MCxcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgZW52TGluazogJ1BPT0xfV09SS19MSU1JVCcsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoZSBudW1iZXIgb2Ygd29yayBwaWVjZXMgdGhhdCBjYW4gYmUgcGVyZm9ybWVkIGJlZm9yZSByZXN0YXJ0aW5nIHRoZSB3b3JrZXIgcHJvY2Vzcy4nXG4gICAgfSxcbiAgICBhY3F1aXJlVGltZW91dDoge1xuICAgICAgdmFsdWU6IDUwMDAsXG4gICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICAgIGVudkxpbms6ICdQT09MX0FDUVVJUkVfVElNRU9VVCcsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoZSBkdXJhdGlvbiwgaW4gbWlsbGlzZWNvbmRzLCB0byB3YWl0IGZvciBhY3F1aXJpbmcgYSByZXNvdXJjZS4nXG4gICAgfSxcbiAgICBjcmVhdGVUaW1lb3V0OiB7XG4gICAgICB2YWx1ZTogNTAwMCxcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgZW52TGluazogJ1BPT0xfQ1JFQVRFX1RJTUVPVVQnLFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdUaGUgZHVyYXRpb24sIGluIG1pbGxpc2Vjb25kcywgdG8gd2FpdCBmb3IgY3JlYXRpbmcgYSByZXNvdXJjZS4nXG4gICAgfSxcbiAgICBkZXN0cm95VGltZW91dDoge1xuICAgICAgdmFsdWU6IDUwMDAsXG4gICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICAgIGVudkxpbms6ICdQT09MX0RFU1RST1lfVElNRU9VVCcsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoZSBkdXJhdGlvbiwgaW4gbWlsbGlzZWNvbmRzLCB0byB3YWl0IGZvciBkZXN0cm95aW5nIGEgcmVzb3VyY2UuJ1xuICAgIH0sXG4gICAgaWRsZVRpbWVvdXQ6IHtcbiAgICAgIHZhbHVlOiAzMDAwMCxcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgZW52TGluazogJ1BPT0xfSURMRV9USU1FT1VUJyxcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnVGhlIGR1cmF0aW9uLCBpbiBtaWxsaXNlY29uZHMsIGFmdGVyIHdoaWNoIGFuIGlkbGUgcmVzb3VyY2UgaXMgZGVzdHJveWVkLidcbiAgICB9LFxuICAgIGNyZWF0ZVJldHJ5SW50ZXJ2YWw6IHtcbiAgICAgIHZhbHVlOiAyMDAsXG4gICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICAgIGVudkxpbms6ICdQT09MX0NSRUFURV9SRVRSWV9JTlRFUlZBTCcsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoZSBkdXJhdGlvbiwgaW4gbWlsbGlzZWNvbmRzLCB0byB3YWl0IGJlZm9yZSByZXRyeWluZyB0aGUgY3JlYXRlIHByb2Nlc3MgaW4gY2FzZSBvZiBhIGZhaWx1cmUuJ1xuICAgIH0sXG4gICAgcmVhcGVySW50ZXJ2YWw6IHtcbiAgICAgIHZhbHVlOiAxMDAwLFxuICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICBlbnZMaW5rOiAnUE9PTF9SRUFQRVJfSU5URVJWQUwnLFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdUaGUgZHVyYXRpb24sIGluIG1pbGxpc2Vjb25kcywgYWZ0ZXIgd2hpY2ggdGhlIGNoZWNrIGZvciBpZGxlIHJlc291cmNlcyB0byBkZXN0cm95IGlzIHRyaWdnZXJlZC4nXG4gICAgfSxcbiAgICBiZW5jaG1hcmtpbmc6IHtcbiAgICAgIHZhbHVlOiBmYWxzZSxcbiAgICAgIHR5cGU6ICdib29sZWFuJyxcbiAgICAgIGVudkxpbms6ICdQT09MX0JFTkNITUFSS0lORycsXG4gICAgICBjbGlOYW1lOiAncG9vbEJlbmNobWFya2luZycsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ0luZGljYXRlIHdoZXRoZXIgdG8gc2hvdyBzdGF0aXN0aWNzIGZvciB0aGUgcG9vbCBvZiByZXNvdXJjZXMgb3Igbm90LidcbiAgICB9XG4gIH0sXG4gIGxvZ2dpbmc6IHtcbiAgICBsZXZlbDoge1xuICAgICAgdmFsdWU6IDQsXG4gICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICAgIGVudkxpbms6ICdMT0dHSU5HX0xFVkVMJyxcbiAgICAgIGNsaU5hbWU6ICdsb2dMZXZlbCcsXG4gICAgICBkZXNjcmlwdGlvbjogJ1RoZSBsb2dnaW5nIGxldmVsIHRvIGJlIHVzZWQuJ1xuICAgIH0sXG4gICAgZmlsZToge1xuICAgICAgdmFsdWU6ICdoaWdoY2hhcnRzLWV4cG9ydC1zZXJ2ZXIubG9nJyxcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgZW52TGluazogJ0xPR0dJTkdfRklMRScsXG4gICAgICBjbGlOYW1lOiAnbG9nRmlsZScsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoZSBuYW1lIG9mIGEgbG9nIGZpbGUuIFRoZSBgbG9nVG9GaWxlYCBhbmQgYGxvZ0Rlc3RgIG9wdGlvbnMgYWxzbyBuZWVkIHRvIGJlIHNldCB0byBlbmFibGUgZmlsZSBsb2dnaW5nLidcbiAgICB9LFxuICAgIGRlc3Q6IHtcbiAgICAgIHZhbHVlOiAnbG9nLycsXG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIGVudkxpbms6ICdMT0dHSU5HX0RFU1QnLFxuICAgICAgY2xpTmFtZTogJ2xvZ0Rlc3QnLFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdUaGUgcGF0aCB0byBzdG9yZSBsb2cgZmlsZXMuIFRoZSBgbG9nVG9GaWxlYCBvcHRpb24gYWxzbyBuZWVkcyB0byBiZSBzZXQgdG8gZW5hYmxlIGZpbGUgbG9nZ2luZy4nXG4gICAgfSxcbiAgICB0b0NvbnNvbGU6IHtcbiAgICAgIHZhbHVlOiB0cnVlLFxuICAgICAgdHlwZTogJ2Jvb2xlYW4nLFxuICAgICAgZW52TGluazogJ0xPR0dJTkdfVE9fQ09OU09MRScsXG4gICAgICBjbGlOYW1lOiAnbG9nVG9Db25zb2xlJyxcbiAgICAgIGRlc2NyaXB0aW9uOiAnRW5hYmxlcyBvciBkaXNhYmxlcyBzaG93aW5nIGxvZ3MgaW4gdGhlIGNvbnNvbGUuJ1xuICAgIH0sXG4gICAgdG9GaWxlOiB7XG4gICAgICB2YWx1ZTogdHJ1ZSxcbiAgICAgIHR5cGU6ICdib29sZWFuJyxcbiAgICAgIGVudkxpbms6ICdMT0dHSU5HX1RPX0ZJTEUnLFxuICAgICAgY2xpTmFtZTogJ2xvZ1RvRmlsZScsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ0VuYWJsZXMgb3IgZGlzYWJsZXMgY3JlYXRpb24gb2YgdGhlIGxvZyBkaXJlY3RvcnkgYW5kIHNhdmluZyB0aGUgbG9nIGludG8gYSAubG9nIGZpbGUuJ1xuICAgIH1cbiAgfSxcbiAgdWk6IHtcbiAgICBlbmFibGU6IHtcbiAgICAgIHZhbHVlOiBmYWxzZSxcbiAgICAgIHR5cGU6ICdib29sZWFuJyxcbiAgICAgIGVudkxpbms6ICdVSV9FTkFCTEUnLFxuICAgICAgY2xpTmFtZTogJ2VuYWJsZVVpJyxcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnRW5hYmxlcyBvciBkaXNhYmxlcyB0aGUgdXNlciBpbnRlcmZhY2UgKFVJKSBmb3IgdGhlIGV4cG9ydCBzZXJ2ZXIuJ1xuICAgIH0sXG4gICAgcm91dGU6IHtcbiAgICAgIHZhbHVlOiAnLycsXG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIGVudkxpbms6ICdVSV9ST1VURScsXG4gICAgICBjbGlOYW1lOiAndWlSb3V0ZScsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoZSBlbmRwb2ludCByb3V0ZSB0byB3aGljaCB0aGUgdXNlciBpbnRlcmZhY2UgKFVJKSBzaG91bGQgYmUgYXR0YWNoZWQuJ1xuICAgIH1cbiAgfSxcbiAgb3RoZXI6IHtcbiAgICBub2RlRW52OiB7XG4gICAgICB2YWx1ZTogJ3Byb2R1Y3Rpb24nLFxuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICBlbnZMaW5rOiAnT1RIRVJfTk9ERV9FTlYnLFxuICAgICAgZGVzY3JpcHRpb246ICdUaGUgdHlwZSBvZiBOb2RlLmpzIGVudmlyb25tZW50LidcbiAgICB9LFxuICAgIGxpc3RlblRvUHJvY2Vzc0V4aXRzOiB7XG4gICAgICB2YWx1ZTogdHJ1ZSxcbiAgICAgIHR5cGU6ICdib29sZWFuJyxcbiAgICAgIGVudkxpbms6ICdPVEhFUl9MSVNURU5fVE9fUFJPQ0VTU19FWElUUycsXG4gICAgICBkZXNjcmlwdGlvbjogJ0RlY2lkZXMgd2hldGhlciBvciBub3QgdG8gYXR0YWNoIHByb2Nlc3MuZXhpdCBoYW5kbGVycy4nXG4gICAgfSxcbiAgICBub0xvZ286IHtcbiAgICAgIHZhbHVlOiBmYWxzZSxcbiAgICAgIHR5cGU6ICdib29sZWFuJyxcbiAgICAgIGVudkxpbms6ICdPVEhFUl9OT19MT0dPJyxcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnU2tpcCBwcmludGluZyB0aGUgbG9nbyBvbiBhIHN0YXJ0dXAuIFdpbGwgYmUgcmVwbGFjZWQgYnkgYSBzaW1wbGUgdGV4dC4nXG4gICAgfSxcbiAgICBoYXJkUmVzZXRQYWdlOiB7XG4gICAgICB2YWx1ZTogZmFsc2UsXG4gICAgICB0eXBlOiAnYm9vbGVhbicsXG4gICAgICBlbnZMaW5rOiAnT1RIRVJfSEFSRF9SRVNFVF9QQUdFJyxcbiAgICAgIGRlc2NyaXB0aW9uOiAnRGVjaWRlcyBpZiB0aGUgcGFnZSBjb250ZW50IHNob3VsZCBiZSByZXNldCBlbnRpcmVseS4nXG4gICAgfSxcbiAgICBicm93c2VyU2hlbGxNb2RlOiB7XG4gICAgICB2YWx1ZTogdHJ1ZSxcbiAgICAgIHR5cGU6ICdib29sZWFuJyxcbiAgICAgIGVudkxpbms6ICdPVEhFUl9CUk9XU0VSX1NIRUxMX01PREUnLFxuICAgICAgZGVzY3JpcHRpb246ICdEZWNpZGVzIGlmIHRoZSBicm93c2VyIHJ1bnMgaW4gdGhlIHNoZWxsIG1vZGUuJ1xuICAgIH1cbiAgfSxcbiAgZGVidWc6IHtcbiAgICBlbmFibGU6IHtcbiAgICAgIHZhbHVlOiBmYWxzZSxcbiAgICAgIHR5cGU6ICdib29sZWFuJyxcbiAgICAgIGVudkxpbms6ICdERUJVR19FTkFCTEUnLFxuICAgICAgY2xpTmFtZTogJ2VuYWJsZURlYnVnJyxcbiAgICAgIGRlc2NyaXB0aW9uOiAnRW5hYmxlcyBvciBkaXNhYmxlcyBkZWJ1ZyBtb2RlIGZvciB0aGUgdW5kZXJseWluZyBicm93c2VyLidcbiAgICB9LFxuICAgIGhlYWRsZXNzOiB7XG4gICAgICB2YWx1ZTogdHJ1ZSxcbiAgICAgIHR5cGU6ICdib29sZWFuJyxcbiAgICAgIGVudkxpbms6ICdERUJVR19IRUFETEVTUycsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ0NvbnRyb2xzIHRoZSBtb2RlIGluIHdoaWNoIHRoZSBicm93c2VyIGlzIGxhdW5jaGVkIHdoZW4gaW4gdGhlIGRlYnVnIG1vZGUuJ1xuICAgIH0sXG4gICAgZGV2dG9vbHM6IHtcbiAgICAgIHZhbHVlOiBmYWxzZSxcbiAgICAgIHR5cGU6ICdib29sZWFuJyxcbiAgICAgIGVudkxpbms6ICdERUJVR19ERVZUT09MUycsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ0RlY2lkZXMgd2hldGhlciB0byBlbmFibGUgRGV2VG9vbHMgd2hlbiB0aGUgYnJvd3NlciBpcyBpbiBhIGhlYWRmdWwgc3RhdGUuJ1xuICAgIH0sXG4gICAgbGlzdGVuVG9Db25zb2xlOiB7XG4gICAgICB2YWx1ZTogZmFsc2UsXG4gICAgICB0eXBlOiAnYm9vbGVhbicsXG4gICAgICBlbnZMaW5rOiAnREVCVUdfTElTVEVOX1RPX0NPTlNPTEUnLFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdEZWNpZGVzIHdoZXRoZXIgdG8gZW5hYmxlIGEgbGlzdGVuZXIgZm9yIGNvbnNvbGUgbWVzc2FnZXMgc2VudCBmcm9tIHRoZSBicm93c2VyLidcbiAgICB9LFxuICAgIGR1bXBpbzoge1xuICAgICAgdmFsdWU6IGZhbHNlLFxuICAgICAgdHlwZTogJ2Jvb2xlYW4nLFxuICAgICAgZW52TGluazogJ0RFQlVHX0RVTVBJTycsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1JlZGlyZWN0cyBicm93c2VyIHByb2Nlc3Mgc3Rkb3V0IGFuZCBzdGRlcnIgdG8gcHJvY2Vzcy5zdGRvdXQgYW5kIHByb2Nlc3Muc3RkZXJyLidcbiAgICB9LFxuICAgIHNsb3dNbzoge1xuICAgICAgdmFsdWU6IDAsXG4gICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICAgIGVudkxpbms6ICdERUJVR19TTE9XX01PJyxcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnU2xvd3MgZG93biBQdXBwZXRlZXIgb3BlcmF0aW9ucyBieSB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiBtaWxsaXNlY29uZHMuJ1xuICAgIH0sXG4gICAgZGVidWdnaW5nUG9ydDoge1xuICAgICAgdmFsdWU6IDkyMjIsXG4gICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICAgIGVudkxpbms6ICdERUJVR19ERUJVR0dJTkdfUE9SVCcsXG4gICAgICBkZXNjcmlwdGlvbjogJ1NwZWNpZmllcyB0aGUgZGVidWdnaW5nIHBvcnQuJ1xuICAgIH1cbiAgfVxufTtcblxuLy8gVGhlIGNvbmZpZyBkZXNjcmlwdGlvbnMgb2JqZWN0IGZvciB0aGUgcHJvbXB0cyBmdW5jdGlvbmFsaXR5LiBJdCBjb250YWluc1xuLy8gaW5mb3JtYXRpb24gbGlrZTpcbi8vICogVHlwZSBvZiBhIHByb21wdFxuLy8gKiBOYW1lIG9mIGFuIG9wdGlvblxuLy8gKiBTaG9ydCBkZXNjcmlwdGlvbiBvZiBhIGNob3NlbiBvcHRpb25cbi8vICogSW5pdGlhbCB2YWx1ZVxuZXhwb3J0IGNvbnN0IHByb21wdHNDb25maWcgPSB7XG4gIHB1cHBldGVlcjogW1xuICAgIHtcbiAgICAgIHR5cGU6ICdsaXN0JyxcbiAgICAgIG5hbWU6ICdhcmdzJyxcbiAgICAgIG1lc3NhZ2U6ICdQdXBwZXRlZXIgYXJndW1lbnRzJyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcucHVwcGV0ZWVyLmFyZ3MudmFsdWUuam9pbignLCcpLFxuICAgICAgc2VwYXJhdG9yOiAnLCdcbiAgICB9XG4gIF0sXG4gIGhpZ2hjaGFydHM6IFtcbiAgICB7XG4gICAgICB0eXBlOiAndGV4dCcsXG4gICAgICBuYW1lOiAndmVyc2lvbicsXG4gICAgICBtZXNzYWdlOiAnSGlnaGNoYXJ0cyB2ZXJzaW9uJyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcuaGlnaGNoYXJ0cy52ZXJzaW9uLnZhbHVlXG4gICAgfSxcbiAgICB7XG4gICAgICB0eXBlOiAndGV4dCcsXG4gICAgICBuYW1lOiAnY2RuVVJMJyxcbiAgICAgIG1lc3NhZ2U6ICdUaGUgVVJMIG9mIENETicsXG4gICAgICBpbml0aWFsOiBkZWZhdWx0Q29uZmlnLmhpZ2hjaGFydHMuY2RuVVJMLnZhbHVlXG4gICAgfSxcbiAgICB7XG4gICAgICB0eXBlOiAnbXVsdGlzZWxlY3QnLFxuICAgICAgbmFtZTogJ2NvcmVTY3JpcHRzJyxcbiAgICAgIG1lc3NhZ2U6ICdBdmFpbGFibGUgY29yZSBzY3JpcHRzJyxcbiAgICAgIGluc3RydWN0aW9uczogJ1NwYWNlOiBTZWxlY3Qgc3BlY2lmaWMsIEE6IFNlbGVjdCBhbGwsIEVudGVyOiBDb25maXJtLicsXG4gICAgICBjaG9pY2VzOiBkZWZhdWx0Q29uZmlnLmhpZ2hjaGFydHMuY29yZVNjcmlwdHMudmFsdWVcbiAgICB9LFxuICAgIHtcbiAgICAgIHR5cGU6ICdtdWx0aXNlbGVjdCcsXG4gICAgICBuYW1lOiAnbW9kdWxlU2NyaXB0cycsXG4gICAgICBtZXNzYWdlOiAnQXZhaWxhYmxlIG1vZHVsZSBzY3JpcHRzJyxcbiAgICAgIGluc3RydWN0aW9uczogJ1NwYWNlOiBTZWxlY3Qgc3BlY2lmaWMsIEE6IFNlbGVjdCBhbGwsIEVudGVyOiBDb25maXJtLicsXG4gICAgICBjaG9pY2VzOiBkZWZhdWx0Q29uZmlnLmhpZ2hjaGFydHMubW9kdWxlU2NyaXB0cy52YWx1ZVxuICAgIH0sXG4gICAge1xuICAgICAgdHlwZTogJ211bHRpc2VsZWN0JyxcbiAgICAgIG5hbWU6ICdpbmRpY2F0b3JTY3JpcHRzJyxcbiAgICAgIG1lc3NhZ2U6ICdBdmFpbGFibGUgaW5kaWNhdG9yIHNjcmlwdHMnLFxuICAgICAgaW5zdHJ1Y3Rpb25zOiAnU3BhY2U6IFNlbGVjdCBzcGVjaWZpYywgQTogU2VsZWN0IGFsbCwgRW50ZXI6IENvbmZpcm0uJyxcbiAgICAgIGNob2ljZXM6IGRlZmF1bHRDb25maWcuaGlnaGNoYXJ0cy5pbmRpY2F0b3JTY3JpcHRzLnZhbHVlXG4gICAgfSxcbiAgICB7XG4gICAgICB0eXBlOiAnbGlzdCcsXG4gICAgICBuYW1lOiAnY3VzdG9tU2NyaXB0cycsXG4gICAgICBtZXNzYWdlOiAnQ3VzdG9tIHNjcmlwdHMnLFxuICAgICAgaW5pdGlhbDogZGVmYXVsdENvbmZpZy5oaWdoY2hhcnRzLmN1c3RvbVNjcmlwdHMudmFsdWUuam9pbignLCcpLFxuICAgICAgc2VwYXJhdG9yOiAnLCdcbiAgICB9LFxuICAgIHtcbiAgICAgIHR5cGU6ICd0b2dnbGUnLFxuICAgICAgbmFtZTogJ2ZvcmNlRmV0Y2gnLFxuICAgICAgbWVzc2FnZTogJ0ZvcmNlIHJlLWZldGNoIHRoZSBzY3JpcHRzJyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcuaGlnaGNoYXJ0cy5mb3JjZUZldGNoLnZhbHVlXG4gICAgfSxcbiAgICB7XG4gICAgICB0eXBlOiAndGV4dCcsXG4gICAgICBuYW1lOiAnY2FjaGVQYXRoJyxcbiAgICAgIG1lc3NhZ2U6ICdUaGUgcGF0aCB0byB0aGUgY2FjaGUgZGlyZWN0b3J5JyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcuaGlnaGNoYXJ0cy5jYWNoZVBhdGgudmFsdWVcbiAgICB9XG4gIF0sXG4gIGV4cG9ydDogW1xuICAgIHtcbiAgICAgIHR5cGU6ICdzZWxlY3QnLFxuICAgICAgbmFtZTogJ3R5cGUnLFxuICAgICAgbWVzc2FnZTogJ1RoZSBkZWZhdWx0IGV4cG9ydCBmaWxlIHR5cGUnLFxuICAgICAgaGludDogYERlZmF1bHQ6ICR7ZGVmYXVsdENvbmZpZy5leHBvcnQudHlwZS52YWx1ZX1gLFxuICAgICAgaW5pdGlhbDogMCxcbiAgICAgIGNob2ljZXM6IFsncG5nJywgJ2pwZWcnLCAncGRmJywgJ3N2ZyddXG4gICAgfSxcbiAgICB7XG4gICAgICB0eXBlOiAnc2VsZWN0JyxcbiAgICAgIG5hbWU6ICdjb25zdHInLFxuICAgICAgbWVzc2FnZTogJ1RoZSBkZWZhdWx0IGNvbnN0cnVjdG9yIGZvciBIaWdoY2hhcnRzJyxcbiAgICAgIGhpbnQ6IGBEZWZhdWx0OiAke2RlZmF1bHRDb25maWcuZXhwb3J0LmNvbnN0ci52YWx1ZX1gLFxuICAgICAgaW5pdGlhbDogMCxcbiAgICAgIGNob2ljZXM6IFsnY2hhcnQnLCAnc3RvY2tDaGFydCcsICdtYXBDaGFydCcsICdnYW50dENoYXJ0J11cbiAgICB9LFxuICAgIHtcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgbmFtZTogJ2RlZmF1bHRIZWlnaHQnLFxuICAgICAgbWVzc2FnZTogJ1RoZSBkZWZhdWx0IGZhbGxiYWNrIGhlaWdodCBvZiB0aGUgZXhwb3J0ZWQgY2hhcnQnLFxuICAgICAgaW5pdGlhbDogZGVmYXVsdENvbmZpZy5leHBvcnQuZGVmYXVsdEhlaWdodC52YWx1ZVxuICAgIH0sXG4gICAge1xuICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICBuYW1lOiAnZGVmYXVsdFdpZHRoJyxcbiAgICAgIG1lc3NhZ2U6ICdUaGUgZGVmYXVsdCBmYWxsYmFjayB3aWR0aCBvZiB0aGUgZXhwb3J0ZWQgY2hhcnQnLFxuICAgICAgaW5pdGlhbDogZGVmYXVsdENvbmZpZy5leHBvcnQuZGVmYXVsdFdpZHRoLnZhbHVlXG4gICAgfSxcbiAgICB7XG4gICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICAgIG5hbWU6ICdkZWZhdWx0U2NhbGUnLFxuICAgICAgbWVzc2FnZTogJ1RoZSBkZWZhdWx0IGZhbGxiYWNrIHNjYWxlIG9mIHRoZSBleHBvcnRlZCBjaGFydCcsXG4gICAgICBpbml0aWFsOiBkZWZhdWx0Q29uZmlnLmV4cG9ydC5kZWZhdWx0U2NhbGUudmFsdWUsXG4gICAgICBtaW46IDAuMSxcbiAgICAgIG1heDogNVxuICAgIH0sXG4gICAge1xuICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICBuYW1lOiAncmFzdGVyaXphdGlvblRpbWVvdXQnLFxuICAgICAgbWVzc2FnZTogJ1RoZSByZW5kZXJpbmcgd2VicGFnZSB0aW1lb3V0IGluIG1pbGxpc2Vjb25kcycsXG4gICAgICBpbml0aWFsOiBkZWZhdWx0Q29uZmlnLmV4cG9ydC5yYXN0ZXJpemF0aW9uVGltZW91dC52YWx1ZVxuICAgIH1cbiAgXSxcbiAgY3VzdG9tTG9naWM6IFtcbiAgICB7XG4gICAgICB0eXBlOiAndG9nZ2xlJyxcbiAgICAgIG5hbWU6ICdhbGxvd0NvZGVFeGVjdXRpb24nLFxuICAgICAgbWVzc2FnZTogJ0VuYWJsZSBleGVjdXRpb24gb2YgY3VzdG9tIGNvZGUnLFxuICAgICAgaW5pdGlhbDogZGVmYXVsdENvbmZpZy5jdXN0b21Mb2dpYy5hbGxvd0NvZGVFeGVjdXRpb24udmFsdWVcbiAgICB9LFxuICAgIHtcbiAgICAgIHR5cGU6ICd0b2dnbGUnLFxuICAgICAgbmFtZTogJ2FsbG93RmlsZVJlc291cmNlcycsXG4gICAgICBtZXNzYWdlOiAnRW5hYmxlIGZpbGUgcmVzb3VyY2VzJyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcuY3VzdG9tTG9naWMuYWxsb3dGaWxlUmVzb3VyY2VzLnZhbHVlXG4gICAgfVxuICBdLFxuICBzZXJ2ZXI6IFtcbiAgICB7XG4gICAgICB0eXBlOiAndG9nZ2xlJyxcbiAgICAgIG5hbWU6ICdlbmFibGUnLFxuICAgICAgbWVzc2FnZTogJ1N0YXJ0cyB0aGUgc2VydmVyIG9uIDAuMC4wLjAnLFxuICAgICAgaW5pdGlhbDogZGVmYXVsdENvbmZpZy5zZXJ2ZXIuZW5hYmxlLnZhbHVlXG4gICAgfSxcbiAgICB7XG4gICAgICB0eXBlOiAndGV4dCcsXG4gICAgICBuYW1lOiAnaG9zdCcsXG4gICAgICBtZXNzYWdlOiAnU2VydmVyIGhvc3RuYW1lJyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcuc2VydmVyLmhvc3QudmFsdWVcbiAgICB9LFxuICAgIHtcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgbmFtZTogJ3BvcnQnLFxuICAgICAgbWVzc2FnZTogJ1NlcnZlciBwb3J0JyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcuc2VydmVyLnBvcnQudmFsdWVcbiAgICB9LFxuICAgIHtcbiAgICAgIHR5cGU6ICd0b2dnbGUnLFxuICAgICAgbmFtZTogJ2JlbmNobWFya2luZycsXG4gICAgICBtZXNzYWdlOiAnRW5hYmxlIHNlcnZlciBiZW5jaG1hcmtpbmcnLFxuICAgICAgaW5pdGlhbDogZGVmYXVsdENvbmZpZy5zZXJ2ZXIuYmVuY2htYXJraW5nLnZhbHVlXG4gICAgfSxcbiAgICB7XG4gICAgICB0eXBlOiAndGV4dCcsXG4gICAgICBuYW1lOiAncHJveHkuaG9zdCcsXG4gICAgICBtZXNzYWdlOiAnVGhlIGhvc3Qgb2YgdGhlIHByb3h5IHNlcnZlciB0byB1c2UnLFxuICAgICAgaW5pdGlhbDogZGVmYXVsdENvbmZpZy5zZXJ2ZXIucHJveHkuaG9zdC52YWx1ZVxuICAgIH0sXG4gICAge1xuICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICBuYW1lOiAncHJveHkucG9ydCcsXG4gICAgICBtZXNzYWdlOiAnVGhlIHBvcnQgb2YgdGhlIHByb3h5IHNlcnZlciB0byB1c2UnLFxuICAgICAgaW5pdGlhbDogZGVmYXVsdENvbmZpZy5zZXJ2ZXIucHJveHkucG9ydC52YWx1ZVxuICAgIH0sXG4gICAge1xuICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICBuYW1lOiAncHJveHkudGltZW91dCcsXG4gICAgICBtZXNzYWdlOiAnVGhlIHRpbWVvdXQgZm9yIHRoZSBwcm94eSBzZXJ2ZXIgdG8gdXNlJyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcuc2VydmVyLnByb3h5LnRpbWVvdXQudmFsdWVcbiAgICB9LFxuICAgIHtcbiAgICAgIHR5cGU6ICd0b2dnbGUnLFxuICAgICAgbmFtZTogJ3JhdGVMaW1pdGluZy5lbmFibGUnLFxuICAgICAgbWVzc2FnZTogJ0VuYWJsZSByYXRlIGxpbWl0aW5nJyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcuc2VydmVyLnJhdGVMaW1pdGluZy5lbmFibGUudmFsdWVcbiAgICB9LFxuICAgIHtcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgbmFtZTogJ3JhdGVMaW1pdGluZy5tYXhSZXF1ZXN0cycsXG4gICAgICBtZXNzYWdlOiAnVGhlIG1heGltdW0gcmVxdWVzdHMgYWxsb3dlZCBwZXIgbWludXRlJyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcuc2VydmVyLnJhdGVMaW1pdGluZy5tYXhSZXF1ZXN0cy52YWx1ZVxuICAgIH0sXG4gICAge1xuICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICBuYW1lOiAncmF0ZUxpbWl0aW5nLndpbmRvdycsXG4gICAgICBtZXNzYWdlOiAnVGhlIHJhdGUtbGltaXRpbmcgdGltZSB3aW5kb3cgaW4gbWludXRlcycsXG4gICAgICBpbml0aWFsOiBkZWZhdWx0Q29uZmlnLnNlcnZlci5yYXRlTGltaXRpbmcud2luZG93LnZhbHVlXG4gICAgfSxcbiAgICB7XG4gICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICAgIG5hbWU6ICdyYXRlTGltaXRpbmcuZGVsYXknLFxuICAgICAgbWVzc2FnZTpcbiAgICAgICAgJ1RoZSBkZWxheSBmb3IgZWFjaCBzdWNjZXNzaXZlIHJlcXVlc3QgYmVmb3JlIHJlYWNoaW5nIHRoZSBtYXhpbXVtJyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcuc2VydmVyLnJhdGVMaW1pdGluZy5kZWxheS52YWx1ZVxuICAgIH0sXG4gICAge1xuICAgICAgdHlwZTogJ3RvZ2dsZScsXG4gICAgICBuYW1lOiAncmF0ZUxpbWl0aW5nLnRydXN0UHJveHknLFxuICAgICAgbWVzc2FnZTogJ1NldCB0byB0cnVlIGlmIGJlaGluZCBhIGxvYWQgYmFsYW5jZXInLFxuICAgICAgaW5pdGlhbDogZGVmYXVsdENvbmZpZy5zZXJ2ZXIucmF0ZUxpbWl0aW5nLnRydXN0UHJveHkudmFsdWVcbiAgICB9LFxuICAgIHtcbiAgICAgIHR5cGU6ICd0ZXh0JyxcbiAgICAgIG5hbWU6ICdyYXRlTGltaXRpbmcuc2tpcEtleScsXG4gICAgICBtZXNzYWdlOlxuICAgICAgICAnQWxsb3dzIGJ5cGFzc2luZyB0aGUgcmF0ZSBsaW1pdGVyIHdoZW4gcHJvdmlkZWQgd2l0aCB0aGUgc2tpcFRva2VuIGFyZ3VtZW50JyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcuc2VydmVyLnJhdGVMaW1pdGluZy5za2lwS2V5LnZhbHVlXG4gICAgfSxcbiAgICB7XG4gICAgICB0eXBlOiAndGV4dCcsXG4gICAgICBuYW1lOiAncmF0ZUxpbWl0aW5nLnNraXBUb2tlbicsXG4gICAgICBtZXNzYWdlOlxuICAgICAgICAnQWxsb3dzIGJ5cGFzc2luZyB0aGUgcmF0ZSBsaW1pdGVyIHdoZW4gcHJvdmlkZWQgd2l0aCB0aGUgc2tpcEtleSBhcmd1bWVudCcsXG4gICAgICBpbml0aWFsOiBkZWZhdWx0Q29uZmlnLnNlcnZlci5yYXRlTGltaXRpbmcuc2tpcFRva2VuLnZhbHVlXG4gICAgfSxcbiAgICB7XG4gICAgICB0eXBlOiAndG9nZ2xlJyxcbiAgICAgIG5hbWU6ICdzc2wuZW5hYmxlJyxcbiAgICAgIG1lc3NhZ2U6ICdFbmFibGUgU1NMIHByb3RvY29sJyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcuc2VydmVyLnNzbC5lbmFibGUudmFsdWVcbiAgICB9LFxuICAgIHtcbiAgICAgIHR5cGU6ICd0b2dnbGUnLFxuICAgICAgbmFtZTogJ3NzbC5mb3JjZScsXG4gICAgICBtZXNzYWdlOiAnRm9yY2Ugc2VydmluZyBvbmx5IG92ZXIgSFRUUFMnLFxuICAgICAgaW5pdGlhbDogZGVmYXVsdENvbmZpZy5zZXJ2ZXIuc3NsLmZvcmNlLnZhbHVlXG4gICAgfSxcbiAgICB7XG4gICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICAgIG5hbWU6ICdzc2wucG9ydCcsXG4gICAgICBtZXNzYWdlOiAnU1NMIHNlcnZlciBwb3J0JyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcuc2VydmVyLnNzbC5wb3J0LnZhbHVlXG4gICAgfSxcbiAgICB7XG4gICAgICB0eXBlOiAndGV4dCcsXG4gICAgICBuYW1lOiAnc3NsLmNlcnRQYXRoJyxcbiAgICAgIG1lc3NhZ2U6ICdUaGUgcGF0aCB0byBmaW5kIHRoZSBTU0wgY2VydGlmaWNhdGUva2V5JyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcuc2VydmVyLnNzbC5jZXJ0UGF0aC52YWx1ZVxuICAgIH1cbiAgXSxcbiAgcG9vbDogW1xuICAgIHtcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgbmFtZTogJ21pbldvcmtlcnMnLFxuICAgICAgbWVzc2FnZTogJ1RoZSBpbml0aWFsIG51bWJlciBvZiB3b3JrZXJzIHRvIHNwYXduJyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcucG9vbC5taW5Xb3JrZXJzLnZhbHVlXG4gICAgfSxcbiAgICB7XG4gICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICAgIG5hbWU6ICdtYXhXb3JrZXJzJyxcbiAgICAgIG1lc3NhZ2U6ICdUaGUgbWF4aW11bSBudW1iZXIgb2Ygd29ya2VycyB0byBzcGF3bicsXG4gICAgICBpbml0aWFsOiBkZWZhdWx0Q29uZmlnLnBvb2wubWF4V29ya2Vycy52YWx1ZVxuICAgIH0sXG4gICAge1xuICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICBuYW1lOiAnd29ya0xpbWl0JyxcbiAgICAgIG1lc3NhZ2U6XG4gICAgICAgICdUaGUgcGllY2VzIG9mIHdvcmsgdGhhdCBjYW4gYmUgcGVyZm9ybWVkIGJlZm9yZSByZXN0YXJ0aW5nIGEgUHVwcGV0ZWVyIHByb2Nlc3MnLFxuICAgICAgaW5pdGlhbDogZGVmYXVsdENvbmZpZy5wb29sLndvcmtMaW1pdC52YWx1ZVxuICAgIH0sXG4gICAge1xuICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICBuYW1lOiAnYWNxdWlyZVRpbWVvdXQnLFxuICAgICAgbWVzc2FnZTogJ1RoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIHRvIHdhaXQgZm9yIGFjcXVpcmluZyBhIHJlc291cmNlJyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcucG9vbC5hY3F1aXJlVGltZW91dC52YWx1ZVxuICAgIH0sXG4gICAge1xuICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICBuYW1lOiAnY3JlYXRlVGltZW91dCcsXG4gICAgICBtZXNzYWdlOiAnVGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgdG8gd2FpdCBmb3IgY3JlYXRpbmcgYSByZXNvdXJjZScsXG4gICAgICBpbml0aWFsOiBkZWZhdWx0Q29uZmlnLnBvb2wuY3JlYXRlVGltZW91dC52YWx1ZVxuICAgIH0sXG4gICAge1xuICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICBuYW1lOiAnZGVzdHJveVRpbWVvdXQnLFxuICAgICAgbWVzc2FnZTogJ1RoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIHRvIHdhaXQgZm9yIGRlc3Ryb3lpbmcgYSByZXNvdXJjZScsXG4gICAgICBpbml0aWFsOiBkZWZhdWx0Q29uZmlnLnBvb2wuZGVzdHJveVRpbWVvdXQudmFsdWVcbiAgICB9LFxuICAgIHtcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgbmFtZTogJ2lkbGVUaW1lb3V0JyxcbiAgICAgIG1lc3NhZ2U6ICdUaGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBhZnRlciBhbiBpZGxlIHJlc291cmNlIGlzIGRlc3Ryb3llZCcsXG4gICAgICBpbml0aWFsOiBkZWZhdWx0Q29uZmlnLnBvb2wuaWRsZVRpbWVvdXQudmFsdWVcbiAgICB9LFxuICAgIHtcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgbmFtZTogJ2NyZWF0ZVJldHJ5SW50ZXJ2YWwnLFxuICAgICAgbWVzc2FnZTpcbiAgICAgICAgJ1RoZSByZXRyeSBpbnRlcnZhbCBpbiBtaWxsaXNlY29uZHMgYWZ0ZXIgYSBjcmVhdGUgcHJvY2VzcyBmYWlscycsXG4gICAgICBpbml0aWFsOiBkZWZhdWx0Q29uZmlnLnBvb2wuY3JlYXRlUmV0cnlJbnRlcnZhbC52YWx1ZVxuICAgIH0sXG4gICAge1xuICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICBuYW1lOiAncmVhcGVySW50ZXJ2YWwnLFxuICAgICAgbWVzc2FnZTpcbiAgICAgICAgJ1RoZSByZWFwZXIgaW50ZXJ2YWwgaW4gbWlsbGlzZWNvbmRzIGFmdGVyIHRyaWdnZXJpbmcgdGhlIGNoZWNrIGZvciBpZGxlIHJlc291cmNlcyB0byBkZXN0cm95JyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcucG9vbC5yZWFwZXJJbnRlcnZhbC52YWx1ZVxuICAgIH0sXG4gICAge1xuICAgICAgdHlwZTogJ3RvZ2dsZScsXG4gICAgICBuYW1lOiAnYmVuY2htYXJraW5nJyxcbiAgICAgIG1lc3NhZ2U6ICdFbmFibGUgYmVuY2htYXJraW5nIGZvciBhIHJlc291cmNlIHBvb2wnLFxuICAgICAgaW5pdGlhbDogZGVmYXVsdENvbmZpZy5wb29sLmJlbmNobWFya2luZy52YWx1ZVxuICAgIH1cbiAgXSxcbiAgbG9nZ2luZzogW1xuICAgIHtcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgbmFtZTogJ2xldmVsJyxcbiAgICAgIG1lc3NhZ2U6XG4gICAgICAgICdUaGUgbG9nIGxldmVsICgwOiBzaWxlbnQsIDE6IGVycm9yLCAyOiB3YXJuaW5nLCAzOiBub3RpY2UsIDQ6IHZlcmJvc2UsIDU6IGJlbmNobWFyayknLFxuICAgICAgaW5pdGlhbDogZGVmYXVsdENvbmZpZy5sb2dnaW5nLmxldmVsLnZhbHVlLFxuICAgICAgcm91bmQ6IDAsXG4gICAgICBtaW46IDAsXG4gICAgICBtYXg6IDVcbiAgICB9LFxuICAgIHtcbiAgICAgIHR5cGU6ICd0ZXh0JyxcbiAgICAgIG5hbWU6ICdmaWxlJyxcbiAgICAgIG1lc3NhZ2U6XG4gICAgICAgICdBIGxvZyBmaWxlIG5hbWUuIFNldCB3aXRoIC0tdG9GaWxlIGFuZCAtLWxvZ0Rlc3QgdG8gZW5hYmxlIGZpbGUgbG9nZ2luZycsXG4gICAgICBpbml0aWFsOiBkZWZhdWx0Q29uZmlnLmxvZ2dpbmcuZmlsZS52YWx1ZVxuICAgIH0sXG4gICAge1xuICAgICAgdHlwZTogJ3RleHQnLFxuICAgICAgbmFtZTogJ2Rlc3QnLFxuICAgICAgbWVzc2FnZTogJ1RoZSBwYXRoIHRvIGEgbG9nIGZpbGUgd2hlbiB0aGUgZmlsZSBsb2dnaW5nIGlzIGVuYWJsZWQnLFxuICAgICAgaW5pdGlhbDogZGVmYXVsdENvbmZpZy5sb2dnaW5nLmRlc3QudmFsdWVcbiAgICB9LFxuICAgIHtcbiAgICAgIHR5cGU6ICd0b2dnbGUnLFxuICAgICAgbmFtZTogJ3RvQ29uc29sZScsXG4gICAgICBtZXNzYWdlOiAnRW5hYmxlIGxvZ2dpbmcgdG8gdGhlIGNvbnNvbGUnLFxuICAgICAgaW5pdGlhbDogZGVmYXVsdENvbmZpZy5sb2dnaW5nLnRvQ29uc29sZS52YWx1ZVxuICAgIH0sXG4gICAge1xuICAgICAgdHlwZTogJ3RvZ2dsZScsXG4gICAgICBuYW1lOiAndG9GaWxlJyxcbiAgICAgIG1lc3NhZ2U6ICdFbmFibGVzIGxvZ2dpbmcgdG8gYSBmaWxlJyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcubG9nZ2luZy50b0ZpbGUudmFsdWVcbiAgICB9XG4gIF0sXG4gIHVpOiBbXG4gICAge1xuICAgICAgdHlwZTogJ3RvZ2dsZScsXG4gICAgICBuYW1lOiAnZW5hYmxlJyxcbiAgICAgIG1lc3NhZ2U6ICdFbmFibGUgVUkgZm9yIHRoZSBleHBvcnQgc2VydmVyJyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcudWkuZW5hYmxlLnZhbHVlXG4gICAgfSxcbiAgICB7XG4gICAgICB0eXBlOiAndGV4dCcsXG4gICAgICBuYW1lOiAncm91dGUnLFxuICAgICAgbWVzc2FnZTogJ0Egcm91dGUgdG8gYXR0YWNoIHRoZSBVSScsXG4gICAgICBpbml0aWFsOiBkZWZhdWx0Q29uZmlnLnVpLnJvdXRlLnZhbHVlXG4gICAgfVxuICBdLFxuICBvdGhlcjogW1xuICAgIHtcbiAgICAgIHR5cGU6ICd0ZXh0JyxcbiAgICAgIG5hbWU6ICdub2RlRW52JyxcbiAgICAgIG1lc3NhZ2U6ICdUaGUgdHlwZSBvZiBOb2RlLmpzIGVudmlyb25tZW50JyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcub3RoZXIubm9kZUVudi52YWx1ZVxuICAgIH0sXG4gICAge1xuICAgICAgdHlwZTogJ3RvZ2dsZScsXG4gICAgICBuYW1lOiAnbGlzdGVuVG9Qcm9jZXNzRXhpdHMnLFxuICAgICAgbWVzc2FnZTogJ1NldCB0byBmYWxzZSB0byBza2lwIGF0dGFjaGluZyBwcm9jZXNzLmV4aXQgaGFuZGxlcnMnLFxuICAgICAgaW5pdGlhbDogZGVmYXVsdENvbmZpZy5vdGhlci5saXN0ZW5Ub1Byb2Nlc3NFeGl0cy52YWx1ZVxuICAgIH0sXG4gICAge1xuICAgICAgdHlwZTogJ3RvZ2dsZScsXG4gICAgICBuYW1lOiAnbm9Mb2dvJyxcbiAgICAgIG1lc3NhZ2U6ICdTa2lwIHByaW50aW5nIHRoZSBsb2dvIG9uIHN0YXJ0dXAuIFJlcGxhY2VkIGJ5IHNpbXBsZSB0ZXh0JyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcub3RoZXIubm9Mb2dvLnZhbHVlXG4gICAgfSxcbiAgICB7XG4gICAgICB0eXBlOiAndG9nZ2xlJyxcbiAgICAgIG5hbWU6ICdoYXJkUmVzZXRQYWdlJyxcbiAgICAgIG1lc3NhZ2U6ICdEZWNpZGVzIGlmIHRoZSBwYWdlIGNvbnRlbnQgc2hvdWxkIGJlIHJlc2V0IGVudGlyZWx5JyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcub3RoZXIuaGFyZFJlc2V0UGFnZS52YWx1ZVxuICAgIH0sXG4gICAge1xuICAgICAgdHlwZTogJ3RvZ2dsZScsXG4gICAgICBuYW1lOiAnYnJvd3NlclNoZWxsTW9kZScsXG4gICAgICBtZXNzYWdlOiAnRGVjaWRlcyBpZiB0aGUgYnJvd3NlciBydW5zIGluIHRoZSBzaGVsbCBtb2RlJyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcub3RoZXIuYnJvd3NlclNoZWxsTW9kZS52YWx1ZVxuICAgIH1cbiAgXSxcbiAgZGVidWc6IFtcbiAgICB7XG4gICAgICB0eXBlOiAndG9nZ2xlJyxcbiAgICAgIG5hbWU6ICdlbmFibGUnLFxuICAgICAgbWVzc2FnZTogJ0VuYWJsZXMgZGVidWcgbW9kZSBmb3IgdGhlIGJyb3dzZXIgaW5zdGFuY2UnLFxuICAgICAgaW5pdGlhbDogZGVmYXVsdENvbmZpZy5kZWJ1Zy5lbmFibGUudmFsdWVcbiAgICB9LFxuICAgIHtcbiAgICAgIHR5cGU6ICd0b2dnbGUnLFxuICAgICAgbmFtZTogJ2hlYWRsZXNzJyxcbiAgICAgIG1lc3NhZ2U6ICdUaGUgbW9kZSBzZXR0aW5nIGZvciB0aGUgYnJvd3NlcicsXG4gICAgICBpbml0aWFsOiBkZWZhdWx0Q29uZmlnLmRlYnVnLmhlYWRsZXNzLnZhbHVlXG4gICAgfSxcbiAgICB7XG4gICAgICB0eXBlOiAndG9nZ2xlJyxcbiAgICAgIG5hbWU6ICdkZXZ0b29scycsXG4gICAgICBtZXNzYWdlOiAnVGhlIERldlRvb2xzIGZvciB0aGUgaGVhZGZ1bCBicm93c2VyJyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcuZGVidWcuZGV2dG9vbHMudmFsdWVcbiAgICB9LFxuICAgIHtcbiAgICAgIHR5cGU6ICd0b2dnbGUnLFxuICAgICAgbmFtZTogJ2xpc3RlblRvQ29uc29sZScsXG4gICAgICBtZXNzYWdlOiAnVGhlIGV2ZW50IGxpc3RlbmVyIGZvciBjb25zb2xlIG1lc3NhZ2VzIGZyb20gdGhlIGJyb3dzZXInLFxuICAgICAgaW5pdGlhbDogZGVmYXVsdENvbmZpZy5kZWJ1Zy5saXN0ZW5Ub0NvbnNvbGUudmFsdWVcbiAgICB9LFxuICAgIHtcbiAgICAgIHR5cGU6ICd0b2dnbGUnLFxuICAgICAgbmFtZTogJ2R1bXBpbycsXG4gICAgICBtZXNzYWdlOiAnUmVkaXJlY3RzIHRoZSBicm93c2VyIHN0ZG91dCBhbmQgc3RkZXJyIHRvIE5vZGVKUyBwcm9jZXNzJyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcuZGVidWcuZHVtcGlvLnZhbHVlXG4gICAgfSxcbiAgICB7XG4gICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICAgIG5hbWU6ICdzbG93TW8nLFxuICAgICAgbWVzc2FnZTogJ1B1cHBldGVlciBvcGVyYXRpb25zIHNsb3cgZG93biBpbiBtaWxsaXNlY29uZHMnLFxuICAgICAgaW5pdGlhbDogZGVmYXVsdENvbmZpZy5kZWJ1Zy5zbG93TW8udmFsdWVcbiAgICB9LFxuICAgIHtcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgbmFtZTogJ2RlYnVnZ2luZ1BvcnQnLFxuICAgICAgbWVzc2FnZTogJ1RoZSBwb3J0IG51bWJlciBmb3IgZGVidWdnaW5nJyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcuZGVidWcuZGVidWdnaW5nUG9ydC52YWx1ZVxuICAgIH1cbiAgXVxufTtcblxuLy8gQWJzb2x1dGUgcHJvcHMgdGhhdCwgaW4gY2FzZSBvZiBtZXJnaW5nIHJlY3Vyc2l2ZWx5LCBuZWVkIHRvIGJlIGZvcmNlIG1lcmdlZFxuZXhwb3J0IGNvbnN0IGFic29sdXRlUHJvcHMgPSBbXG4gICdvcHRpb25zJyxcbiAgJ2dsb2JhbE9wdGlvbnMnLFxuICAndGhlbWVPcHRpb25zJyxcbiAgJ3Jlc291cmNlcycsXG4gICdwYXlsb2FkJ1xuXTtcblxuLy8gQXJndW1lbnQgbmVzdGluZyBsZXZlbCBvZiBhbGwgZXhwb3J0IHNlcnZlciBvcHRpb25zXG5leHBvcnQgY29uc3QgbmVzdGVkQXJncyA9IHt9O1xuXG4vKipcbiAqIFJlY3Vyc2l2ZWx5IGNyZWF0ZXMgYSBjaGFpbiBvZiBuZXN0ZWQgYXJndW1lbnRzIGZyb20gYW4gb2JqZWN0LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmogLSBUaGUgb2JqZWN0IGNvbnRhaW5pbmcgbmVzdGVkIGFyZ3VtZW50cy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wQ2hhaW4gLSBUaGUgY3VycmVudCBjaGFpbiBvZiBuZXN0ZWQgcHJvcGVydGllc1xuICogKHVzZWQgaW50ZXJuYWxseSBkdXJpbmcgcmVjdXJzaW9uKS5cbiAqL1xuY29uc3QgY3JlYXRlTmVzdGVkQXJncyA9IChvYmosIHByb3BDaGFpbiA9ICcnKSA9PiB7XG4gIE9iamVjdC5rZXlzKG9iaikuZm9yRWFjaCgoaykgPT4ge1xuICAgIGlmICghWydwdXBwZXRlZXInLCAnaGlnaGNoYXJ0cyddLmluY2x1ZGVzKGspKSB7XG4gICAgICBjb25zdCBlbnRyeSA9IG9ialtrXTtcbiAgICAgIGlmICh0eXBlb2YgZW50cnkudmFsdWUgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIC8vIEdvIGRlZXBlciBpbiB0aGUgbmVzdGVkIGFyZ3VtZW50c1xuICAgICAgICBjcmVhdGVOZXN0ZWRBcmdzKGVudHJ5LCBgJHtwcm9wQ2hhaW59LiR7a31gKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIENyZWF0ZSB0aGUgY2hhaW4gb2YgbmVzdGVkIGFyZ3VtZW50c1xuICAgICAgICBuZXN0ZWRBcmdzW2VudHJ5LmNsaU5hbWUgfHwga10gPSBgJHtwcm9wQ2hhaW59LiR7a31gLnN1YnN0cmluZygxKTtcblxuICAgICAgICAvLyBTdXBwb3J0IGZvciB0aGUgbGVnYWN5LCBQaGFudG9tSlMgcHJvcGVydGllcyBuYW1lc1xuICAgICAgICBpZiAoZW50cnkubGVnYWN5TmFtZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgbmVzdGVkQXJnc1tlbnRyeS5sZWdhY3lOYW1lXSA9IGAke3Byb3BDaGFpbn0uJHtrfWAuc3Vic3RyaW5nKDEpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9KTtcbn07XG5cbmNyZWF0ZU5lc3RlZEFyZ3MoZGVmYXVsdENvbmZpZyk7XG4iLCIvKipcbiAqIEBmaWxlb3ZlcnZpZXdcbiAqIFRoaXMgZmlsZSBpcyByZXNwb25zaWJsZSBmb3IgcGFyc2luZyB0aGUgZW52aXJvbm1lbnQgdmFyaWFibGVzIHdpdGggdGhlICd6b2QnXG4gKiBsaWJyYXJ5LiBUaGUgcGFyc2VkIGVudmlyb25tZW50IHZhcmlhYmxlcyBhcmUgdGhlbiBleHBvcnRlZCB0byBiZSB1c2VkXG4gKiBpbiB0aGUgYXBwbGljYXRpb24gYXMgXCJlbnZzXCIuIFdlIHNob3VsZCBub3QgdXNlIHByb2Nlc3MuZW52IGRpcmVjdGx5XG4gKiBpbiB0aGUgYXBwbGljYXRpb24gYXMgdGhlc2Ugd291bGQgbm90IGJlIHBhcnNlZCBwcm9wZXJseS5cbiAqXG4gKiBUaGUgZW52aXJvbm1lbnQgdmFyaWFibGVzIGFyZSBwYXJzZWQgYW5kIHZhbGlkYXRlZCBvbmx5IG9uY2Ugd2hlblxuICogdGhlIGFwcGxpY2F0aW9uIHN0YXJ0cy4gV2Ugc2hvdWxkIHdyaXRlIGEgY3VzdG9tIHZhbGlkYXRvciBvciBhIHRyYW5zZm9ybWVyXG4gKiBmb3IgZWFjaCBvZiB0aGUgb3B0aW9ucy5cbiAqL1xuXG5pbXBvcnQgZG90ZW52IGZyb20gJ2RvdGVudic7XG5pbXBvcnQgeyB6IH0gZnJvbSAnem9kJztcblxuaW1wb3J0IHsgc2NyaXB0c05hbWVzIH0gZnJvbSAnLi9zY2hlbWFzL2NvbmZpZy5qcyc7XG5cbi8vIExvYWQgLmVudiBpbnRvIGVudmlyb25tZW50IHZhcmlhYmxlc1xuZG90ZW52LmNvbmZpZygpO1xuXG4vLyBPYmplY3Qgd2l0aCBjdXN0b20gdmFsaWRhdG9ycyBhbmQgdHJhbnNmb3JtZXJzLCB0byBhdm9pZCByZXBldGl0aW9uXG4vLyBpbiB0aGUgQ29uZmlnIG9iamVjdFxuY29uc3QgdiA9IHtcbiAgLy8gU3BsaXRzIHN0cmluZyB2YWx1ZSBpbnRvIGVsZW1lbnRzIGluIGFuIGFycmF5LCB0cmltcyBldmVyeSBlbGVtZW50LCBjaGVja3NcbiAgLy8gaWYgYW4gYXJyYXkgaXMgY29ycmVjdCwgaWYgaXQgaXMgZW1wdHksIGFuZCBpZiBpdCBpcywgcmV0dXJucyB1bmRlZmluZWRcbiAgYXJyYXk6IChmaWx0ZXJBcnJheSkgPT5cbiAgICB6XG4gICAgICAuc3RyaW5nKClcbiAgICAgIC50cmFuc2Zvcm0oKHZhbHVlKSA9PlxuICAgICAgICB2YWx1ZVxuICAgICAgICAgIC5zcGxpdCgnLCcpXG4gICAgICAgICAgLm1hcCgodmFsdWUpID0+IHZhbHVlLnRyaW0oKSlcbiAgICAgICAgICAuZmlsdGVyKCh2YWx1ZSkgPT4gZmlsdGVyQXJyYXkuaW5jbHVkZXModmFsdWUpKVxuICAgICAgKVxuICAgICAgLnRyYW5zZm9ybSgodmFsdWUpID0+ICh2YWx1ZS5sZW5ndGggPyB2YWx1ZSA6IHVuZGVmaW5lZCkpLFxuXG4gIC8vIEFsbG93cyBvbmx5IHRydWUsIGZhbHNlIGFuZCBjb3JyZWN0bHkgcGFyc2UgdGhlIHZhbHVlIHRvIGJvb2xlYW5cbiAgLy8gb3Igbm8gdmFsdWUgaW4gd2hpY2ggY2FzZSB0aGUgcmV0dXJuZWQgdmFsdWUgd2lsbCBiZSB1bmRlZmluZWRcbiAgYm9vbGVhbjogKCkgPT5cbiAgICB6XG4gICAgICAuZW51bShbJ3RydWUnLCAnZmFsc2UnLCAnJ10pXG4gICAgICAudHJhbnNmb3JtKCh2YWx1ZSkgPT4gKHZhbHVlICE9PSAnJyA/IHZhbHVlID09PSAndHJ1ZScgOiB1bmRlZmluZWQpKSxcblxuICAvLyBBbGxvd3MgcGFzc2VkIHZhbHVlcyBvciBubyB2YWx1ZSBpbiB3aGljaCBjYXNlIHRoZSByZXR1cm5lZCB2YWx1ZSB3aWxsXG4gIC8vIGJlIHVuZGVmaW5lZFxuICBlbnVtOiAodmFsdWVzKSA9PlxuICAgIHpcbiAgICAgIC5lbnVtKFsuLi52YWx1ZXMsICcnXSlcbiAgICAgIC50cmFuc2Zvcm0oKHZhbHVlKSA9PiAodmFsdWUgIT09ICcnID8gdmFsdWUgOiB1bmRlZmluZWQpKSxcblxuICAvLyBUcmltcyB0aGUgc3RyaW5nIHZhbHVlIGFuZCBjaGVja3MgaWYgaXQgaXMgZW1wdHkgb3IgY29udGFpbnMgc3RyaW5naWZpZWRcbiAgLy8gdmFsdWVzIHN1Y2ggYXMgZmFsc2UsIHVuZGVmaW5lZCwgbnVsbCwgTmFOLCBpZiBpdCBkb2VzLCByZXR1cm5zIHVuZGVmaW5lZFxuICBzdHJpbmc6ICgpID0+XG4gICAgelxuICAgICAgLnN0cmluZygpXG4gICAgICAudHJpbSgpXG4gICAgICAucmVmaW5lKFxuICAgICAgICAodmFsdWUpID0+XG4gICAgICAgICAgIVsnZmFsc2UnLCAndW5kZWZpbmVkJywgJ251bGwnLCAnTmFOJ10uaW5jbHVkZXModmFsdWUpIHx8XG4gICAgICAgICAgdmFsdWUgPT09ICcnLFxuICAgICAgICAodmFsdWUpID0+ICh7XG4gICAgICAgICAgbWVzc2FnZTogYFRoZSBzdHJpbmcgY29udGFpbnMgZm9yYmlkZGVuIHZhbHVlcywgcmVjZWl2ZWQgJyR7dmFsdWV9J2BcbiAgICAgICAgfSlcbiAgICAgIClcbiAgICAgIC50cmFuc2Zvcm0oKHZhbHVlKSA9PiAodmFsdWUgIT09ICcnID8gdmFsdWUgOiB1bmRlZmluZWQpKSxcblxuICAvLyBDaGVja3MgaWYgdGhlIHN0cmluZyBpcyBhIHZhbGlkIHBhdGggZGlyZWN0b3J5IChwYXRoIGZvcm1hdClcbiAgcGF0aDogKCkgPT5cbiAgICB6XG4gICAgICAuc3RyaW5nKClcbiAgICAgIC50cmltKClcbiAgICAgIC5yZWZpbmUoXG4gICAgICAgICh2YWx1ZSkgPT4ge1xuICAgICAgICAgIC8vIFNpbXBsaWZpZWQgcmVnZXggdG8gbWF0Y2ggYm90aCBhYnNvbHV0ZSBhbmQgcmVsYXRpdmUgcGF0aHNcbiAgICAgICAgICByZXR1cm4gL14oXFwuXFwvfFxcLlxcLlxcL3xcXC98W2EtekEtWl06XFxcXHxbYS16QS1aXTpcXC8pPygoPzpbXFx3LV0rKVtcXFxcL10/KSskLy50ZXN0KFxuICAgICAgICAgICAgdmFsdWVcbiAgICAgICAgICApO1xuICAgICAgICB9LFxuICAgICAgICB7fSxcbiAgICAgICAge1xuICAgICAgICAgIG1lc3NhZ2U6ICdUaGUgc3RyaW5nIGlzIGFuIGludmFsaWQgcGF0aCBkaXJlY3Rvcnkgc3RyaW5nLidcbiAgICAgICAgfVxuICAgICAgKSxcblxuICAvLyBBbGxvd3MgcG9zaXRpdmUgbnVtYmVycyBvciBubyB2YWx1ZSBpbiB3aGljaCBjYXNlIHRoZSByZXR1cm5lZCB2YWx1ZSB3aWxsXG4gIC8vIGJlIHVuZGVmaW5lZFxuICBwb3NpdGl2ZU51bTogKCkgPT5cbiAgICB6XG4gICAgICAuc3RyaW5nKClcbiAgICAgIC50cmltKClcbiAgICAgIC5yZWZpbmUoXG4gICAgICAgICh2YWx1ZSkgPT5cbiAgICAgICAgICB2YWx1ZSA9PT0gJycgfHwgKCFpc05hTihwYXJzZUZsb2F0KHZhbHVlKSkgJiYgcGFyc2VGbG9hdCh2YWx1ZSkgPiAwKSxcbiAgICAgICAgKHZhbHVlKSA9PiAoe1xuICAgICAgICAgIG1lc3NhZ2U6IGBUaGUgdmFsdWUgbXVzdCBiZSBudW1lcmljIGFuZCBwb3NpdGl2ZSwgcmVjZWl2ZWQgJyR7dmFsdWV9J2BcbiAgICAgICAgfSlcbiAgICAgIClcbiAgICAgIC50cmFuc2Zvcm0oKHZhbHVlKSA9PiAodmFsdWUgIT09ICcnID8gcGFyc2VGbG9hdCh2YWx1ZSkgOiB1bmRlZmluZWQpKSxcblxuICAvLyBBbGxvd3Mgbm9uLW5lZ2F0aXZlIG51bWJlcnMgb3Igbm8gdmFsdWUgaW4gd2hpY2ggY2FzZSB0aGUgcmV0dXJuZWQgdmFsdWVcbiAgLy8gd2lsbCBiZSB1bmRlZmluZWRcbiAgbm9uTmVnYXRpdmVOdW06ICgpID0+XG4gICAgelxuICAgICAgLnN0cmluZygpXG4gICAgICAudHJpbSgpXG4gICAgICAucmVmaW5lKFxuICAgICAgICAodmFsdWUpID0+XG4gICAgICAgICAgdmFsdWUgPT09ICcnIHx8ICghaXNOYU4ocGFyc2VGbG9hdCh2YWx1ZSkpICYmIHBhcnNlRmxvYXQodmFsdWUpID49IDApLFxuICAgICAgICAodmFsdWUpID0+ICh7XG4gICAgICAgICAgbWVzc2FnZTogYFRoZSB2YWx1ZSBtdXN0IGJlIG51bWVyaWMgYW5kIG5vbi1uZWdhdGl2ZSwgcmVjZWl2ZWQgJyR7dmFsdWV9J2BcbiAgICAgICAgfSlcbiAgICAgIClcbiAgICAgIC50cmFuc2Zvcm0oKHZhbHVlKSA9PiAodmFsdWUgIT09ICcnID8gcGFyc2VGbG9hdCh2YWx1ZSkgOiB1bmRlZmluZWQpKVxufTtcblxuZXhwb3J0IGNvbnN0IENvbmZpZyA9IHoub2JqZWN0KHtcbiAgLy8gcHVwcGV0ZWVyXG4gIFBVUFBFVEVFUl9URU1QX0RJUjogdi5wYXRoKCksXG5cbiAgLy8gaGlnaGNoYXJ0c1xuICBISUdIQ0hBUlRTX1ZFUlNJT046IHpcbiAgICAuc3RyaW5nKClcbiAgICAudHJpbSgpXG4gICAgLnJlZmluZShcbiAgICAgICh2YWx1ZSkgPT4gL14obGF0ZXN0fFxcZCsoXFwuXFxkKyl7MCwyfSkkLy50ZXN0KHZhbHVlKSB8fCB2YWx1ZSA9PT0gJycsXG4gICAgICAodmFsdWUpID0+ICh7XG4gICAgICAgIG1lc3NhZ2U6IGBISUdIQ0hBUlRTX1ZFUlNJT04gbXVzdCBiZSAnbGF0ZXN0JywgYSBtYWpvciB2ZXJzaW9uLCBvciBpbiB0aGUgZm9ybSBYWC5ZWS5aWiwgcmVjZWl2ZWQgJyR7dmFsdWV9J2BcbiAgICAgIH0pXG4gICAgKVxuICAgIC50cmFuc2Zvcm0oKHZhbHVlKSA9PiAodmFsdWUgIT09ICcnID8gdmFsdWUgOiB1bmRlZmluZWQpKSxcbiAgSElHSENIQVJUU19DRE5fVVJMOiB6XG4gICAgLnN0cmluZygpXG4gICAgLnRyaW0oKVxuICAgIC5yZWZpbmUoXG4gICAgICAodmFsdWUpID0+XG4gICAgICAgIHZhbHVlLnN0YXJ0c1dpdGgoJ2h0dHBzOi8vJykgfHxcbiAgICAgICAgdmFsdWUuc3RhcnRzV2l0aCgnaHR0cDovLycpIHx8XG4gICAgICAgIHZhbHVlID09PSAnJyxcbiAgICAgICh2YWx1ZSkgPT4gKHtcbiAgICAgICAgbWVzc2FnZTogYEludmFsaWQgdmFsdWUgZm9yIEhJR0hDSEFSVFNfQ0ROX1VSTC4gSXQgc2hvdWxkIHN0YXJ0IHdpdGggaHR0cDovLyBvciBodHRwczovLywgcmVjZWl2ZWQgJyR7dmFsdWV9J2BcbiAgICAgIH0pXG4gICAgKVxuICAgIC50cmFuc2Zvcm0oKHZhbHVlKSA9PiAodmFsdWUgIT09ICcnID8gdmFsdWUgOiB1bmRlZmluZWQpKSxcbiAgSElHSENIQVJUU19DT1JFX1NDUklQVFM6IHYuYXJyYXkoc2NyaXB0c05hbWVzLmNvcmUpLFxuICBISUdIQ0hBUlRTX01PRFVMRV9TQ1JJUFRTOiB2LmFycmF5KHNjcmlwdHNOYW1lcy5tb2R1bGVzKSxcbiAgSElHSENIQVJUU19JTkRJQ0FUT1JfU0NSSVBUUzogdi5hcnJheShzY3JpcHRzTmFtZXMuaW5kaWNhdG9ycyksXG4gIEhJR0hDSEFSVFNfRk9SQ0VfRkVUQ0g6IHYuYm9vbGVhbigpLFxuICBISUdIQ0hBUlRTX0NBQ0hFX1BBVEg6IHYuc3RyaW5nKCksXG4gIEhJR0hDSEFSVFNfQURNSU5fVE9LRU46IHYuc3RyaW5nKCksXG5cbiAgLy8gZXhwb3J0XG4gIEVYUE9SVF9UWVBFOiB2LmVudW0oWydqcGVnJywgJ3BuZycsICdwZGYnLCAnc3ZnJ10pLFxuICBFWFBPUlRfQ09OU1RSOiB2LmVudW0oWydjaGFydCcsICdzdG9ja0NoYXJ0JywgJ21hcENoYXJ0JywgJ2dhbnR0Q2hhcnQnXSksXG4gIEVYUE9SVF9ERUZBVUxUX0hFSUdIVDogdi5wb3NpdGl2ZU51bSgpLFxuICBFWFBPUlRfREVGQVVMVF9XSURUSDogdi5wb3NpdGl2ZU51bSgpLFxuICBFWFBPUlRfREVGQVVMVF9TQ0FMRTogdi5wb3NpdGl2ZU51bSgpLFxuICBFWFBPUlRfUkFTVEVSSVpBVElPTl9USU1FT1VUOiB2Lm5vbk5lZ2F0aXZlTnVtKCksXG5cbiAgLy8gY3VzdG9tXG4gIENVU1RPTV9MT0dJQ19BTExPV19DT0RFX0VYRUNVVElPTjogdi5ib29sZWFuKCksXG4gIENVU1RPTV9MT0dJQ19BTExPV19GSUxFX1JFU09VUkNFUzogdi5ib29sZWFuKCksXG5cbiAgLy8gc2VydmVyXG4gIFNFUlZFUl9FTkFCTEU6IHYuYm9vbGVhbigpLFxuICBTRVJWRVJfSE9TVDogdi5zdHJpbmcoKSxcbiAgU0VSVkVSX1BPUlQ6IHYucG9zaXRpdmVOdW0oKSxcbiAgU0VSVkVSX01BWF9VUExPQURfU0laRTogdi5wb3NpdGl2ZU51bSgpLFxuICBTRVJWRVJfQkVOQ0hNQVJLSU5HOiB2LmJvb2xlYW4oKSxcblxuICAvLyBzZXJ2ZXIgcHJveHlcbiAgU0VSVkVSX1BST1hZX0hPU1Q6IHYuc3RyaW5nKCksXG4gIFNFUlZFUl9QUk9YWV9QT1JUOiB2LnBvc2l0aXZlTnVtKCksXG4gIFNFUlZFUl9QUk9YWV9VU0VSTkFNRTogdi5zdHJpbmcoKSxcbiAgU0VSVkVSX1BST1hZX1BBU1NXT1JEOiB2LnN0cmluZygpLFxuICBTRVJWRVJfUFJPWFlfVElNRU9VVDogdi5ub25OZWdhdGl2ZU51bSgpLFxuXG4gIC8vIHNlcnZlciByYXRlIGxpbWl0aW5nXG4gIFNFUlZFUl9SQVRFX0xJTUlUSU5HX0VOQUJMRTogdi5ib29sZWFuKCksXG4gIFNFUlZFUl9SQVRFX0xJTUlUSU5HX01BWF9SRVFVRVNUUzogdi5ub25OZWdhdGl2ZU51bSgpLFxuICBTRVJWRVJfUkFURV9MSU1JVElOR19XSU5ET1c6IHYubm9uTmVnYXRpdmVOdW0oKSxcbiAgU0VSVkVSX1JBVEVfTElNSVRJTkdfREVMQVk6IHYubm9uTmVnYXRpdmVOdW0oKSxcbiAgU0VSVkVSX1JBVEVfTElNSVRJTkdfVFJVU1RfUFJPWFk6IHYuYm9vbGVhbigpLFxuICBTRVJWRVJfUkFURV9MSU1JVElOR19TS0lQX0tFWTogdi5zdHJpbmcoKSxcbiAgU0VSVkVSX1JBVEVfTElNSVRJTkdfU0tJUF9UT0tFTjogdi5zdHJpbmcoKSxcblxuICAvLyBzZXJ2ZXIgc3NsXG4gIFNFUlZFUl9TU0xfRU5BQkxFOiB2LmJvb2xlYW4oKSxcbiAgU0VSVkVSX1NTTF9GT1JDRTogdi5ib29sZWFuKCksXG4gIFNFUlZFUl9TU0xfUE9SVDogdi5wb3NpdGl2ZU51bSgpLFxuICBTRVJWRVJfU1NMX0NFUlRfUEFUSDogdi5zdHJpbmcoKSxcblxuICAvLyBwb29sXG4gIFBPT0xfTUlOX1dPUktFUlM6IHYubm9uTmVnYXRpdmVOdW0oKSxcbiAgUE9PTF9NQVhfV09SS0VSUzogdi5ub25OZWdhdGl2ZU51bSgpLFxuICBQT09MX1dPUktfTElNSVQ6IHYucG9zaXRpdmVOdW0oKSxcbiAgUE9PTF9BQ1FVSVJFX1RJTUVPVVQ6IHYubm9uTmVnYXRpdmVOdW0oKSxcbiAgUE9PTF9DUkVBVEVfVElNRU9VVDogdi5ub25OZWdhdGl2ZU51bSgpLFxuICBQT09MX0RFU1RST1lfVElNRU9VVDogdi5ub25OZWdhdGl2ZU51bSgpLFxuICBQT09MX0lETEVfVElNRU9VVDogdi5ub25OZWdhdGl2ZU51bSgpLFxuICBQT09MX0NSRUFURV9SRVRSWV9JTlRFUlZBTDogdi5ub25OZWdhdGl2ZU51bSgpLFxuICBQT09MX1JFQVBFUl9JTlRFUlZBTDogdi5ub25OZWdhdGl2ZU51bSgpLFxuICBQT09MX0JFTkNITUFSS0lORzogdi5ib29sZWFuKCksXG5cbiAgLy8gbG9nZ2VyXG4gIExPR0dJTkdfTEVWRUw6IHpcbiAgICAuc3RyaW5nKClcbiAgICAudHJpbSgpXG4gICAgLnJlZmluZShcbiAgICAgICh2YWx1ZSkgPT5cbiAgICAgICAgdmFsdWUgPT09ICcnIHx8XG4gICAgICAgICghaXNOYU4ocGFyc2VGbG9hdCh2YWx1ZSkpICYmXG4gICAgICAgICAgcGFyc2VGbG9hdCh2YWx1ZSkgPj0gMCAmJlxuICAgICAgICAgIHBhcnNlRmxvYXQodmFsdWUpIDw9IDUpLFxuICAgICAgKHZhbHVlKSA9PiAoe1xuICAgICAgICBtZXNzYWdlOiBgSW52YWxpZCB2YWx1ZSBmb3IgTE9HR0lOR19MRVZFTC4gV2Ugb25seSBhY2NlcHQgdmFsdWVzIGZyb20gMCB0byA1IGFzIGxvZ2dpbmcgbGV2ZWxzLCByZWNlaXZlZCAnJHt2YWx1ZX0nYFxuICAgICAgfSlcbiAgICApXG4gICAgLnRyYW5zZm9ybSgodmFsdWUpID0+ICh2YWx1ZSAhPT0gJycgPyBwYXJzZUZsb2F0KHZhbHVlKSA6IHVuZGVmaW5lZCkpLFxuICBMT0dHSU5HX0ZJTEU6IHYuc3RyaW5nKCksXG4gIExPR0dJTkdfREVTVDogdi5zdHJpbmcoKSxcbiAgTE9HR0lOR19UT19DT05TT0xFOiB2LmJvb2xlYW4oKSxcbiAgTE9HR0lOR19UT19GSUxFOiB2LmJvb2xlYW4oKSxcblxuICAvLyB1aVxuICBVSV9FTkFCTEU6IHYuYm9vbGVhbigpLFxuICBVSV9ST1VURTogdi5zdHJpbmcoKSxcblxuICAvLyBvdGhlclxuICBPVEhFUl9OT0RFX0VOVjogdi5lbnVtKFsnZGV2ZWxvcG1lbnQnLCAncHJvZHVjdGlvbicsICd0ZXN0J10pLFxuICBPVEhFUl9MSVNURU5fVE9fUFJPQ0VTU19FWElUUzogdi5ib29sZWFuKCksXG4gIE9USEVSX05PX0xPR086IHYuYm9vbGVhbigpLFxuICBPVEhFUl9IQVJEX1JFU0VUX1BBR0U6IHYuYm9vbGVhbigpLFxuICBPVEhFUl9CUk9XU0VSX1NIRUxMX01PREU6IHYuYm9vbGVhbigpLFxuICBPVEhFUl9BTExPV19YTElOSzogdi5ib29sZWFuKCksXG5cbiAgLy8gZGVidWdnZXJcbiAgREVCVUdfRU5BQkxFOiB2LmJvb2xlYW4oKSxcbiAgREVCVUdfSEVBRExFU1M6IHYuYm9vbGVhbigpLFxuICBERUJVR19ERVZUT09MUzogdi5ib29sZWFuKCksXG4gIERFQlVHX0xJU1RFTl9UT19DT05TT0xFOiB2LmJvb2xlYW4oKSxcbiAgREVCVUdfRFVNUElPOiB2LmJvb2xlYW4oKSxcbiAgREVCVUdfU0xPV19NTzogdi5ub25OZWdhdGl2ZU51bSgpLFxuICBERUJVR19ERUJVR0dJTkdfUE9SVDogdi5wb3NpdGl2ZU51bSgpXG59KTtcblxuZXhwb3J0IGNvbnN0IGVudnMgPSBDb25maWcucGFydGlhbCgpLnBhcnNlKHByb2Nlc3MuZW52KTtcbiIsIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG5cbkhpZ2hjaGFydHMgRXhwb3J0IFNlcnZlclxuXG5Db3B5cmlnaHQgKGMpIDIwMTYtMjAyNCwgSGlnaHNvZnRcblxuTGljZW5jZWQgdW5kZXIgdGhlIE1JVCBsaWNlbmNlLlxuXG5BZGRpdGlvbmFsbHkgYSB2YWxpZCBIaWdoY2hhcnRzIGxpY2Vuc2UgaXMgcmVxdWlyZWQgZm9yIHVzZS5cblxuU2VlIExJQ0VOU0UgZmlsZSBpbiByb290IGZvciBkZXRhaWxzLlxuXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG5pbXBvcnQgeyBhcHBlbmRGaWxlLCBleGlzdHNTeW5jLCBta2RpclN5bmMgfSBmcm9tICdmcyc7XG5cbi8vIFRoZSBhdmFpbGFibGUgY29sb3JzXG5jb25zdCBjb2xvcnMgPSBbJ3JlZCcsICd5ZWxsb3cnLCAnYmx1ZScsICdncmF5JywgJ2dyZWVuJ107XG5cbi8vIFRoZSBkZWZhdWx0IGxvZ2dpbmcgY29uZmlnXG5sZXQgbG9nZ2luZyA9IHtcbiAgLy8gRmxhZ3MgZm9yIGxvZ2dpbmcgc3RhdHVzXG4gIHRvQ29uc29sZTogdHJ1ZSxcbiAgdG9GaWxlOiBmYWxzZSxcbiAgcGF0aENyZWF0ZWQ6IGZhbHNlLFxuICAvLyBMb2cgbGV2ZWxzXG4gIGxldmVsc0Rlc2M6IFtcbiAgICB7XG4gICAgICB0aXRsZTogJ2Vycm9yJyxcbiAgICAgIGNvbG9yOiBjb2xvcnNbMF1cbiAgICB9LFxuICAgIHtcbiAgICAgIHRpdGxlOiAnd2FybmluZycsXG4gICAgICBjb2xvcjogY29sb3JzWzFdXG4gICAgfSxcbiAgICB7XG4gICAgICB0aXRsZTogJ25vdGljZScsXG4gICAgICBjb2xvcjogY29sb3JzWzJdXG4gICAgfSxcbiAgICB7XG4gICAgICB0aXRsZTogJ3ZlcmJvc2UnLFxuICAgICAgY29sb3I6IGNvbG9yc1szXVxuICAgIH0sXG4gICAge1xuICAgICAgdGl0bGU6ICdiZW5jaG1hcmsnLFxuICAgICAgY29sb3I6IGNvbG9yc1s0XVxuICAgIH1cbiAgXSxcbiAgLy8gTG9nIGxpc3RlbmVyc1xuICBsaXN0ZW5lcnM6IFtdXG59O1xuXG4vKipcbiAqIExvZ3MgdGhlIHByb3ZpZGVkIHRleHRzIHRvIGEgZmlsZSwgaWYgZmlsZSBsb2dnaW5nIGlzIGVuYWJsZWQuIEl0IGNyZWF0ZXNcbiAqIHRoZSBuZWNlc3NhcnkgZGlyZWN0b3J5IHN0cnVjdHVyZSBpZiBub3QgYWxyZWFkeSBjcmVhdGVkIGFuZCBhcHBlbmRzIHRoZVxuICogY29udGVudCwgaW5jbHVkaW5nIGFuIG9wdGlvbmFsIHByZWZpeCwgdG8gdGhlIHNwZWNpZmllZCBsb2cgZmlsZS5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ1tdfSB0ZXh0cyAtIEFuIGFycmF5IG9mIHRleHRzIHRvIGJlIGxvZ2dlZC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBwcmVmaXggLSBBbiBvcHRpb25hbCBwcmVmaXggdG8gYmUgYWRkZWQgdG8gZWFjaCBsb2cgZW50cnkuXG4gKi9cbmNvbnN0IGxvZ1RvRmlsZSA9ICh0ZXh0cywgcHJlZml4KSA9PiB7XG4gIGlmICghbG9nZ2luZy5wYXRoQ3JlYXRlZCkge1xuICAgIC8vIENyZWF0ZSBpZiBkb2VzIG5vdCBleGlzdFxuICAgICFleGlzdHNTeW5jKGxvZ2dpbmcuZGVzdCkgJiYgbWtkaXJTeW5jKGxvZ2dpbmcuZGVzdCk7XG5cbiAgICAvLyBXZSBub3cgYXNzdW1lIHRoZSBwYXRoIGlzIGF2YWlsYWJsZSwgZS5nLiBpdCdzIHRoZSByZXNwb25zaWJpbGl0eVxuICAgIC8vIG9mIHRoZSB1c2VyIHRvIGNyZWF0ZSB0aGUgcGF0aCB3aXRoIHRoZSBjb3JyZWN0IGFjY2VzcyByaWdodHMuXG4gICAgbG9nZ2luZy5wYXRoQ3JlYXRlZCA9IHRydWU7XG4gIH1cblxuICAvLyBBZGQgdGhlIGNvbnRlbnQgdG8gYSBmaWxlXG4gIGFwcGVuZEZpbGUoXG4gICAgYCR7bG9nZ2luZy5kZXN0fSR7bG9nZ2luZy5maWxlfWAsXG4gICAgW3ByZWZpeF0uY29uY2F0KHRleHRzKS5qb2luKCcgJykgKyAnXFxuJyxcbiAgICAoZXJyb3IpID0+IHtcbiAgICAgIGlmIChlcnJvcikge1xuICAgICAgICBjb25zb2xlLmxvZyhgW2xvZ2dlcl0gVW5hYmxlIHRvIHdyaXRlIHRvIGxvZyBmaWxlOiAke2Vycm9yfWApO1xuICAgICAgICBsb2dnaW5nLnRvRmlsZSA9IGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgKTtcbn07XG5cbi8qKlxuICogTG9ncyBhIG1lc3NhZ2UuIEFjY2VwdHMgYSB2YXJpYWJsZSBhbW91bnQgb2YgYXJndW1lbnRzLiBBcmd1bWVudHMgYWZ0ZXJcbiAqIGBsZXZlbGAgd2lsbCBiZSBwYXNzZWQgZGlyZWN0bHkgdG8gY29uc29sZS5sb2csIGFuZC9vciB3aWxsIGJlIGpvaW5lZFxuICogYW5kIGFwcGVuZGVkIHRvIHRoZSBsb2cgZmlsZS5cbiAqXG4gKiBAcGFyYW0ge2FueX0gYXJncyAtIEFuIGFycmF5IG9mIGFyZ3VtZW50cyB3aGVyZSB0aGUgZmlyc3QgaXMgdGhlIGxvZyBsZXZlbFxuICogYW5kIHRoZSByZXN0IGFyZSBzdHJpbmdzIHRvIGJ1aWxkIGEgbWVzc2FnZSB3aXRoLlxuICovXG5leHBvcnQgY29uc3QgbG9nID0gKC4uLmFyZ3MpID0+IHtcbiAgY29uc3QgW25ld0xldmVsLCAuLi50ZXh0c10gPSBhcmdzO1xuXG4gIC8vIEN1cnJlbnQgbG9nZ2luZyBvcHRpb25zXG4gIGNvbnN0IHsgbGV2ZWxzRGVzYywgbGV2ZWwgfSA9IGxvZ2dpbmc7XG5cbiAgLy8gQ2hlY2sgaWYgbG9nIGxldmVsIGlzIHdpdGhpbiBhIGNvcnJlY3QgcmFuZ2Ugb3IgaXMgYSBiZW5jaG1hcmsgbG9nXG4gIGlmIChcbiAgICBuZXdMZXZlbCAhPT0gNSAmJlxuICAgIChuZXdMZXZlbCA9PT0gMCB8fCBuZXdMZXZlbCA+IGxldmVsIHx8IGxldmVsID4gbGV2ZWxzRGVzYy5sZW5ndGgpXG4gICkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIEdldCByaWQgb2YgdGhlIEdNVCB0ZXh0IGluZm9ybWF0aW9uXG4gIGNvbnN0IG5ld0RhdGUgPSBuZXcgRGF0ZSgpLnRvU3RyaW5nKCkuc3BsaXQoJygnKVswXS50cmltKCk7XG5cbiAgLy8gQ3JlYXRlIGEgbWVzc2FnZSdzIHByZWZpeFxuICBjb25zdCBwcmVmaXggPSBgJHtuZXdEYXRlfSBbJHtsZXZlbHNEZXNjW25ld0xldmVsIC0gMV0udGl0bGV9XSAtYDtcblxuICAvLyBDYWxsIGF2YWlsYWJsZSBsb2cgbGlzdGVuZXJzXG4gIGxvZ2dpbmcubGlzdGVuZXJzLmZvckVhY2goKGZuKSA9PiB7XG4gICAgZm4ocHJlZml4LCB0ZXh0cy5qb2luKCcgJykpO1xuICB9KTtcblxuICAvLyBMb2cgdG8gY29uc29sZVxuICBpZiAobG9nZ2luZy50b0NvbnNvbGUpIHtcbiAgICBjb25zb2xlLmxvZy5hcHBseShcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIFtwcmVmaXgudG9TdHJpbmcoKVtsb2dnaW5nLmxldmVsc0Rlc2NbbmV3TGV2ZWwgLSAxXS5jb2xvcl1dLmNvbmNhdCh0ZXh0cylcbiAgICApO1xuICB9XG5cbiAgLy8gTG9nIHRvIGZpbGVcbiAgaWYgKGxvZ2dpbmcudG9GaWxlKSB7XG4gICAgbG9nVG9GaWxlKHRleHRzLCBwcmVmaXgpO1xuICB9XG59O1xuXG4vKipcbiAqIExvZ3MgYW4gZXJyb3IgbWVzc2FnZSB3aXRoIGl0cyBzdGFjayB0cmFjZS4gT3B0aW9uYWxseSwgYSBjdXN0b20gbWVzc2FnZVxuICogY2FuIGJlIHByb3ZpZGVkLlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBsZXZlbCAtIFRoZSBsb2cgbGV2ZWwuXG4gKiBAcGFyYW0ge0Vycm9yfSBlcnJvciAtIFRoZSBlcnJvciBvYmplY3QuXG4gKiBAcGFyYW0ge3N0cmluZ30gY3VzdG9tTWVzc2FnZSAtIEFuIG9wdGlvbmFsIGN1c3RvbSBtZXNzYWdlIHRvIGJlIGxvZ2dlZCBhbG9uZ1xuICogd2l0aCB0aGUgZXJyb3IuXG4gKi9cbmV4cG9ydCBjb25zdCBsb2dXaXRoU3RhY2sgPSAobmV3TGV2ZWwsIGVycm9yLCBjdXN0b21NZXNzYWdlKSA9PiB7XG4gIC8vIEdldCB0aGUgbWFpbiBtZXNzYWdlXG4gIGNvbnN0IG1haW5NZXNzYWdlID0gY3VzdG9tTWVzc2FnZSB8fCBlcnJvci5tZXNzYWdlO1xuXG4gIC8vIEN1cnJlbnQgbG9nZ2luZyBvcHRpb25zXG4gIGNvbnN0IHsgbGV2ZWwsIGxldmVsc0Rlc2MgfSA9IGxvZ2dpbmc7XG5cbiAgLy8gQ2hlY2sgaWYgbG9nIGxldmVsIGlzIHdpdGhpbiBhIGNvcnJlY3QgcmFuZ2VcbiAgaWYgKG5ld0xldmVsID09PSAwIHx8IG5ld0xldmVsID4gbGV2ZWwgfHwgbGV2ZWwgPiBsZXZlbHNEZXNjLmxlbmd0aCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIEdldCByaWQgb2YgdGhlIEdNVCB0ZXh0IGluZm9ybWF0aW9uXG4gIGNvbnN0IG5ld0RhdGUgPSBuZXcgRGF0ZSgpLnRvU3RyaW5nKCkuc3BsaXQoJygnKVswXS50cmltKCk7XG5cbiAgLy8gQ3JlYXRlIGEgbWVzc2FnZSdzIHByZWZpeFxuICBjb25zdCBwcmVmaXggPSBgJHtuZXdEYXRlfSBbJHtsZXZlbHNEZXNjW25ld0xldmVsIC0gMV0udGl0bGV9XSAtYDtcblxuICAvLyBJZiB0aGUgY3VzdG9tTWVzc2FnZSBleGlzdHMsIHdlIHdhbnQgdG8gZGlzcGxheSB0aGUgd2hvbGUgc3RhY2sgbWVzc2FnZVxuICBjb25zdCBzdGFja01lc3NhZ2UgPVxuICAgIGVycm9yLm1lc3NhZ2UgIT09IGVycm9yLnN0YWNrTWVzc2FnZSB8fCBlcnJvci5zdGFja01lc3NhZ2UgPT09IHVuZGVmaW5lZFxuICAgICAgPyBlcnJvci5zdGFja1xuICAgICAgOiBlcnJvci5zdGFjay5zcGxpdCgnXFxuJykuc2xpY2UoMSkuam9pbignXFxuJyk7XG5cbiAgLy8gQ29tYmluZSBjdXN0b20gbWVzc2FnZSBvciBlcnJvciBtZXNzYWdlIHdpdGggZXJyb3Igc3RhY2sgbWVzc2FnZVxuICBjb25zdCB0ZXh0cyA9IFttYWluTWVzc2FnZSwgJ1xcbicsIHN0YWNrTWVzc2FnZV07XG5cbiAgLy8gTG9nIHRvIGNvbnNvbGVcbiAgaWYgKGxvZ2dpbmcudG9Db25zb2xlKSB7XG4gICAgY29uc29sZS5sb2cuYXBwbHkoXG4gICAgICB1bmRlZmluZWQsXG4gICAgICBbcHJlZml4LnRvU3RyaW5nKClbbG9nZ2luZy5sZXZlbHNEZXNjW25ld0xldmVsIC0gMV0uY29sb3JdXS5jb25jYXQoW1xuICAgICAgICBtYWluTWVzc2FnZVtjb2xvcnNbbmV3TGV2ZWwgLSAxXV0sXG4gICAgICAgICdcXG4nLFxuICAgICAgICBzdGFja01lc3NhZ2VcbiAgICAgIF0pXG4gICAgKTtcbiAgfVxuXG4gIC8vIENhbGwgYXZhaWxhYmxlIGxvZyBsaXN0ZW5lcnNcbiAgbG9nZ2luZy5saXN0ZW5lcnMuZm9yRWFjaCgoZm4pID0+IHtcbiAgICBmbihwcmVmaXgsIHRleHRzLmpvaW4oJyAnKSk7XG4gIH0pO1xuXG4gIC8vIExvZyB0byBmaWxlXG4gIGlmIChsb2dnaW5nLnRvRmlsZSkge1xuICAgIGxvZ1RvRmlsZSh0ZXh0cywgcHJlZml4KTtcbiAgfVxufTtcblxuLyoqXG4gKiBTZXRzIHRoZSBsb2cgbGV2ZWwgdG8gdGhlIHNwZWNpZmllZCB2YWx1ZS4gTG9nIGxldmVscyBhcmUgKDAgPSBubyBsb2dnaW5nLFxuICogMSA9IGVycm9yLCAyID0gd2FybmluZywgMyA9IG5vdGljZSwgNCA9IHZlcmJvc2Ugb3IgNSA9IGJlbmNobWFyaylcbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gbmV3TGV2ZWwgLSBUaGUgbmV3IGxvZyBsZXZlbCB0byBiZSBzZXQuXG4gKi9cbmV4cG9ydCBjb25zdCBzZXRMb2dMZXZlbCA9IChuZXdMZXZlbCkgPT4ge1xuICBpZiAobmV3TGV2ZWwgPj0gMCAmJiBuZXdMZXZlbCA8PSBsb2dnaW5nLmxldmVsc0Rlc2MubGVuZ3RoKSB7XG4gICAgbG9nZ2luZy5sZXZlbCA9IG5ld0xldmVsO1xuICB9XG59O1xuXG4vKipcbiAqIEVuYWJsZXMgZmlsZSBsb2dnaW5nIHdpdGggdGhlIHNwZWNpZmllZCBkZXN0aW5hdGlvbiBhbmQgbG9nIGZpbGUuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGxvZ0Rlc3QgLSBUaGUgZGVzdGluYXRpb24gcGF0aCBmb3IgbG9nIGZpbGVzLlxuICogQHBhcmFtIHtzdHJpbmd9IGxvZ0ZpbGUgLSBUaGUgbG9nIGZpbGUgbmFtZS5cbiAqL1xuZXhwb3J0IGNvbnN0IGVuYWJsZUZpbGVMb2dnaW5nID0gKGxvZ0Rlc3QsIGxvZ0ZpbGUpID0+IHtcbiAgLy8gVXBkYXRlIGxvZ2dpbmcgb3B0aW9uc1xuICBsb2dnaW5nID0ge1xuICAgIC4uLmxvZ2dpbmcsXG4gICAgZGVzdDogbG9nRGVzdCB8fCBsb2dnaW5nLmRlc3QsXG4gICAgZmlsZTogbG9nRmlsZSB8fCBsb2dnaW5nLmZpbGUsXG4gICAgdG9GaWxlOiB0cnVlXG4gIH07XG5cbiAgaWYgKGxvZ2dpbmcuZGVzdC5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gbG9nKDEsICdbbG9nZ2VyXSBGaWxlIGxvZ2dpbmcgaW5pdGlhbGl6YXRpb246IG5vIHBhdGggc3VwcGxpZWQuJyk7XG4gIH1cblxuICBpZiAoIWxvZ2dpbmcuZGVzdC5lbmRzV2l0aCgnLycpKSB7XG4gICAgbG9nZ2luZy5kZXN0ICs9ICcvJztcbiAgfVxufTtcblxuLyoqXG4gKiBJbml0aWFsaXplcyBsb2dnaW5nIHdpdGggdGhlIHNwZWNpZmllZCBsb2dnaW5nIGNvbmZpZ3VyYXRpb24uXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGxvZ2dpbmdPcHRpb25zIC0gVGhlIGxvZ2dpbmcgY29uZmlndXJhdGlvbiBvYmplY3QuXG4gKi9cbmV4cG9ydCBjb25zdCBpbml0TG9nZ2luZyA9IChsb2dnaW5nT3B0aW9ucykgPT4ge1xuICAvLyBTZXQgYWxsIHRoZSBsb2dnaW5nIG9wdGlvbnMgb24gb3VyIGxvZ2dpbmcgbW9kdWxlIG9iamVjdFxuICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhsb2dnaW5nT3B0aW9ucykpIHtcbiAgICBsb2dnaW5nW2tleV0gPSB2YWx1ZTtcbiAgfVxuXG4gIC8vIFNldCB0aGUgbG9nIGxldmVsXG4gIHNldExvZ0xldmVsKGxvZ2dpbmdPcHRpb25zICYmIHBhcnNlSW50KGxvZ2dpbmdPcHRpb25zLmxldmVsKSk7XG5cbiAgLy8gU2V0IHRoZSBsb2cgZmlsZSBwYXRoIGFuZCBuYW1lXG4gIGlmIChsb2dnaW5nT3B0aW9ucyAmJiBsb2dnaW5nT3B0aW9ucy5kZXN0ICYmIGxvZ2dpbmdPcHRpb25zLnRvRmlsZSkge1xuICAgIGVuYWJsZUZpbGVMb2dnaW5nKFxuICAgICAgbG9nZ2luZ09wdGlvbnMuZGVzdCxcbiAgICAgIGxvZ2dpbmdPcHRpb25zLmZpbGUgfHwgJ2hpZ2hjaGFydHMtZXhwb3J0LXNlcnZlci5sb2cnXG4gICAgKTtcbiAgfVxufTtcblxuLyoqXG4gKiBBZGRzIGEgbGlzdGVuZXIgZnVuY3Rpb24gdG8gdGhlIGxvZ2dpbmcgc3lzdGVtLlxuICpcbiAqIEBwYXJhbSB7ZnVuY3Rpb259IGZuIC0gVGhlIGxpc3RlbmVyIGZ1bmN0aW9uIHRvIGJlIGFkZGVkLlxuICovXG5leHBvcnQgY29uc3QgbGlzdGVuID0gKGZuKSA9PiB7XG4gIGxvZ2dpbmcubGlzdGVuZXJzLnB1c2goZm4pO1xufTtcblxuZXhwb3J0IGRlZmF1bHQge1xuICBsb2csXG4gIGxvZ1dpdGhTdGFjayxcbiAgc2V0TG9nTGV2ZWwsXG4gIGVuYWJsZUZpbGVMb2dnaW5nLFxuICBpbml0TG9nZ2luZyxcbiAgbGlzdGVuXG59O1xuIiwiLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcblxuSGlnaGNoYXJ0cyBFeHBvcnQgU2VydmVyXG5cbkNvcHlyaWdodCAoYykgMjAxNi0yMDI0LCBIaWdoc29mdFxuXG5MaWNlbmNlZCB1bmRlciB0aGUgTUlUIGxpY2VuY2UuXG5cbkFkZGl0aW9uYWxseSBhIHZhbGlkIEhpZ2hjaGFydHMgbGljZW5zZSBpcyByZXF1aXJlZCBmb3IgdXNlLlxuXG5TZWUgTElDRU5TRSBmaWxlIGluIHJvb3QgZm9yIGRldGFpbHMuXG5cbioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG5cbmltcG9ydCB7IHJlYWRGaWxlU3luYyB9IGZyb20gJ2ZzJztcbmltcG9ydCB7IGpvaW4gfSBmcm9tICdwYXRoJztcbmltcG9ydCB7IGZpbGVVUkxUb1BhdGggfSBmcm9tICd1cmwnO1xuXG5pbXBvcnQgeyBkZWZhdWx0Q29uZmlnIH0gZnJvbSAnLi4vbGliL3NjaGVtYXMvY29uZmlnLmpzJztcbmltcG9ydCB7IGxvZywgbG9nV2l0aFN0YWNrIH0gZnJvbSAnLi9sb2dnZXIuanMnO1xuXG5jb25zdCBNQVhfQkFDS09GRl9BVFRFTVBUUyA9IDY7XG5cbmV4cG9ydCBjb25zdCBfX2Rpcm5hbWUgPSBmaWxlVVJMVG9QYXRoKG5ldyBVUkwoJy4uLy4nLCBpbXBvcnQubWV0YS51cmwpKTtcblxuLyoqXG4gKiBDbGVhcnMgYW5kIHN0YW5kYXJkaXplcyB0ZXh0IGJ5IHJlcGxhY2luZyBtdWx0aXBsZSBjb25zZWN1dGl2ZSB3aGl0ZXNwYWNlXG4gKiBjaGFyYWN0ZXJzIHdpdGggYSBzaW5nbGUgc3BhY2UgYW5kIHRyaW1taW5nIGFueSBsZWFkaW5nIG9yIHRyYWlsaW5nXG4gKiB3aGl0ZXNwYWNlLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IC0gVGhlIGlucHV0IHRleHQgdG8gYmUgY2xlYXJlZC5cbiAqIEBwYXJhbSB7UmVnRXhwfSBbcnVsZT0vXFxzXFxzKy9nXSAtIFRoZSByZWd1bGFyIGV4cHJlc3Npb24gcnVsZSB0byBtYXRjaFxuICogbXVsdGlwbGUgY29uc2VjdXRpdmUgd2hpdGVzcGFjZSBjaGFyYWN0ZXJzLlxuICogQHBhcmFtIHtzdHJpbmd9IFtyZXBsYWNlcj0nICddIC0gVGhlIHN0cmluZyB1c2VkIHRvIHJlcGxhY2UgbXVsdGlwbGVcbiAqIGNvbnNlY3V0aXZlIHdoaXRlc3BhY2UgY2hhcmFjdGVycy5cbiAqXG4gKiBAcmV0dXJucyB7c3RyaW5nfSAtIFRoZSBjbGVhcmVkIGFuZCBzdGFuZGFyZGl6ZWQgdGV4dC5cbiAqL1xuZXhwb3J0IGNvbnN0IGNsZWFyVGV4dCA9ICh0ZXh0LCBydWxlID0gL1xcc1xccysvZywgcmVwbGFjZXIgPSAnICcpID0+XG4gIHRleHQucmVwbGFjZUFsbChydWxlLCByZXBsYWNlcikudHJpbSgpO1xuXG4vKipcbiAqIEltcGxlbWVudHMgYW4gZXhwb25lbnRpYWwgYmFja29mZiBzdHJhdGVneSBmb3IgcmV0cnlpbmcgYSBmdW5jdGlvbiB1bnRpbFxuICogYSBjZXJ0YWluIG51bWJlciBvZiBhdHRlbXB0cyBhcmUgcmVhY2hlZC5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiAtIFRoZSBmdW5jdGlvbiB0byBiZSByZXRyaWVkLlxuICogQHBhcmFtIHtudW1iZXJ9IFthdHRlbXB0PTBdIC0gVGhlIGN1cnJlbnQgYXR0ZW1wdCBudW1iZXIuXG4gKiBAcGFyYW0gey4uLmFueX0gYXJncyAtIEFyZ3VtZW50cyB0byBiZSBwYXNzZWQgdG8gdGhlIGZ1bmN0aW9uLlxuICpcbiAqIEByZXR1cm5zIHtQcm9taXNlfSAtIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSByZXN1bHQgb2YgdGhlIGZ1bmN0aW9uXG4gKiBpZiBzdWNjZXNzZnVsLlxuICpcbiAqIEB0aHJvd3Mge0Vycm9yfSAtIFRocm93cyBhbiBlcnJvciBpZiB0aGUgbWF4aW11bSBudW1iZXIgb2YgYXR0ZW1wdHNcbiAqIGlzIHJlYWNoZWQuXG4gKi9cbmV4cG9ydCBjb25zdCBleHBCYWNrb2ZmID0gYXN5bmMgKGZuLCBhdHRlbXB0ID0gMCwgLi4uYXJncykgPT4ge1xuICB0cnkge1xuICAgIC8vIFRyeSB0byBjYWxsIHRoZSBmdW5jdGlvblxuICAgIHJldHVybiBhd2FpdCBmbiguLi5hcmdzKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAvLyBDYWxjdWxhdGUgZGVsYXkgaW4gbXNcbiAgICBjb25zdCBkZWxheUluTXMgPSAyICoqIGF0dGVtcHQgKiAxMDAwO1xuXG4gICAgLy8gSWYgdGhlIGF0dGVtcHQgZXhjZWVkcyB0aGUgbWF4aW11bSBhdHRlbXB0cyBvZiByZWFwZWF0LCB0aHJvdyBhbiBlcnJvclxuICAgIGlmICgrK2F0dGVtcHQgPj0gTUFYX0JBQ0tPRkZfQVRURU1QVFMpIHtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cblxuICAgIC8vIFdhaXQgZ2l2ZW4gYW1vdW50IG9mIHRpbWVcbiAgICBhd2FpdCBuZXcgUHJvbWlzZSgocmVzcG9uc2UpID0+IHNldFRpbWVvdXQocmVzcG9uc2UsIGRlbGF5SW5NcykpO1xuICAgIGxvZyhcbiAgICAgIDMsXG4gICAgICBgW3Bvb2xdIFdhaXRlZCAke2RlbGF5SW5Nc31tcyB1bnRpbCBuZXh0IGNhbGwgZm9yIHRoZSByZXNvdXJjZSBpZDogJHthcmdzWzBdfS5gXG4gICAgKTtcblxuICAgIC8vIFRyeSBhZ2FpblxuICAgIHJldHVybiBleHBCYWNrb2ZmKGZuLCBhdHRlbXB0LCAuLi5hcmdzKTtcbiAgfVxufTtcblxuLyoqXG4gKiBGaXhlcyB0aGUgZXhwb3J0IHR5cGUgYmFzZWQgb24gTUlNRSB0eXBlcyBhbmQgZmlsZSBleHRlbnNpb25zLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIC0gVGhlIG9yaWdpbmFsIGV4cG9ydCB0eXBlLlxuICogQHBhcmFtIHtzdHJpbmd9IG91dGZpbGUgLSBUaGUgZmlsZSBwYXRoIG9yIG5hbWUuXG4gKlxuICogQHJldHVybnMge3N0cmluZ30gLSBUaGUgY29ycmVjdGVkIGV4cG9ydCB0eXBlLlxuICovXG5leHBvcnQgY29uc3QgZml4VHlwZSA9ICh0eXBlLCBvdXRmaWxlKSA9PiB7XG4gIC8vIE1JTUUgdHlwZXNcbiAgY29uc3QgbWltZVR5cGVzID0ge1xuICAgICdpbWFnZS9wbmcnOiAncG5nJyxcbiAgICAnaW1hZ2UvanBlZyc6ICdqcGVnJyxcbiAgICAnYXBwbGljYXRpb24vcGRmJzogJ3BkZicsXG4gICAgJ2ltYWdlL3N2Zyt4bWwnOiAnc3ZnJ1xuICB9O1xuXG4gIC8vIEZvcm1hdHNcbiAgY29uc3QgZm9ybWF0cyA9IFsncG5nJywgJ2pwZWcnLCAncGRmJywgJ3N2ZyddO1xuXG4gIC8vIENoZWNrIGlmIHR5cGUgYW5kIG91dGZpbGUncyBleHRlbnNpb25zIGFyZSB0aGUgc2FtZVxuICBpZiAob3V0ZmlsZSkge1xuICAgIGNvbnN0IG91dFR5cGUgPSBvdXRmaWxlLnNwbGl0KCcuJykucG9wKCk7XG5cbiAgICBpZiAob3V0VHlwZSA9PT0gJ2pwZycpIHtcbiAgICAgIHR5cGUgPSAnanBlZyc7XG4gICAgfSBlbHNlIGlmIChmb3JtYXRzLmluY2x1ZGVzKG91dFR5cGUpICYmIHR5cGUgIT09IG91dFR5cGUpIHtcbiAgICAgIHR5cGUgPSBvdXRUeXBlO1xuICAgIH1cbiAgfVxuXG4gIC8vIFJldHVybiBhIGNvcnJlY3QgdHlwZVxuICByZXR1cm4gbWltZVR5cGVzW3R5cGVdIHx8IGZvcm1hdHMuZmluZCgodCkgPT4gdCA9PT0gdHlwZSkgfHwgJ3BuZyc7XG59O1xuXG4vKipcbiAqIEhhbmRsZXMgYW5kIHZhbGlkYXRlcyByZXNvdXJjZXMgZm9yIGV4cG9ydC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdHxzdHJpbmd9IHJlc291cmNlcyAtIFRoZSByZXNvdXJjZXMgdG8gYmUgaGFuZGxlZC4gQ2FuIGJlIGVpdGhlclxuICogYSBKU09OIG9iamVjdCwgc3RyaW5naWZpZWQgSlNPTiBvciBhIHBhdGggdG8gYSBKU09OIGZpbGUuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGFsbG93RmlsZVJlc291cmNlcyAtIFdoZXRoZXIgdG8gYWxsb3cgbG9hZGluZyByZXNvdXJjZXMgZnJvbVxuICogZmlsZXMuXG4gKlxuICogQHJldHVybnMge09iamVjdHx1bmRlZmluZWR9IC0gVGhlIGhhbmRsZWQgcmVzb3VyY2VzIG9yIHVuZGVmaW5lZCBpZiBubyB2YWxpZFxuICogcmVzb3VyY2VzIGFyZSBmb3VuZC5cbiAqL1xuZXhwb3J0IGNvbnN0IGhhbmRsZVJlc291cmNlcyA9IChyZXNvdXJjZXMgPSBmYWxzZSwgYWxsb3dGaWxlUmVzb3VyY2VzKSA9PiB7XG4gIGNvbnN0IGFsbG93ZWRQcm9wcyA9IFsnanMnLCAnY3NzJywgJ2ZpbGVzJ107XG5cbiAgbGV0IGhhbmRsZWRSZXNvdXJjZXMgPSByZXNvdXJjZXM7XG4gIGxldCBjb3JyZWN0UmVzb3VyY2VzID0gZmFsc2U7XG5cbiAgLy8gVHJ5IHRvIGxvYWQgcmVzb3VyY2VzIGZyb20gYSBmaWxlXG4gIGlmIChhbGxvd0ZpbGVSZXNvdXJjZXMgJiYgcmVzb3VyY2VzLmVuZHNXaXRoKCcuanNvbicpKSB7XG4gICAgdHJ5IHtcbiAgICAgIGhhbmRsZWRSZXNvdXJjZXMgPSBpc0NvcnJlY3RKU09OKHJlYWRGaWxlU3luYyhyZXNvdXJjZXMsICd1dGY4JykpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICByZXR1cm4gbG9nV2l0aFN0YWNrKDIsIGVycm9yLCBgW2NsaV0gTm8gcmVzb3VyY2VzIGZvdW5kLmApO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICAvLyBUcnkgdG8gZ2V0IEpTT05cbiAgICBoYW5kbGVkUmVzb3VyY2VzID0gaXNDb3JyZWN0SlNPTihyZXNvdXJjZXMpO1xuXG4gICAgLy8gR2V0IHJpZCBvZiB0aGUgZmlsZXMgc2VjdGlvblxuICAgIGlmIChoYW5kbGVkUmVzb3VyY2VzICYmICFhbGxvd0ZpbGVSZXNvdXJjZXMpIHtcbiAgICAgIGRlbGV0ZSBoYW5kbGVkUmVzb3VyY2VzLmZpbGVzO1xuICAgIH1cbiAgfVxuXG4gIC8vIEZpbHRlciBmcm9tIHVubmVjZXNzYXJ5IHByb3BlcnRpZXNcbiAgZm9yIChjb25zdCBwcm9wTmFtZSBpbiBoYW5kbGVkUmVzb3VyY2VzKSB7XG4gICAgaWYgKCFhbGxvd2VkUHJvcHMuaW5jbHVkZXMocHJvcE5hbWUpKSB7XG4gICAgICBkZWxldGUgaGFuZGxlZFJlc291cmNlc1twcm9wTmFtZV07XG4gICAgfSBlbHNlIGlmICghY29ycmVjdFJlc291cmNlcykge1xuICAgICAgY29ycmVjdFJlc291cmNlcyA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgLy8gQ2hlY2sgaWYgYXQgbGVhc3Qgb25lIG9mIGFsbG93ZWQgcHJvcGVydGllcyBpcyBwcmVzZW50XG4gIGlmICghY29ycmVjdFJlc291cmNlcykge1xuICAgIHJldHVybiBsb2coMywgYFtjbGldIE5vIHJlc291cmNlcyBmb3VuZC5gKTtcbiAgfVxuXG4gIC8vIEhhbmRsZSBmaWxlcyBzZWN0aW9uXG4gIGlmIChoYW5kbGVkUmVzb3VyY2VzLmZpbGVzKSB7XG4gICAgaGFuZGxlZFJlc291cmNlcy5maWxlcyA9IGhhbmRsZWRSZXNvdXJjZXMuZmlsZXMubWFwKChpdGVtKSA9PiBpdGVtLnRyaW0oKSk7XG4gICAgaWYgKCFoYW5kbGVkUmVzb3VyY2VzLmZpbGVzIHx8IGhhbmRsZWRSZXNvdXJjZXMuZmlsZXMubGVuZ3RoIDw9IDApIHtcbiAgICAgIGRlbGV0ZSBoYW5kbGVkUmVzb3VyY2VzLmZpbGVzO1xuICAgIH1cbiAgfVxuXG4gIC8vIFJldHVybiByZXNvdXJjZXNcbiAgcmV0dXJuIGhhbmRsZWRSZXNvdXJjZXM7XG59O1xuXG4vKipcbiAqIFZhbGlkYXRlcyBhbmQgcGFyc2VzIEpTT04gZGF0YS4gQ2hlY2tzIGlmIHByb3ZpZGVkIGRhdGEgaXMgb3IgY2FuXG4gKiBiZSBhIGNvcnJlY3QgSlNPTi4gSWYgYSBwcmltaXRpdmUgaXMgcHJvdmlkZWQsIGl0IGlzIHN0cmluZ2lmaWVkIGFuZCByZXR1cm5lZC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdHxzdHJpbmd9IGRhdGEgLSBUaGUgSlNPTiBkYXRhIHRvIGJlIHZhbGlkYXRlZCBhbmQgcGFyc2VkLlxuICogQHBhcmFtIHtib29sZWFufSB0b1N0cmluZyAtIFdoZXRoZXIgdG8gcmV0dXJuIGEgc3RyaW5naWZpZWQgcmVwcmVzZW50YXRpb25cbiAqIG9mIHRoZSBwYXJzZWQgSlNPTi5cbiAqXG4gKiBAcmV0dXJucyB7T2JqZWN0fHN0cmluZ3xib29sZWFufSAtIFRoZSBwYXJzZWQgSlNPTiBvYmplY3QsIHN0cmluZ2lmaWVkIEpTT04sXG4gKiBvciBmYWxzZSBpZiB2YWxpZGF0aW9uIGZhaWxzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNDb3JyZWN0SlNPTihkYXRhLCB0b1N0cmluZykge1xuICB0cnkge1xuICAgIC8vIEdldCB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIGlmIG5vdCBhbHJlYWR5IGJlZm9yZSBwYXJzaW5nXG4gICAgY29uc3QgcGFyc2VkRGF0YSA9IEpTT04ucGFyc2UoXG4gICAgICB0eXBlb2YgZGF0YSAhPT0gJ3N0cmluZycgPyBKU09OLnN0cmluZ2lmeShkYXRhKSA6IGRhdGFcbiAgICApO1xuXG4gICAgLy8gUmV0dXJuIGEgc3RyaW5naWZpZWQgcmVwcmVzZW50YXRpb24gb2YgYSBKU09OIGlmIHJlcXVpcmVkXG4gICAgaWYgKHR5cGVvZiBwYXJzZWREYXRhICE9PSAnc3RyaW5nJyAmJiB0b1N0cmluZykge1xuICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHBhcnNlZERhdGEpO1xuICAgIH1cblxuICAgIC8vIFJldHVybiBhIEpTT05cbiAgICByZXR1cm4gcGFyc2VkRGF0YTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBpdGVtIGlzIGFuIG9iamVjdC5cbiAqXG4gKiBAcGFyYW0ge2FueX0gaXRlbSAtIFRoZSBpdGVtIHRvIGJlIGNoZWNrZWQuXG4gKlxuICogQHJldHVybnMge2Jvb2xlYW59IC0gVHJ1ZSBpZiB0aGUgaXRlbSBpcyBhbiBvYmplY3QsIGZhbHNlIG90aGVyd2lzZS5cbiAqL1xuZXhwb3J0IGNvbnN0IGlzT2JqZWN0ID0gKGl0ZW0pID0+XG4gIHR5cGVvZiBpdGVtID09PSAnb2JqZWN0JyAmJiAhQXJyYXkuaXNBcnJheShpdGVtKSAmJiBpdGVtICE9PSBudWxsO1xuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gb2JqZWN0IGlzIGVtcHR5LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBpdGVtIC0gVGhlIG9iamVjdCB0byBiZSBjaGVja2VkLlxuICpcbiAqIEByZXR1cm5zIHtib29sZWFufSAtIFRydWUgaWYgdGhlIG9iamVjdCBpcyBlbXB0eSwgZmFsc2Ugb3RoZXJ3aXNlLlxuICovXG5leHBvcnQgY29uc3QgaXNPYmplY3RFbXB0eSA9IChpdGVtKSA9PlxuICB0eXBlb2YgaXRlbSA9PT0gJ29iamVjdCcgJiZcbiAgIUFycmF5LmlzQXJyYXkoaXRlbSkgJiZcbiAgaXRlbSAhPT0gbnVsbCAmJlxuICBPYmplY3Qua2V5cyhpdGVtKS5sZW5ndGggPT09IDA7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGEgcHJpdmF0ZSBJUCByYW5nZSBVUkwgaXMgZm91bmQgaW4gdGhlIGdpdmVuIHN0cmluZy5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gaXRlbSAtIFRoZSBzdHJpbmcgdG8gYmUgY2hlY2tlZCBmb3IgYSBwcml2YXRlIElQIHJhbmdlIFVSTC5cbiAqXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBUcnVlIGlmIGEgcHJpdmF0ZSBJUCByYW5nZSBVUkwgaXMgZm91bmQsIGZhbHNlXG4gKiBvdGhlcndpc2UuXG4gKi9cbmV4cG9ydCBjb25zdCBpc1ByaXZhdGVSYW5nZVVybEZvdW5kID0gKGl0ZW0pID0+IHtcbiAgY29uc3QgcmVnZXhQYXR0ZXJucyA9IFtcbiAgICAveGxpbms6aHJlZj1cIig/Omh0dHA6XFwvXFwvfGh0dHBzOlxcL1xcLyk/bG9jYWxob3N0XFxiLyxcbiAgICAveGxpbms6aHJlZj1cIig/Omh0dHA6XFwvXFwvfGh0dHBzOlxcL1xcLyk/MTBcXC5cXGR7MSwzfVxcLlxcZHsxLDN9XFwuXFxkezEsM31cXGIvLFxuICAgIC94bGluazpocmVmPVwiKD86aHR0cDpcXC9cXC98aHR0cHM6XFwvXFwvKT8xMjdcXC5cXGR7MSwzfVxcLlxcZHsxLDN9XFwuXFxkezEsM31cXGIvLFxuICAgIC94bGluazpocmVmPVwiKD86aHR0cDpcXC9cXC98aHR0cHM6XFwvXFwvKT8xNzJcXC4oMVs2LTldfDJbMC05XXwzWzAtMV0pXFwuXFxkezEsM31cXC5cXGR7MSwzfVxcYi8sXG4gICAgL3hsaW5rOmhyZWY9XCIoPzpodHRwOlxcL1xcL3xodHRwczpcXC9cXC8pPzE5MlxcLjE2OFxcLlxcZHsxLDN9XFwuXFxkezEsM31cXGIvXG4gIF07XG5cbiAgcmV0dXJuIHJlZ2V4UGF0dGVybnMuc29tZSgocGF0dGVybikgPT4gcGF0dGVybi50ZXN0KGl0ZW0pKTtcbn07XG5cbi8qKlxuICogQ3JlYXRlcyBhIGRlZXAgY29weSBvZiB0aGUgZ2l2ZW4gb2JqZWN0IG9yIGFycmF5LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fEFycmF5fSBvYmogLSBUaGUgb2JqZWN0IG9yIGFycmF5IHRvIGJlIGRlZXBseSBjb3BpZWQuXG4gKlxuICogQHJldHVybnMge09iamVjdHxBcnJheX0gLSBUaGUgZGVlcCBjb3B5IG9mIHRoZSBwcm92aWRlZCBvYmplY3Qgb3IgYXJyYXkuXG4gKi9cbmV4cG9ydCBjb25zdCBkZWVwQ29weSA9IChvYmopID0+IHtcbiAgaWYgKG9iaiA9PT0gbnVsbCB8fCB0eXBlb2Ygb2JqICE9PSAnb2JqZWN0Jykge1xuICAgIHJldHVybiBvYmo7XG4gIH1cblxuICBjb25zdCBjb3B5ID0gQXJyYXkuaXNBcnJheShvYmopID8gW10gOiB7fTtcblxuICBmb3IgKGNvbnN0IGtleSBpbiBvYmopIHtcbiAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KSkge1xuICAgICAgY29weVtrZXldID0gZGVlcENvcHkob2JqW2tleV0pO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBjb3B5O1xufTtcblxuLyoqXG4gKiBDb252ZXJ0cyB0aGUgcHJvdmlkZWQgb3B0aW9ucyBvYmplY3QgdG8gYSBKU09OLWZvcm1hdHRlZCBzdHJpbmcgd2l0aCB0aGVcbiAqIG9wdGlvbiB0byBwcmVzZXJ2ZSBmdW5jdGlvbnMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgLSBUaGUgb3B0aW9ucyBvYmplY3QgdG8gYmUgY29udmVydGVkIHRvIGEgc3RyaW5nLlxuICogQHBhcmFtIHtib29sZWFufSBhbGxvd0Z1bmN0aW9ucyAtIElmIHNldCB0byB0cnVlLCBmdW5jdGlvbnMgYXJlIHByZXNlcnZlZFxuICogaW4gdGhlIG91dHB1dC5cbiAqXG4gKiBAcmV0dXJucyB7c3RyaW5nfSAtIFRoZSBKU09OLWZvcm1hdHRlZCBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBvcHRpb25zLlxuICovXG5leHBvcnQgY29uc3Qgb3B0aW9uc1N0cmluZ2lmeSA9IChvcHRpb25zLCBhbGxvd0Z1bmN0aW9ucykgPT4ge1xuICBjb25zdCByZXBsYWNlckNhbGxiYWNrID0gKG5hbWUsIHZhbHVlKSA9PiB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHZhbHVlID0gdmFsdWUudHJpbSgpO1xuXG4gICAgICAvLyBJZiBhbGxvd0Z1bmN0aW9ucyBpcyBzZXQgdG8gdHJ1ZSwgcHJlc2VydmUgZnVuY3Rpb25zXG4gICAgICBpZiAoXG4gICAgICAgICh2YWx1ZS5zdGFydHNXaXRoKCdmdW5jdGlvbignKSB8fCB2YWx1ZS5zdGFydHNXaXRoKCdmdW5jdGlvbiAoJykpICYmXG4gICAgICAgIHZhbHVlLmVuZHNXaXRoKCd9JylcbiAgICAgICkge1xuICAgICAgICB2YWx1ZSA9IGFsbG93RnVuY3Rpb25zXG4gICAgICAgICAgPyBgRVhQX0ZVTiR7KHZhbHVlICsgJycpLnJlcGxhY2VBbGwoL1xcbnxcXHR8XFxyL2csICcgJyl9RVhQX0ZVTmBcbiAgICAgICAgICA6IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nXG4gICAgICA/IGBFWFBfRlVOJHsodmFsdWUgKyAnJykucmVwbGFjZUFsbCgvXFxufFxcdHxcXHIvZywgJyAnKX1FWFBfRlVOYFxuICAgICAgOiB2YWx1ZTtcbiAgfTtcblxuICAvLyBTdHJpbmdpZnkgb3B0aW9ucyBhbmQgaWYgcmVxdWlyZWQsIHJlcGxhY2Ugc3BlY2lhbCBmdW5jdGlvbnMgbWFya3NcbiAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KG9wdGlvbnMsIHJlcGxhY2VyQ2FsbGJhY2spLnJlcGxhY2VBbGwoXG4gICAgL1wiRVhQX0ZVTnxFWFBfRlVOXCIvZyxcbiAgICAnJ1xuICApO1xufTtcblxuLyoqXG4gKiBQcmludHMgdGhlIEhpZ2hjaGFydHMgRXhwb3J0IFNlcnZlciBsb2dvIGFuZCB2ZXJzaW9uIGluZm9ybWF0aW9uLlxuICpcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gbm9Mb2dvIC0gSWYgdHJ1ZSwgb25seSBwcmludHMgdmVyc2lvbiBpbmZvcm1hdGlvbiB3aXRob3V0XG4gKiB0aGUgbG9nby5cbiAqL1xuZXhwb3J0IGNvbnN0IHByaW50TG9nbyA9IChub0xvZ28pID0+IHtcbiAgLy8gR2V0IHBhY2thZ2UgdmVyc2lvbiBlaXRoZXIgZnJvbSBlbnYgb3IgZnJvbSBwYWNrYWdlLmpzb25cbiAgY29uc3QgcGFja2FnZVZlcnNpb24gPSBKU09OLnBhcnNlKFxuICAgIHJlYWRGaWxlU3luYyhqb2luKF9fZGlybmFtZSwgJ3BhY2thZ2UuanNvbicpKVxuICApLnZlcnNpb247XG5cbiAgLy8gUHJpbnQgdGV4dCBvbmx5XG4gIGlmIChub0xvZ28pIHtcbiAgICBjb25zb2xlLmxvZyhgU3RhcnRpbmcgSGlnaGNoYXJ0cyBFeHBvcnQgU2VydmVyIHYke3BhY2thZ2VWZXJzaW9ufS4uLmApO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIFByaW50IHRoZSBsb2dvXG4gIGNvbnNvbGUubG9nKFxuICAgIHJlYWRGaWxlU3luYyhfX2Rpcm5hbWUgKyAnL21zZy9zdGFydHVwLm1zZycpLnRvU3RyaW5nKCkuYm9sZC55ZWxsb3csXG4gICAgYHYke3BhY2thZ2VWZXJzaW9ufVxcbmAuYm9sZFxuICApO1xufTtcblxuLyoqXG4gKiBQcmludHMgdGhlIHVzYWdlIGluZm9ybWF0aW9uIGZvciBDTEkgYXJndW1lbnRzLiBJZiByZXF1aXJlZCwgaXQgY2FuIGxpc3RcbiAqIHByb3BlcnRpZXMgcmVjdXJzaXZlbHlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHByaW50VXNhZ2UoKSB7XG4gIGNvbnN0IHBhZCA9IDQ4O1xuICBjb25zdCByZWFkbWUgPSAnaHR0cHM6Ly9naXRodWIuY29tL2hpZ2hjaGFydHMvbm9kZS1leHBvcnQtc2VydmVyI3JlYWRtZSc7XG5cbiAgLy8gRGlzcGxheSByZWFkbWUgaW5mb3JtYXRpb25cbiAgY29uc29sZS5sb2coXG4gICAgJ1xcblVzYWdlIG9mIENMSSBhcmd1bWVudHM6Jy5ib2xkLFxuICAgICdcXG4tLS0tLS0nLFxuICAgIGBcXG5Gb3IgbW9yZSBkZXRhaWxlZCBpbmZvcm1hdGlvbiwgdmlzaXQgdGhlIHJlYWRtZSBhdDogJHtyZWFkbWUuYm9sZC55ZWxsb3d9LmBcbiAgKTtcblxuICBjb25zdCBjeWNsZUNhdGVnb3JpZXMgPSAob3B0aW9ucykgPT4ge1xuICAgIGZvciAoY29uc3QgW25hbWUsIG9wdGlvbl0gb2YgT2JqZWN0LmVudHJpZXMob3B0aW9ucykpIHtcbiAgICAgIC8vIElmIGNhdGVnb3J5IGhhcyBtb3JlIGxldmVscywgZ28gZnVydGhlclxuICAgICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob3B0aW9uLCAndmFsdWUnKSkge1xuICAgICAgICBjeWNsZUNhdGVnb3JpZXMob3B0aW9uKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxldCBkZXNjTmFtZSA9IGAgIC0tJHtvcHRpb24uY2xpTmFtZSB8fCBuYW1lfSAke1xuICAgICAgICAgICgnPCcgKyBvcHRpb24udHlwZSArICc+JykuZ3JlZW5cbiAgICAgICAgfSBgO1xuICAgICAgICBpZiAoZGVzY05hbWUubGVuZ3RoIDwgcGFkKSB7XG4gICAgICAgICAgZm9yIChsZXQgaSA9IGRlc2NOYW1lLmxlbmd0aDsgaSA8IHBhZDsgaSsrKSB7XG4gICAgICAgICAgICBkZXNjTmFtZSArPSAnLic7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gRGlzcGxheSBjb3JyZWN0bHkgYWxpZ25lZCBtZXNzYWdlc1xuICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICBkZXNjTmFtZSxcbiAgICAgICAgICBvcHRpb24uZGVzY3JpcHRpb24sXG4gICAgICAgICAgYFtEZWZhdWx0OiAke29wdGlvbi52YWx1ZS50b1N0cmluZygpLmJvbGR9XWAuYmx1ZVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICAvLyBDeWNsZSB0aHJvdWdoIG9wdGlvbnMgb2YgZWFjaCBjYXRlZ29yaWVzIGFuZCBkaXNwbGF5IHRoZSB1c2FnZSBpbmZvXG4gIE9iamVjdC5rZXlzKGRlZmF1bHRDb25maWcpLmZvckVhY2goKGNhdGVnb3J5KSA9PiB7XG4gICAgLy8gT25seSBwdXBwZXRlZXIgYW5kIGhpZ2hjaGFydHMgY2F0ZWdvcmllcyBjYW5ub3QgYmUgY29uZmlndXJlZCB0aHJvdWdoIENMSVxuICAgIGlmICghWydwdXBwZXRlZXInLCAnaGlnaGNoYXJ0cyddLmluY2x1ZGVzKGNhdGVnb3J5KSkge1xuICAgICAgY29uc29sZS5sb2coYFxcbiR7Y2F0ZWdvcnkudG9VcHBlckNhc2UoKX1gLnJlZCk7XG4gICAgICBjeWNsZUNhdGVnb3JpZXMoZGVmYXVsdENvbmZpZ1tjYXRlZ29yeV0pO1xuICAgIH1cbiAgfSk7XG4gIGNvbnNvbGUubG9nKCdcXG4nKTtcbn1cblxuLyoqXG4gKiBSb3VuZHMgYSBudW1iZXIgdG8gdGhlIHNwZWNpZmllZCBwcmVjaXNpb24uXG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIC0gVGhlIG51bWJlciB0byBiZSByb3VuZGVkLlxuICogQHBhcmFtIHtudW1iZXJ9IHByZWNpc2lvbiAtIFRoZSBudW1iZXIgb2YgZGVjaW1hbCBwbGFjZXMgdG8gcm91bmQgdG8uXG4gKlxuICogQHJldHVybnMge251bWJlcn0gLSBUaGUgcm91bmRlZCBudW1iZXIuXG4gKi9cbmV4cG9ydCBjb25zdCByb3VuZE51bWJlciA9ICh2YWx1ZSwgcHJlY2lzaW9uID0gMSkgPT4ge1xuICBjb25zdCBtdWx0aXBsaWVyID0gTWF0aC5wb3coMTAsIHByZWNpc2lvbiB8fCAwKTtcbiAgcmV0dXJuIE1hdGgucm91bmQoK3ZhbHVlICogbXVsdGlwbGllcikgLyBtdWx0aXBsaWVyO1xufTtcblxuLyoqXG4gKiBDb252ZXJ0cyBhIHZhbHVlIHRvIGEgYm9vbGVhbi5cbiAqXG4gKiBAcGFyYW0ge2FueX0gaXRlbSAtIFRoZSB2YWx1ZSB0byBiZSBjb252ZXJ0ZWQgdG8gYSBib29sZWFuLlxuICpcbiAqIEByZXR1cm5zIHtib29sZWFufSAtIFRoZSBib29sZWFuIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBpbnB1dCB2YWx1ZS5cbiAqL1xuZXhwb3J0IGNvbnN0IHRvQm9vbGVhbiA9IChpdGVtKSA9PlxuICBbJ2ZhbHNlJywgJ3VuZGVmaW5lZCcsICdudWxsJywgJ05hTicsICcwJywgJyddLmluY2x1ZGVzKGl0ZW0pXG4gICAgPyBmYWxzZVxuICAgIDogISFpdGVtO1xuXG4vKipcbiAqIFdyYXBzIGN1c3RvbSBjb2RlIHRvIGV4ZWN1dGUgaXQgc2FmZWx5LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBjdXN0b21Db2RlIC0gVGhlIGN1c3RvbSBjb2RlIHRvIGJlIHdyYXBwZWQuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGFsbG93RmlsZVJlc291cmNlcyAtIEZsYWcgdG8gYWxsb3cgbG9hZGluZyBjb2RlIGZyb20gYSBmaWxlLlxuICpcbiAqIEByZXR1cm5zIHtzdHJpbmd8Ym9vbGVhbn0gLSBUaGUgd3JhcHBlZCBjdXN0b20gY29kZSBvciBmYWxzZSBpZiB3cmFwcGluZ1xuICogZmFpbHMuXG4gKi9cbmV4cG9ydCBjb25zdCB3cmFwQXJvdW5kID0gKGN1c3RvbUNvZGUsIGFsbG93RmlsZVJlc291cmNlcykgPT4ge1xuICBpZiAoY3VzdG9tQ29kZSAmJiB0eXBlb2YgY3VzdG9tQ29kZSA9PT0gJ3N0cmluZycpIHtcbiAgICBjdXN0b21Db2RlID0gY3VzdG9tQ29kZS50cmltKCk7XG5cbiAgICBpZiAoY3VzdG9tQ29kZS5lbmRzV2l0aCgnLmpzJykpIHtcbiAgICAgIHJldHVybiBhbGxvd0ZpbGVSZXNvdXJjZXNcbiAgICAgICAgPyB3cmFwQXJvdW5kKHJlYWRGaWxlU3luYyhjdXN0b21Db2RlLCAndXRmOCcpKVxuICAgICAgICA6IGZhbHNlO1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICBjdXN0b21Db2RlLnN0YXJ0c1dpdGgoJ2Z1bmN0aW9uKCknKSB8fFxuICAgICAgY3VzdG9tQ29kZS5zdGFydHNXaXRoKCdmdW5jdGlvbiAoKScpIHx8XG4gICAgICBjdXN0b21Db2RlLnN0YXJ0c1dpdGgoJygpPT4nKSB8fFxuICAgICAgY3VzdG9tQ29kZS5zdGFydHNXaXRoKCcoKSA9PicpXG4gICAgKSB7XG4gICAgICByZXR1cm4gYCgke2N1c3RvbUNvZGV9KSgpYDtcbiAgICB9XG4gICAgcmV0dXJuIGN1c3RvbUNvZGUucmVwbGFjZSgvOyQvLCAnJyk7XG4gIH1cbn07XG5cbi8qKlxuICogVXRpbGl0eSB0byBtZWFzdXJlIGVsYXBzZWQgdGltZSB1c2luZyB0aGUgTm9kZS5qcyBwcm9jZXNzLmhydGltZSgpIG1ldGhvZC5cbiAqXG4gKiBAcmV0dXJucyB7ZnVuY3Rpb24oKTogbnVtYmVyfSAtIEEgZnVuY3Rpb24gdG8gY2FsY3VsYXRlIHRoZSBlbGFwc2VkIHRpbWVcbiAqIGluIG1pbGxpc2Vjb25kcy5cbiAqL1xuZXhwb3J0IGNvbnN0IG1lYXN1cmVUaW1lID0gKCkgPT4ge1xuICBjb25zdCBzdGFydCA9IHByb2Nlc3MuaHJ0aW1lLmJpZ2ludCgpO1xuICByZXR1cm4gKCkgPT4gTnVtYmVyKHByb2Nlc3MuaHJ0aW1lLmJpZ2ludCgpIC0gc3RhcnQpIC8gMTAwMDAwMDtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19kaXJuYW1lLFxuICBjbGVhclRleHQsXG4gIGV4cEJhY2tvZmYsXG4gIGZpeFR5cGUsXG4gIGhhbmRsZVJlc291cmNlcyxcbiAgaXNDb3JyZWN0SlNPTixcbiAgaXNPYmplY3QsXG4gIGlzT2JqZWN0RW1wdHksXG4gIGlzUHJpdmF0ZVJhbmdlVXJsRm91bmQsXG4gIG9wdGlvbnNTdHJpbmdpZnksXG4gIHByaW50TG9nbyxcbiAgcHJpbnRVc2FnZSxcbiAgcm91bmROdW1iZXIsXG4gIHRvQm9vbGVhbixcbiAgd3JhcEFyb3VuZCxcbiAgbWVhc3VyZVRpbWVcbn07XG4iLCIvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuXG5IaWdoY2hhcnRzIEV4cG9ydCBTZXJ2ZXJcblxuQ29weXJpZ2h0IChjKSAyMDE2LTIwMjQsIEhpZ2hzb2Z0XG5cbkxpY2VuY2VkIHVuZGVyIHRoZSBNSVQgbGljZW5jZS5cblxuQWRkaXRpb25hbGx5IGEgdmFsaWQgSGlnaGNoYXJ0cyBsaWNlbnNlIGlzIHJlcXVpcmVkIGZvciB1c2UuXG5cblNlZSBMSUNFTlNFIGZpbGUgaW4gcm9vdCBmb3IgZGV0YWlscy5cblxuKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuaW1wb3J0IHsgZXhpc3RzU3luYywgcmVhZEZpbGVTeW5jLCBwcm9taXNlcyBhcyBmc1Byb21pc2VzIH0gZnJvbSAnZnMnO1xuXG5pbXBvcnQgcHJvbXB0cyBmcm9tICdwcm9tcHRzJztcblxuaW1wb3J0IHtcbiAgYWJzb2x1dGVQcm9wcyxcbiAgZGVmYXVsdENvbmZpZyxcbiAgbmVzdGVkQXJncyxcbiAgcHJvbXB0c0NvbmZpZ1xufSBmcm9tICcuL3NjaGVtYXMvY29uZmlnLmpzJztcbmltcG9ydCB7IGVudnMgfSBmcm9tICcuL2VudnMuanMnO1xuaW1wb3J0IHsgbG9nLCBsb2dXaXRoU3RhY2sgfSBmcm9tICcuL2xvZ2dlci5qcyc7XG5pbXBvcnQgeyBkZWVwQ29weSwgaXNPYmplY3QsIHByaW50VXNhZ2UsIHRvQm9vbGVhbiB9IGZyb20gJy4vdXRpbHMuanMnO1xuXG5sZXQgZ2VuZXJhbE9wdGlvbnMgPSB7fTtcblxuLyoqXG4gKiBSZXRyaWV2ZXMgYW5kIHJldHVybnMgdGhlIGdlbmVyYWwgb3B0aW9ucyBmb3IgdGhlIGV4cG9ydCBwcm9jZXNzLlxuICpcbiAqIEByZXR1cm5zIHtPYmplY3R9IFRoZSBnZW5lcmFsIG9wdGlvbnMgb2JqZWN0LlxuICovXG5leHBvcnQgY29uc3QgZ2V0T3B0aW9ucyA9ICgpID0+IGdlbmVyYWxPcHRpb25zO1xuXG4vKipcbiAqIEluaXRpYWxpemVzIGFuZCBzZXRzIHRoZSBnZW5lcmFsIG9wdGlvbnMgZm9yIHRoZSBzZXJ2ZXIgaW5zdGFjZSwga2VlcGluZ1xuICogdGhlIHByaW5jaXBsZSBvZiB0aGUgb3B0aW9ucyBsb2FkIHByaW9yaXR5LiBJdCBhY2NlcHRzIG9wdGlvbmFsIHVzZXJPcHRpb25zXG4gKiBhbmQgYXJncyBmcm9tIHRoZSBDTEkuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHVzZXJPcHRpb25zIC0gVXNlci1wcm92aWRlZCBvcHRpb25zIGZvciBjdXN0b21pemF0aW9uLlxuICogQHBhcmFtIHtBcnJheX0gYXJncyAtIENvbW1hbmQtbGluZSBhcmd1bWVudHMgZm9yIGFkZGl0aW9uYWwgY29uZmlndXJhdGlvblxuICogKENMSSB1c2FnZSkuXG4gKlxuICogQHJldHVybnMge09iamVjdH0gVGhlIHVwZGF0ZWQgZ2VuZXJhbCBvcHRpb25zIG9iamVjdC5cbiAqL1xuZXhwb3J0IGNvbnN0IHNldE9wdGlvbnMgPSAodXNlck9wdGlvbnMsIGFyZ3MpID0+IHtcbiAgLy8gT25seSBmb3IgdGhlIENMSSB1c2FnZVxuICBpZiAoYXJncz8ubGVuZ3RoKSB7XG4gICAgLy8gR2V0IHRoZSBhZGRpdGlvbmFsIG9wdGlvbnMgZnJvbSB0aGUgY3VzdG9tIEpTT04gZmlsZVxuICAgIGdlbmVyYWxPcHRpb25zID0gbG9hZENvbmZpZ0ZpbGUoYXJncyk7XG4gIH1cblxuICAvLyBVcGRhdGUgdGhlIGRlZmF1bHQgY29uZmlnIHdpdGggYSBjb3JyZWN0IG9wdGlvbiB2YWx1ZXNcbiAgdXBkYXRlRGVmYXVsdENvbmZpZyhkZWZhdWx0Q29uZmlnLCBnZW5lcmFsT3B0aW9ucyk7XG5cbiAgLy8gU2V0IHZhbHVlcyBmb3Igc2VydmVyJ3Mgb3B0aW9ucyBhbmQgcmV0dXJucyB0aGVtXG4gIGdlbmVyYWxPcHRpb25zID0gaW5pdE9wdGlvbnMoZGVmYXVsdENvbmZpZyk7XG5cbiAgLy8gQXBwbHkgdXNlciBvcHRpb25zIGlmIHRoZXJlIGFyZSBhbnlcbiAgaWYgKHVzZXJPcHRpb25zKSB7XG4gICAgLy8gTWVyZ2UgdXNlciBvcHRpb25zXG4gICAgZ2VuZXJhbE9wdGlvbnMgPSBtZXJnZUNvbmZpZ09wdGlvbnMoXG4gICAgICBnZW5lcmFsT3B0aW9ucyxcbiAgICAgIHVzZXJPcHRpb25zLFxuICAgICAgYWJzb2x1dGVQcm9wc1xuICAgICk7XG4gIH1cblxuICAvLyBPbmx5IGZvciB0aGUgQ0xJIHVzYWdlXG4gIGlmIChhcmdzPy5sZW5ndGgpIHtcbiAgICAvLyBQYWlyIHByb3ZpZGVkIGFyZ3VtZW50c1xuICAgIGdlbmVyYWxPcHRpb25zID0gcGFpckFyZ3VtZW50VmFsdWUoZ2VuZXJhbE9wdGlvbnMsIGFyZ3MsIGRlZmF1bHRDb25maWcpO1xuICB9XG5cbiAgLy8gUmV0dXJuIGZpbmFsIGdlbmVyYWwgb3B0aW9uc1xuICByZXR1cm4gZ2VuZXJhbE9wdGlvbnM7XG59O1xuXG4vKipcbiAqIEFsbG93cyBtYW51YWwgY29uZmlndXJhdGlvbiBiYXNlZCBvbiBzcGVjaWZpZWQgcHJvbXB0cyBhbmQgc2F2ZXNcbiAqIHRoZSBjb25maWd1cmF0aW9uIHRvIGEgZmlsZS5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gY29uZmlnRmlsZU5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgY29uZmlndXJhdGlvbiBmaWxlLlxuICpcbiAqIEByZXR1cm5zIHtQcm9taXNlPGJvb2xlYW4+fSBBIFByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0cnVlIG9uY2UgdGhlIG1hbnVhbFxuICogY29uZmlndXJhdGlvbiBpcyBjb21wbGV0ZWQgYW5kIHNhdmVkLlxuICovXG5leHBvcnQgY29uc3QgbWFudWFsQ29uZmlnID0gYXN5bmMgKGNvbmZpZ0ZpbGVOYW1lKSA9PiB7XG4gIC8vIFByZXBhcmUgYSBjb25maWcgb2JqZWN0XG4gIGxldCBjb25maWdGaWxlID0ge307XG5cbiAgLy8gQ2hlY2sgaWYgcHJvdmlkZWQgY29uZmlnIGZpbGUgZXhpc3RzXG4gIGlmIChleGlzdHNTeW5jKGNvbmZpZ0ZpbGVOYW1lKSkge1xuICAgIGNvbmZpZ0ZpbGUgPSBKU09OLnBhcnNlKHJlYWRGaWxlU3luYyhjb25maWdGaWxlTmFtZSwgJ3V0ZjgnKSk7XG4gIH1cblxuICAvLyBRdWVzdGlvbiBhYm91dCBhIGNvbmZpZ3VyYXRpb24gY2F0ZWdvcnlcbiAgY29uc3Qgb25TdWJtaXQgPSBhc3luYyAocCwgY2F0ZWdvcmllcykgPT4ge1xuICAgIGxldCBxdWVzdGlvbnNDb3VudGVyID0gMDtcbiAgICBsZXQgYWxsUXVlc3Rpb25zID0gW107XG5cbiAgICAvLyBDcmVhdGUgYSBjb3JyZXNwb25kaW5nIHByb3BlcnR5IGluIHRoZSBtYW51YWxDb25maWcgb2JqZWN0XG4gICAgZm9yIChjb25zdCBzZWN0aW9uIG9mIGNhdGVnb3JpZXMpIHtcbiAgICAgIC8vIE1hcmsgZWFjaCBvcHRpb24gd2l0aCBhIHNlY3Rpb25cbiAgICAgIHByb21wdHNDb25maWdbc2VjdGlvbl0gPSBwcm9tcHRzQ29uZmlnW3NlY3Rpb25dLm1hcCgob3B0aW9uKSA9PiAoe1xuICAgICAgICAuLi5vcHRpb24sXG4gICAgICAgIHNlY3Rpb25cbiAgICAgIH0pKTtcblxuICAgICAgLy8gQ29sbGVjdCB0aGUgcXVlc3Rpb25zXG4gICAgICBhbGxRdWVzdGlvbnMgPSBbLi4uYWxsUXVlc3Rpb25zLCAuLi5wcm9tcHRzQ29uZmlnW3NlY3Rpb25dXTtcbiAgICB9XG5cbiAgICBhd2FpdCBwcm9tcHRzKGFsbFF1ZXN0aW9ucywge1xuICAgICAgb25TdWJtaXQ6IGFzeW5jIChwcm9tcHQsIGFuc3dlcikgPT4ge1xuICAgICAgICAvLyBHZXQgdGhlIGRlZmF1bHQgbW9kdWxlIHNjcmlwdHNcbiAgICAgICAgaWYgKHByb21wdC5uYW1lID09PSAnbW9kdWxlU2NyaXB0cycpIHtcbiAgICAgICAgICBhbnN3ZXIgPSBhbnN3ZXIubGVuZ3RoXG4gICAgICAgICAgICA/IGFuc3dlci5tYXAoKG1vZHVsZSkgPT4gcHJvbXB0LmNob2ljZXNbbW9kdWxlXSlcbiAgICAgICAgICAgIDogcHJvbXB0LmNob2ljZXM7XG5cbiAgICAgICAgICBjb25maWdGaWxlW3Byb21wdC5zZWN0aW9uXVtwcm9tcHQubmFtZV0gPSBhbnN3ZXI7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uZmlnRmlsZVtwcm9tcHQuc2VjdGlvbl0gPSByZWN1cnNpdmVQcm9wcyhcbiAgICAgICAgICAgIE9iamVjdC5hc3NpZ24oe30sIGNvbmZpZ0ZpbGVbcHJvbXB0LnNlY3Rpb25dIHx8IHt9KSxcbiAgICAgICAgICAgIHByb21wdC5uYW1lLnNwbGl0KCcuJyksXG4gICAgICAgICAgICBwcm9tcHQuY2hvaWNlcyA/IHByb21wdC5jaG9pY2VzW2Fuc3dlcl0gOiBhbnN3ZXJcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCsrcXVlc3Rpb25zQ291bnRlciA9PT0gYWxsUXVlc3Rpb25zLmxlbmd0aCkge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhd2FpdCBmc1Byb21pc2VzLndyaXRlRmlsZShcbiAgICAgICAgICAgICAgY29uZmlnRmlsZU5hbWUsXG4gICAgICAgICAgICAgIEpTT04uc3RyaW5naWZ5KGNvbmZpZ0ZpbGUsIG51bGwsIDIpLFxuICAgICAgICAgICAgICAndXRmOCdcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGxvZ1dpdGhTdGFjayhcbiAgICAgICAgICAgICAgMSxcbiAgICAgICAgICAgICAgZXJyb3IsXG4gICAgICAgICAgICAgIGBbY29uZmlnXSBBbiBlcnJvciBvY2N1cnJlZCB3aGlsZSBjcmVhdGluZyB0aGUgJHtjb25maWdGaWxlTmFtZX0gZmlsZS5gXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHRydWU7XG4gIH07XG5cbiAgLy8gRmluZCB0aGUgY2F0ZWdvcmllc1xuICBjb25zdCBjaG9pY2VzID0gT2JqZWN0LmtleXMocHJvbXB0c0NvbmZpZykubWFwKChjaG9pY2UpID0+ICh7XG4gICAgdGl0bGU6IGAke2Nob2ljZX0gb3B0aW9uc2AsXG4gICAgdmFsdWU6IGNob2ljZVxuICB9KSk7XG5cbiAgLy8gQ2F0ZWdvcnkgcHJvbXB0XG4gIHJldHVybiBwcm9tcHRzKFxuICAgIHtcbiAgICAgIHR5cGU6ICdtdWx0aXNlbGVjdCcsXG4gICAgICBuYW1lOiAnY2F0ZWdvcnknLFxuICAgICAgbWVzc2FnZTogJ1doaWNoIGNhdGVnb3J5IGRvIHlvdSB3YW50IHRvIGNvbmZpZ3VyZT8nLFxuICAgICAgaGludDogJ1NwYWNlOiBTZWxlY3Qgc3BlY2lmaWMsIEE6IFNlbGVjdCBhbGwsIEVudGVyOiBDb25maXJtLicsXG4gICAgICBpbnN0cnVjdGlvbnM6ICcnLFxuICAgICAgY2hvaWNlc1xuICAgIH0sXG4gICAgeyBvblN1Ym1pdCB9XG4gICk7XG59O1xuXG4vKipcbiAqIE1hcHMgb2xkLXN0cnVjdHVyZWQgKFBoYW50b21KUykgb3B0aW9ucyB0byBhIG5ldyBjb25maWd1cmF0aW9uIGZvcm1hdFxuICogKFB1cHBldGVlcikuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9sZE9wdGlvbnMgLSBPbGQtc3RydWN0dXJlZCBvcHRpb25zIHRvIGJlIG1hcHBlZC5cbiAqXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBOZXcgb3B0aW9ucyBzdHJ1Y3R1cmVkIGJhc2VkIG9uIHRoZSBkZWZpbmVkIG5lc3RlZEFyZ3NcbiAqIG1hcHBpbmcuXG4gKi9cbmV4cG9ydCBjb25zdCBtYXBUb05ld0NvbmZpZyA9IChvbGRPcHRpb25zKSA9PiB7XG4gIGNvbnN0IG5ld09wdGlvbnMgPSB7fTtcbiAgLy8gQ3ljbGUgdGhyb3VnaCBvbGQtc3RydWN0dXJlZCBvcHRpb25zXG4gIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKG9sZE9wdGlvbnMpKSB7XG4gICAgY29uc3QgcHJvcGVydGllc0NoYWluID0gbmVzdGVkQXJnc1trZXldID8gbmVzdGVkQXJnc1trZXldLnNwbGl0KCcuJykgOiBbXTtcblxuICAgIC8vIFBvcHVsYXRlIG9iamVjdCBpbiBjb3JyZWN0IHByb3BlcnRpZXMgbGV2ZWxzXG4gICAgcHJvcGVydGllc0NoYWluLnJlZHVjZShcbiAgICAgIChvYmosIHByb3AsIGluZGV4KSA9PlxuICAgICAgICAob2JqW3Byb3BdID1cbiAgICAgICAgICBwcm9wZXJ0aWVzQ2hhaW4ubGVuZ3RoIC0gMSA9PT0gaW5kZXggPyB2YWx1ZSA6IG9ialtwcm9wXSB8fCB7fSksXG4gICAgICBuZXdPcHRpb25zXG4gICAgKTtcbiAgfVxuICByZXR1cm4gbmV3T3B0aW9ucztcbn07XG5cbi8qKlxuICogTWVyZ2VzIHR3byBzZXRzIG9mIGNvbmZpZ3VyYXRpb24gb3B0aW9ucywgY29uc2lkZXJpbmcgYWJzb2x1dGUgcHJvcGVydGllcy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIE9yaWdpbmFsIGNvbmZpZ3VyYXRpb24gb3B0aW9ucy5cbiAqIEBwYXJhbSB7T2JqZWN0fSBuZXdPcHRpb25zIC0gTmV3IGNvbmZpZ3VyYXRpb24gb3B0aW9ucyB0byBiZSBtZXJnZWQuXG4gKiBAcGFyYW0ge0FycmF5fSBhYnNvbHV0ZVByb3BzIC0gTGlzdCBvZiBwcm9wZXJ0aWVzIHRoYXQgc2hvdWxkXG4gKiBub3QgYmUgcmVjdXJzaXZlbHkgbWVyZ2VkLlxuICpcbiAqIEByZXR1cm5zIHtPYmplY3R9IE1lcmdlZCBjb25maWd1cmF0aW9uIG9wdGlvbnMuXG4gKi9cbmV4cG9ydCBjb25zdCBtZXJnZUNvbmZpZ09wdGlvbnMgPSAob3B0aW9ucywgbmV3T3B0aW9ucywgYWJzb2x1dGVQcm9wcyA9IFtdKSA9PiB7XG4gIGNvbnN0IG1lcmdlZE9wdGlvbnMgPSBkZWVwQ29weShvcHRpb25zKTtcblxuICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhuZXdPcHRpb25zKSkge1xuICAgIG1lcmdlZE9wdGlvbnNba2V5XSA9XG4gICAgICBpc09iamVjdCh2YWx1ZSkgJiZcbiAgICAgICFhYnNvbHV0ZVByb3BzLmluY2x1ZGVzKGtleSkgJiZcbiAgICAgIG1lcmdlZE9wdGlvbnNba2V5XSAhPT0gdW5kZWZpbmVkXG4gICAgICAgID8gbWVyZ2VDb25maWdPcHRpb25zKG1lcmdlZE9wdGlvbnNba2V5XSwgdmFsdWUsIGFic29sdXRlUHJvcHMpXG4gICAgICAgIDogdmFsdWUgIT09IHVuZGVmaW5lZFxuICAgICAgICAgID8gdmFsdWVcbiAgICAgICAgICA6IG1lcmdlZE9wdGlvbnNba2V5XTtcbiAgfVxuXG4gIHJldHVybiBtZXJnZWRPcHRpb25zO1xufTtcblxuLyoqXG4gKiBJbml0aWFsaXplcyBleHBvcnQgc2V0dGluZ3MgYmFzZWQgb24gcHJvdmlkZWQgZXhwb3J0T3B0aW9uc1xuICogYW5kIGdlbmVyYWxPcHRpb25zLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBleHBvcnRPcHRpb25zIC0gT3B0aW9ucyBzcGVjaWZpYyB0byB0aGUgZXhwb3J0IHByb2Nlc3MuXG4gKiBAcGFyYW0ge09iamVjdH0gZ2VuZXJhbE9wdGlvbnMgLSBHZW5lcmFsIGNvbmZpZ3VyYXRpb24gb3B0aW9ucy5cbiAqXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBJbml0aWFsaXplZCBleHBvcnQgc2V0dGluZ3MuXG4gKi9cbmV4cG9ydCBjb25zdCBpbml0RXhwb3J0U2V0dGluZ3MgPSAoZXhwb3J0T3B0aW9ucywgZ2VuZXJhbE9wdGlvbnMgPSB7fSkgPT4ge1xuICBsZXQgb3B0aW9ucyA9IHt9O1xuXG4gIGlmIChleHBvcnRPcHRpb25zLnN2Zykge1xuICAgIG9wdGlvbnMgPSBkZWVwQ29weShnZW5lcmFsT3B0aW9ucyk7XG4gICAgb3B0aW9ucy5leHBvcnQudHlwZSA9IGV4cG9ydE9wdGlvbnMudHlwZSB8fCBleHBvcnRPcHRpb25zLmV4cG9ydC50eXBlO1xuICAgIG9wdGlvbnMuZXhwb3J0LnNjYWxlID0gZXhwb3J0T3B0aW9ucy5zY2FsZSB8fCBleHBvcnRPcHRpb25zLmV4cG9ydC5zY2FsZTtcbiAgICBvcHRpb25zLmV4cG9ydC5vdXRmaWxlID1cbiAgICAgIGV4cG9ydE9wdGlvbnMub3V0ZmlsZSB8fCBleHBvcnRPcHRpb25zLmV4cG9ydC5vdXRmaWxlO1xuICAgIG9wdGlvbnMucGF5bG9hZCA9IHtcbiAgICAgIHN2ZzogZXhwb3J0T3B0aW9ucy5zdmdcbiAgICB9O1xuICB9IGVsc2Uge1xuICAgIG9wdGlvbnMgPSBtZXJnZUNvbmZpZ09wdGlvbnMoXG4gICAgICBnZW5lcmFsT3B0aW9ucyxcbiAgICAgIGV4cG9ydE9wdGlvbnMsXG4gICAgICAvLyBPbWl0IGdvaW5nIGRvd24gcmVjdXJzaXZlbHkgd2l0aCB0aGUgYmVsb3dzXG4gICAgICBhYnNvbHV0ZVByb3BzXG4gICAgKTtcbiAgfVxuXG4gIG9wdGlvbnMuZXhwb3J0Lm91dGZpbGUgPVxuICAgIG9wdGlvbnMuZXhwb3J0Py5vdXRmaWxlIHx8IGBjaGFydC4ke29wdGlvbnMuZXhwb3J0Py50eXBlIHx8ICdwbmcnfWA7XG4gIHJldHVybiBvcHRpb25zO1xufTtcblxuLyoqXG4gKiBMb2FkcyBhZGRpdGlvbmFsIGNvbmZpZ3VyYXRpb24gZnJvbSBhIHNwZWNpZmllZCBmaWxlIHVzaW5nXG4gKiB0aGUgLS1sb2FkQ29uZmlnIG9wdGlvbi5cbiAqXG4gKiBAcGFyYW0ge0FycmF5fSBhcmdzIC0gQ29tbWFuZC1saW5lIGFyZ3VtZW50cyB0byBjaGVjayBmb3JcbiAqIHRoZSAtLWxvYWRDb25maWcgb3B0aW9uLlxuICpcbiAqIEByZXR1cm5zIHtPYmplY3R9IEFkZGl0aW9uYWwgY29uZmlndXJhdGlvbiBsb2FkZWQgZnJvbSB0aGUgc3BlY2lmaWVkIGZpbGUsXG4gKiBvciBhbiBlbXB0eSBvYmplY3QgaWYgbm90IGZvdW5kIG9yIGludmFsaWQuXG4gKi9cbmZ1bmN0aW9uIGxvYWRDb25maWdGaWxlKGFyZ3MpIHtcbiAgLy8gQ2hlY2sgaWYgdGhlIC0tbG9hZENvbmZpZyBvcHRpb24gd2FzIHVzZWRcbiAgY29uc3QgY29uZmlnSW5kZXggPSBhcmdzLmZpbmRJbmRleChcbiAgICAoYXJnKSA9PiBhcmcucmVwbGFjZSgvLS9nLCAnJykgPT09ICdsb2FkQ29uZmlnJ1xuICApO1xuXG4gIC8vIENoZWNrIGlmIHRoZSAtLWxvYWRDb25maWcgaGFzIGEgdmFsdWVcbiAgaWYgKGNvbmZpZ0luZGV4ID4gLTEgJiYgYXJnc1tjb25maWdJbmRleCArIDFdKSB7XG4gICAgY29uc3QgZmlsZU5hbWUgPSBhcmdzW2NvbmZpZ0luZGV4ICsgMV07XG4gICAgdHJ5IHtcbiAgICAgIC8vIENoZWNrIGlmIGFuIGFkZGl0aW9uYWwgY29uZmlnIGZpbGUgaXMgYSBjb3JyZWN0IEpTT04gZmlsZVxuICAgICAgaWYgKGZpbGVOYW1lICYmIGZpbGVOYW1lLmVuZHNXaXRoKCcuanNvbicpKSB7XG4gICAgICAgIC8vIExvYWQgYW4gb3B0aW9uYWwgY3VzdG9tIEpTT04gY29uZmlnIGZpbGVcbiAgICAgICAgcmV0dXJuIEpTT04ucGFyc2UocmVhZEZpbGVTeW5jKGZpbGVOYW1lKSk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ1dpdGhTdGFjayhcbiAgICAgICAgMixcbiAgICAgICAgZXJyb3IsXG4gICAgICAgIGBbY29uZmlnXSBVbmFibGUgdG8gbG9hZCB0aGUgY29uZmlndXJhdGlvbiBmcm9tIHRoZSAke2ZpbGVOYW1lfSBmaWxlLmBcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLy8gTm8gYWRkaXRpb25hbCBvcHRpb25zIHRvIHJldHVyblxuICByZXR1cm4ge307XG59XG5cbi8qKlxuICogVXBkYXRlcyB0aGUgZGVmYXVsdCBjb25maWd1cmF0aW9uIG9iamVjdCB3aXRoIHZhbHVlcyBmcm9tIGEgY3VzdG9tIG9iamVjdFxuICogYW5kIGVudmlyb25tZW50IHZhcmlhYmxlcy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gY29uZmlnT2JqIC0gVGhlIGRlZmF1bHQgY29uZmlndXJhdGlvbiBvYmplY3QuXG4gKiBAcGFyYW0ge09iamVjdH0gY3VzdG9tT2JqIC0gQ3VzdG9tIGNvbmZpZ3VyYXRpb24gb2JqZWN0IHRvIG92ZXJyaWRlIGRlZmF1bHRzLlxuICogQHBhcmFtIHtzdHJpbmd9IHByb3BDaGFpbiAtIFByb3BlcnR5IGNoYWluIGZvciB0cmFja2luZyBuZXN0ZWQgcHJvcGVydGllc1xuICogZHVyaW5nIHJlY3Vyc2lvbi5cbiAqL1xuZnVuY3Rpb24gdXBkYXRlRGVmYXVsdENvbmZpZyhjb25maWdPYmosIGN1c3RvbU9iaiA9IHt9LCBwcm9wQ2hhaW4gPSAnJykge1xuICBPYmplY3Qua2V5cyhjb25maWdPYmopLmZvckVhY2goKGtleSkgPT4ge1xuICAgIGNvbnN0IGVudHJ5ID0gY29uZmlnT2JqW2tleV07XG4gICAgY29uc3QgY3VzdG9tVmFsdWUgPSBjdXN0b21PYmogJiYgY3VzdG9tT2JqW2tleV07XG5cbiAgICBpZiAodHlwZW9mIGVudHJ5LnZhbHVlID09PSAndW5kZWZpbmVkJykge1xuICAgICAgdXBkYXRlRGVmYXVsdENvbmZpZyhlbnRyeSwgY3VzdG9tVmFsdWUsIGAke3Byb3BDaGFpbn0uJHtrZXl9YCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIElmIGEgdmFsdWUgZnJvbSBhIGN1c3RvbSBKU09OIGV4aXN0cywgaXQgdGFrZSBwcmVjZWRlbmNlXG4gICAgICBpZiAoY3VzdG9tVmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBlbnRyeS52YWx1ZSA9IGN1c3RvbVZhbHVlO1xuICAgICAgfVxuXG4gICAgICAvLyBJZiBhIHZhbHVlIGZyb20gYW4gZW52IHZhcmlhYmxlIGV4aXN0cywgaXQgdGFrZSBwcmVjZWRlbmNlXG4gICAgICBpZiAoZW50cnkuZW52TGluayBpbiBlbnZzICYmIGVudnNbZW50cnkuZW52TGlua10gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBlbnRyeS52YWx1ZSA9IGVudnNbZW50cnkuZW52TGlua107XG4gICAgICB9XG4gICAgfVxuICB9KTtcbn1cblxuLyoqXG4gKiBJbml0aWFsaXplcyBvcHRpb25zIG9iamVjdCBiYXNlZCBvbiBwcm92aWRlZCBpdGVtcywgc2V0dGluZyB2YWx1ZXMgZnJvbVxuICogbmVzdGVkIHByb3BlcnRpZXMgcmVjdXJzaXZlbHkuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGl0ZW1zIC0gQ29uZmlndXJhdGlvbiBpdGVtcyB0byBiZSB1c2VkIGZvciBpbml0aWFsaXppbmdcbiAqIG9wdGlvbnMuXG4gKlxuICogQHJldHVybnMge09iamVjdH0gSW5pdGlhbGl6ZWQgb3B0aW9ucyBvYmplY3QuXG4gKi9cbmZ1bmN0aW9uIGluaXRPcHRpb25zKGl0ZW1zKSB7XG4gIGxldCBvcHRpb25zID0ge307XG4gIGZvciAoY29uc3QgW25hbWUsIGl0ZW1dIG9mIE9iamVjdC5lbnRyaWVzKGl0ZW1zKSkge1xuICAgIG9wdGlvbnNbbmFtZV0gPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoaXRlbSwgJ3ZhbHVlJylcbiAgICAgID8gaXRlbS52YWx1ZVxuICAgICAgOiBpbml0T3B0aW9ucyhpdGVtKTtcbiAgfVxuICByZXR1cm4gb3B0aW9ucztcbn1cblxuLyoqXG4gKiBQYWlycyBhcmd1bWVudCB2YWx1ZXMgd2l0aCBjb3JyZXNwb25kaW5nIG9wdGlvbnMgaW4gdGhlIGNvbmZpZ3VyYXRpb24sXG4gKiB1cGRhdGluZyB0aGUgb3B0aW9ucyBvYmplY3QuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgLSBDb25maWd1cmF0aW9uIG9wdGlvbnMgb2JqZWN0IHRvIGJlIHVwZGF0ZWQuXG4gKiBAcGFyYW0ge0FycmF5fSBhcmdzIC0gQ29tbWFuZC1saW5lIGFyZ3VtZW50cyBjb250YWluaW5nIHZhbHVlcyBmb3Igc3BlY2lmaWNcbiAqIG9wdGlvbnMuXG4gKiBAcGFyYW0ge09iamVjdH0gZGVmYXVsdENvbmZpZyAtIERlZmF1bHQgY29uZmlndXJhdGlvbiBvYmplY3QgZm9yIHJlZmVyZW5jZS5cbiAqXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBVcGRhdGVkIG9wdGlvbnMgb2JqZWN0LlxuICovXG5mdW5jdGlvbiBwYWlyQXJndW1lbnRWYWx1ZShvcHRpb25zLCBhcmdzLCBkZWZhdWx0Q29uZmlnKSB7XG4gIGxldCBzaG93VXNhZ2UgPSBmYWxzZTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBhcmdzLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3Qgb3B0aW9uID0gYXJnc1tpXS5yZXBsYWNlKC8tL2csICcnKTtcblxuICAgIC8vIEZpbmQgdGhlIHJpZ2h0IHBsYWNlIGZvciBwcm9wZXJ0eSdzIHZhbHVlXG4gICAgY29uc3QgcHJvcGVydGllc0NoYWluID0gbmVzdGVkQXJnc1tvcHRpb25dXG4gICAgICA/IG5lc3RlZEFyZ3Nbb3B0aW9uXS5zcGxpdCgnLicpXG4gICAgICA6IFtdO1xuXG4gICAgLy8gR2V0IHRoZSBjb3JyZWN0IHR5cGUgZm9yIENMSSBhcmdzIHdoaWNoIGFyZSBwYXNzZWQgYXMgc3RyaW5nc1xuICAgIGxldCBhcmd1bWVudFR5cGU7XG4gICAgcHJvcGVydGllc0NoYWluLnJlZHVjZSgob2JqLCBwcm9wLCBpbmRleCkgPT4ge1xuICAgICAgaWYgKHByb3BlcnRpZXNDaGFpbi5sZW5ndGggLSAxID09PSBpbmRleCkge1xuICAgICAgICBhcmd1bWVudFR5cGUgPSBvYmpbcHJvcF0udHlwZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBvYmpbcHJvcF07XG4gICAgfSwgZGVmYXVsdENvbmZpZyk7XG5cbiAgICBwcm9wZXJ0aWVzQ2hhaW4ucmVkdWNlKChvYmosIHByb3AsIGluZGV4KSA9PiB7XG4gICAgICBpZiAocHJvcGVydGllc0NoYWluLmxlbmd0aCAtIDEgPT09IGluZGV4KSB7XG4gICAgICAgIC8vIEZpbmRzIGFuIG9wdGlvbiBhbmQgc2V0IGEgY29ycmVzcG9uZGluZyB2YWx1ZVxuICAgICAgICBpZiAodHlwZW9mIG9ialtwcm9wXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICBpZiAoYXJnc1srK2ldKSB7XG4gICAgICAgICAgICBpZiAoYXJndW1lbnRUeXBlID09PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICAgICAgb2JqW3Byb3BdID0gdG9Cb29sZWFuKGFyZ3NbaV0pO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChhcmd1bWVudFR5cGUgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICAgIG9ialtwcm9wXSA9ICthcmdzW2ldO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChhcmd1bWVudFR5cGUuaW5kZXhPZignXScpID49IDApIHtcbiAgICAgICAgICAgICAgb2JqW3Byb3BdID0gYXJnc1tpXS5zcGxpdCgnLCcpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgb2JqW3Byb3BdID0gYXJnc1tpXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbG9nKFxuICAgICAgICAgICAgICAyLFxuICAgICAgICAgICAgICBgW2NvbmZpZ10gTWlzc2luZyB2YWx1ZSBmb3IgdGhlICcke29wdGlvbn0nIGFyZ3VtZW50LiBVc2luZyB0aGUgZGVmYXVsdCB2YWx1ZS5gXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgc2hvd1VzYWdlID0gdHJ1ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBvYmpbcHJvcF07XG4gICAgfSwgb3B0aW9ucyk7XG4gIH1cblxuICAvLyBEaXNwbGF5IHRoZSB1c2FnZSBmb3IgdGhlIHJlZmVyZW5jZSBpZiBuZWVkZWRcbiAgaWYgKHNob3dVc2FnZSkge1xuICAgIHByaW50VXNhZ2UoZGVmYXVsdENvbmZpZyk7XG4gIH1cblxuICByZXR1cm4gb3B0aW9ucztcbn1cblxuLyoqXG4gKiBSZWN1cnNpdmVseSB1cGRhdGVzIHByb3BlcnRpZXMgaW4gYW4gb2JqZWN0IGJhc2VkIG9uIG5lc3RlZCBuYW1lcyBhbmQgYXNzaWduc1xuICogdGhlIGZpbmFsIHZhbHVlLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RUb1VwZGF0ZSAtIFRoZSBvYmplY3QgdG8gYmUgdXBkYXRlZC5cbiAqIEBwYXJhbSB7QXJyYXl9IG5lc3RlZE5hbWVzIC0gQXJyYXkgb2YgbmVzdGVkIHByb3BlcnR5IG5hbWVzLlxuICogQHBhcmFtIHthbnl9IHZhbHVlIC0gVGhlIGZpbmFsIHZhbHVlIHRvIGJlIGFzc2lnbmVkLlxuICpcbiAqIEByZXR1cm5zIHtPYmplY3R9IFVwZGF0ZWQgb2JqZWN0IHdpdGggYXNzaWduZWQgdmFsdWVzLlxuICovXG5mdW5jdGlvbiByZWN1cnNpdmVQcm9wcyhvYmplY3RUb1VwZGF0ZSwgbmVzdGVkTmFtZXMsIHZhbHVlKSB7XG4gIHdoaWxlIChuZXN0ZWROYW1lcy5sZW5ndGggPiAxKSB7XG4gICAgY29uc3QgcHJvcE5hbWUgPSBuZXN0ZWROYW1lcy5zaGlmdCgpO1xuXG4gICAgLy8gQ3JlYXRlIGEgcHJvcGVydHkgaW4gb2JqZWN0IGlmIGl0IGRvZXNuJ3QgZXhpc3RcbiAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3RUb1VwZGF0ZSwgcHJvcE5hbWUpKSB7XG4gICAgICBvYmplY3RUb1VwZGF0ZVtwcm9wTmFtZV0gPSB7fTtcbiAgICB9XG5cbiAgICAvLyBDYWxsIGZ1bmN0aW9uIGFnYWluIGlmIHRoZXJlIHN0aWxsIG5hbWVzIHRvIGdvXG4gICAgb2JqZWN0VG9VcGRhdGVbcHJvcE5hbWVdID0gcmVjdXJzaXZlUHJvcHMoXG4gICAgICBPYmplY3QuYXNzaWduKHt9LCBvYmplY3RUb1VwZGF0ZVtwcm9wTmFtZV0pLFxuICAgICAgbmVzdGVkTmFtZXMsXG4gICAgICB2YWx1ZVxuICAgICk7XG5cbiAgICByZXR1cm4gb2JqZWN0VG9VcGRhdGU7XG4gIH1cblxuICAvLyBBc3NpZ24gdGhlIGZpbmFsIHZhbHVlXG4gIG9iamVjdFRvVXBkYXRlW25lc3RlZE5hbWVzWzBdXSA9IHZhbHVlO1xuICByZXR1cm4gb2JqZWN0VG9VcGRhdGU7XG59XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgZ2V0T3B0aW9ucyxcbiAgc2V0T3B0aW9ucyxcbiAgbWFudWFsQ29uZmlnLFxuICBtYXBUb05ld0NvbmZpZyxcbiAgbWVyZ2VDb25maWdPcHRpb25zLFxuICBpbml0RXhwb3J0U2V0dGluZ3Ncbn07XG4iLCIvKipcbiAqIFRoaXMgbW9kdWxlIGV4cG9ydHMgdHdvIGZ1bmN0aW9uczogZmV0Y2ggKGZvciBHRVQgcmVxdWVzdHMpIGFuZCBwb3N0IChmb3IgUE9TVCByZXF1ZXN0cykuXG4gKi9cblxuaW1wb3J0IGh0dHAgZnJvbSAnaHR0cCc7XG5pbXBvcnQgaHR0cHMgZnJvbSAnaHR0cHMnO1xuXG4vKipcbiAqIFJldHVybnMgdGhlIEhUVFAgb3IgSFRUUFMgcHJvdG9jb2wgbW9kdWxlIGJhc2VkIG9uIHRoZSBwcm92aWRlZCBVUkwuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHVybCAtIFRoZSBVUkwgdG8gZGV0ZXJtaW5lIHRoZSBwcm90b2NvbC5cbiAqXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBUaGUgSFRUUCBvciBIVFRQUyBwcm90b2NvbCBtb2R1bGUgKGh0dHAgb3IgaHR0cHMpLlxuICovXG5jb25zdCBnZXRQcm90b2NvbCA9ICh1cmwpID0+ICh1cmwuc3RhcnRzV2l0aCgnaHR0cHMnKSA/IGh0dHBzIDogaHR0cCk7XG5cbi8qKlxuICogRmV0Y2hlcyBkYXRhIGZyb20gdGhlIHNwZWNpZmllZCBVUkwgdXNpbmcgZWl0aGVyIEhUVFAgb3IgSFRUUFMgcHJvdG9jb2wuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHVybCAtIFRoZSBVUkwgdG8gZmV0Y2ggZGF0YSBmcm9tLlxuICogQHBhcmFtIHtPYmplY3R9IHJlcXVlc3RPcHRpb25zIC0gT3B0aW9ucyBmb3IgdGhlIEhUVFAgcmVxdWVzdCAob3B0aW9uYWwpLlxuICpcbiAqIEByZXR1cm5zIHtQcm9taXNlPE9iamVjdD59IFByb21pc2UgcmVzb2x2aW5nIHRvIHRoZSBIVFRQIHJlc3BvbnNlIG9iamVjdFxuICogd2l0aCBhZGRlZCAndGV4dCcgcHJvcGVydHkgb3IgcmVqZWN0aW5nIHdpdGggYW4gZXJyb3IuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGZldGNoKHVybCwgcmVxdWVzdE9wdGlvbnMgPSB7fSkge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGNvbnN0IHByb3RvY29sID0gZ2V0UHJvdG9jb2wodXJsKTtcblxuICAgIHByb3RvY29sXG4gICAgICAuZ2V0KFxuICAgICAgICB1cmwsXG4gICAgICAgIE9iamVjdC5hc3NpZ24oXG4gICAgICAgICAge1xuICAgICAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICAgICAnVXNlci1BZ2VudCc6ICdoaWdoY2hhcnRzL2V4cG9ydCcsXG4gICAgICAgICAgICAgIFJlZmVyZXI6ICdoaWdoY2hhcnRzLmV4cG9ydCdcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LFxuICAgICAgICAgIHJlcXVlc3RPcHRpb25zIHx8IHt9XG4gICAgICAgICksXG4gICAgICAgIChyZXMpID0+IHtcbiAgICAgICAgICBsZXQgZGF0YSA9ICcnO1xuXG4gICAgICAgICAgLy8gQSBjaHVuayBvZiBkYXRhIGhhcyBiZWVuIHJlY2VpdmVkLlxuICAgICAgICAgIHJlcy5vbignZGF0YScsIChjaHVuaykgPT4ge1xuICAgICAgICAgICAgZGF0YSArPSBjaHVuaztcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIC8vIFRoZSB3aG9sZSByZXNwb25zZSBoYXMgYmVlbiByZWNlaXZlZC5cbiAgICAgICAgICByZXMub24oJ2VuZCcsICgpID0+IHtcbiAgICAgICAgICAgIGlmICghZGF0YSkge1xuICAgICAgICAgICAgICByZWplY3QoJ05vdGhpbmcgd2FzIGZldGNoZWQgZnJvbSB0aGUgVVJMLicpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXMudGV4dCA9IGRhdGE7XG4gICAgICAgICAgICByZXNvbHZlKHJlcyk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIClcbiAgICAgIC5vbignZXJyb3InLCAoZXJyb3IpID0+IHtcbiAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgIH0pO1xuICB9KTtcbn1cblxuLyoqXG4gKiBTZW5kcyBhIFBPU1QgcmVxdWVzdCB0byB0aGUgc3BlY2lmaWVkIFVSTCB3aXRoIHRoZSBwcm92aWRlZCBKU09OIGJvZHkgdXNpbmdcbiAqIGVpdGhlciBIVFRQIG9yIEhUVFBTIHByb3RvY29sLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB1cmwgLSBUaGUgVVJMIHRvIHNlbmQgdGhlIFBPU1QgcmVxdWVzdCB0by5cbiAqIEBwYXJhbSB7T2JqZWN0fSBib2R5IC0gVGhlIEpTT04gYm9keSB0byBpbmNsdWRlIGluIHRoZSBQT1NUIHJlcXVlc3RcbiAqIChvcHRpb25hbCwgZGVmYXVsdCBpcyBhbiBlbXB0eSBvYmplY3QpLlxuICogQHBhcmFtIHtPYmplY3R9IHJlcXVlc3RPcHRpb25zIC0gT3B0aW9ucyBmb3IgdGhlIEhUVFAgcmVxdWVzdCAob3B0aW9uYWwpLlxuICpcbiAqIEByZXR1cm5zIHtQcm9taXNlPE9iamVjdD59IFByb21pc2UgcmVzb2x2aW5nIHRvIHRoZSBIVFRQIHJlc3BvbnNlIG9iamVjdCB3aXRoXG4gKiBhZGRlZCAndGV4dCcgcHJvcGVydHkgb3IgcmVqZWN0aW5nIHdpdGggYW4gZXJyb3IuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHBvc3QodXJsLCBib2R5ID0ge30sIHJlcXVlc3RPcHRpb25zID0ge30pIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjb25zdCBwcm90b2NvbCA9IGdldFByb3RvY29sKHVybCk7XG4gICAgY29uc3QgZGF0YSA9IEpTT04uc3RyaW5naWZ5KGJvZHkpO1xuXG4gICAgLy8gU2V0IGRlZmF1bHQgaGVhZGVycyBhbmQgbWVyZ2Ugd2l0aCByZXF1ZXN0T3B0aW9uc1xuICAgIGNvbnN0IG9wdGlvbnMgPSBPYmplY3QuYXNzaWduKFxuICAgICAge1xuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICAgICAgJ0NvbnRlbnQtTGVuZ3RoJzogZGF0YS5sZW5ndGhcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIHJlcXVlc3RPcHRpb25zXG4gICAgKTtcblxuICAgIGNvbnN0IHJlcSA9IHByb3RvY29sXG4gICAgICAucmVxdWVzdCh1cmwsIG9wdGlvbnMsIChyZXMpID0+IHtcbiAgICAgICAgbGV0IHJlc3BvbnNlRGF0YSA9ICcnO1xuXG4gICAgICAgIC8vIEEgY2h1bmsgb2YgZGF0YSBoYXMgYmVlbiByZWNlaXZlZC5cbiAgICAgICAgcmVzLm9uKCdkYXRhJywgKGNodW5rKSA9PiB7XG4gICAgICAgICAgcmVzcG9uc2VEYXRhICs9IGNodW5rO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBUaGUgd2hvbGUgcmVzcG9uc2UgaGFzIGJlZW4gcmVjZWl2ZWQuXG4gICAgICAgIHJlcy5vbignZW5kJywgKCkgPT4ge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXMudGV4dCA9IHJlc3BvbnNlRGF0YTtcbiAgICAgICAgICAgIHJlc29sdmUocmVzKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSlcbiAgICAgIC5vbignZXJyb3InLCAoZXJyb3IpID0+IHtcbiAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgIH0pO1xuXG4gICAgLy8gV3JpdGUgdGhlIHJlcXVlc3QgYm9keSBhbmQgZW5kIHRoZSByZXF1ZXN0LlxuICAgIHJlcS53cml0ZShkYXRhKTtcbiAgICByZXEuZW5kKCk7XG4gIH0pO1xufVxuXG5leHBvcnQgZGVmYXVsdCBmZXRjaDtcbmV4cG9ydCB7IGZldGNoLCBwb3N0IH07XG4iLCJjbGFzcyBFeHBvcnRFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgY29uc3RydWN0b3IobWVzc2FnZSkge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy5tZXNzYWdlID0gbWVzc2FnZTtcbiAgICB0aGlzLnN0YWNrTWVzc2FnZSA9IG1lc3NhZ2U7XG4gIH1cblxuICBzZXRFcnJvcihlcnJvcikge1xuICAgIHRoaXMuZXJyb3IgPSBlcnJvcjtcbiAgICBpZiAoZXJyb3IubmFtZSkge1xuICAgICAgdGhpcy5uYW1lID0gZXJyb3IubmFtZTtcbiAgICB9XG4gICAgaWYgKGVycm9yLnN0YXR1c0NvZGUpIHtcbiAgICAgIHRoaXMuc3RhdHVzQ29kZSA9IGVycm9yLnN0YXR1c0NvZGU7XG4gICAgfVxuICAgIGlmIChlcnJvci5zdGFjaykge1xuICAgICAgdGhpcy5zdGFja01lc3NhZ2UgPSBlcnJvci5tZXNzYWdlO1xuICAgICAgdGhpcy5zdGFjayA9IGVycm9yLnN0YWNrO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBFeHBvcnRFcnJvcjtcbiIsIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG5cbkhpZ2hjaGFydHMgRXhwb3J0IFNlcnZlclxuXG5Db3B5cmlnaHQgKGMpIDIwMTYtMjAyNCwgSGlnaHNvZnRcblxuTGljZW5jZWQgdW5kZXIgdGhlIE1JVCBsaWNlbmNlLlxuXG5BZGRpdGlvbmFsbHkgYSB2YWxpZCBIaWdoY2hhcnRzIGxpY2Vuc2UgaXMgcmVxdWlyZWQgZm9yIHVzZS5cblxuU2VlIExJQ0VOU0UgZmlsZSBpbiByb290IGZvciBkZXRhaWxzLlxuXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG4vLyBUaGUgY2FjaGUgbWFuYWdlciBtYW5hZ2VzIHRoZSBIaWdoY2hhcnRzIGxpYnJhcnkgYW5kIGl0cyBkZXBlbmRlbmNpZXMuXG4vLyBUaGUgY2FjaGUgaXRzZWxmIGlzIHN0b3JlZCBpbiAuY2FjaGUsIGFuZCBpcyBjaGVja2VkIGJ5IHRoZSBjb25maWcgc3lzdGVtXG4vLyBiZWZvcmUgc3RhcnRpbmcgdGhlIHNlcnZpY2VcblxuaW1wb3J0IHsgZXhpc3RzU3luYywgbWtkaXJTeW5jLCByZWFkRmlsZVN5bmMsIHdyaXRlRmlsZVN5bmMgfSBmcm9tICdmcyc7XG5pbXBvcnQgeyBqb2luIH0gZnJvbSAncGF0aCc7XG5cbmltcG9ydCB7IEh0dHBzUHJveHlBZ2VudCB9IGZyb20gJ2h0dHBzLXByb3h5LWFnZW50JztcblxuaW1wb3J0IHsgZ2V0T3B0aW9ucyB9IGZyb20gJy4vY29uZmlnLmpzJztcbmltcG9ydCB7IGVudnMgfSBmcm9tICcuL2VudnMuanMnO1xuaW1wb3J0IHsgZmV0Y2ggfSBmcm9tICcuL2ZldGNoLmpzJztcbmltcG9ydCB7IGxvZyB9IGZyb20gJy4vbG9nZ2VyLmpzJztcbmltcG9ydCB7IF9fZGlybmFtZSB9IGZyb20gJy4vdXRpbHMuanMnO1xuXG5pbXBvcnQgRXhwb3J0RXJyb3IgZnJvbSAnLi9lcnJvcnMvRXhwb3J0RXJyb3IuanMnO1xuXG5jb25zdCBjYWNoZSA9IHtcbiAgY2RuVVJMOiAnaHR0cHM6Ly9jb2RlLmhpZ2hjaGFydHMuY29tLycsXG4gIGFjdGl2ZU1hbmlmZXN0OiB7fSxcbiAgc291cmNlczogJycsXG4gIGhjVmVyc2lvbjogJydcbn07XG5cbi8qKlxuICogRXh0cmFjdHMgYW5kIGNhY2hlcyB0aGUgSGlnaGNoYXJ0cyB2ZXJzaW9uIGZyb20gdGhlIHNvdXJjZXMgc3RyaW5nLlxuICpcbiAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBleHRyYWN0ZWQgSGlnaGNoYXJ0cyB2ZXJzaW9uLlxuICovXG5leHBvcnQgY29uc3QgZXh0cmFjdFZlcnNpb24gPSAoY2FjaGUpID0+IHtcbiAgcmV0dXJuIGNhY2hlLnNvdXJjZXNcbiAgICAuc3Vic3RyaW5nKDAsIGNhY2hlLnNvdXJjZXMuaW5kZXhPZignKi8nKSlcbiAgICAucmVwbGFjZSgnLyonLCAnJylcbiAgICAucmVwbGFjZSgnKi8nLCAnJylcbiAgICAucmVwbGFjZSgvXFxuL2csICcnKVxuICAgIC50cmltKCk7XG59O1xuXG4vKipcbiAqIEV4dHJhY3RzIHRoZSBIaWdoY2hhcnRzIG1vZHVsZSBuYW1lIGJhc2VkIG9uIHRoZSBzY3JpcHRQYXRoLlxuICovXG5leHBvcnQgY29uc3QgZXh0cmFjdE1vZHVsZU5hbWUgPSAoc2NyaXB0UGF0aCkgPT4ge1xuICByZXR1cm4gc2NyaXB0UGF0aC5yZXBsYWNlKFxuICAgIC8oLiopXFwvfCguKiltb2R1bGVzXFwvfHN0b2NrXFwvKC4qKWluZGljYXRvcnNcXC98bWFwc1xcLyguKiltb2R1bGVzXFwvL2dpLFxuICAgICcnXG4gICk7XG59O1xuXG4vKipcbiAqIFNhdmVzIHRoZSBwcm92aWRlZCBjb25maWd1cmF0aW9uIGFuZCBmZXRjaGVkIG1vZHVsZXMgdG8gdGhlIGNhY2hlIG1hbmlmZXN0XG4gKiBmaWxlLlxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBjb25maWcgLSBIaWdoY2hhcnRzLXJlbGF0ZWQgY29uZmlndXJhdGlvbiBvYmplY3QuXG4gKiBAcGFyYW0ge29iamVjdH0gZmV0Y2hlZE1vZHVsZXMgLSBBbiBvYmplY3QgdGhhdCBjb250YWlucyBtYXBwZWQgbmFtZXMgb2ZcbiAqIGZldGNoZWQgSGlnaGNoYXJ0cyBtb2R1bGVzIHRvIHVzZS5cbiAqXG4gKiBAdGhyb3dzIHtFeHBvcnRFcnJvcn0gVGhyb3dzIGFuIEV4cG9ydEVycm9yIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSB3cml0aW5nXG4gKiB0aGUgY2FjaGUgbWFuaWZlc3QuXG4gKi9cbmV4cG9ydCBjb25zdCBzYXZlQ29uZmlnVG9NYW5pZmVzdCA9IGFzeW5jIChjb25maWcsIGZldGNoZWRNb2R1bGVzKSA9PiB7XG4gIGNvbnN0IG5ld01hbmlmZXN0ID0ge1xuICAgIHZlcnNpb246IGNvbmZpZy52ZXJzaW9uLFxuICAgIG1vZHVsZXM6IGZldGNoZWRNb2R1bGVzIHx8IHt9XG4gIH07XG5cbiAgLy8gVXBkYXRlIGNhY2hlIG9iamVjdCB3aXRoIHRoZSBjdXJyZW50IG1vZHVsZXNcbiAgY2FjaGUuYWN0aXZlTWFuaWZlc3QgPSBuZXdNYW5pZmVzdDtcblxuICBsb2coMywgJ1tjYWNoZV0gV3JpdGluZyBhIG5ldyBtYW5pZmVzdC4nKTtcbiAgdHJ5IHtcbiAgICB3cml0ZUZpbGVTeW5jKFxuICAgICAgam9pbihfX2Rpcm5hbWUsIGNvbmZpZy5jYWNoZVBhdGgsICdtYW5pZmVzdC5qc29uJyksXG4gICAgICBKU09OLnN0cmluZ2lmeShuZXdNYW5pZmVzdCksXG4gICAgICAndXRmOCdcbiAgICApO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHRocm93IG5ldyBFeHBvcnRFcnJvcignW2NhY2hlXSBFcnJvciB3cml0aW5nIHRoZSBjYWNoZSBtYW5pZmVzdC4nKS5zZXRFcnJvcihcbiAgICAgIGVycm9yXG4gICAgKTtcbiAgfVxufTtcblxuLyoqXG4gKiBGZXRjaGVzIGEgc2luZ2xlIHNjcmlwdCBhbmQgdXBkYXRlcyB0aGUgZmV0Y2hlZE1vZHVsZXMgYWNjb3JkaW5nbHkuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHNjcmlwdCAtIEEgcGF0aCB0byBzY3JpcHQgdG8gZ2V0LlxuICogQHBhcmFtIHtPYmplY3R9IHJlcXVlc3RPcHRpb25zIC0gQWRkaXRpb25hbCBvcHRpb25zIGZvciB0aGUgcHJveHkgYWdlbnRcbiAqIHRvIHVzZSBmb3IgYSByZXF1ZXN0LlxuICogQHBhcmFtIHtPYmplY3R9IGZldGNoZWRNb2R1bGVzIC0gQW4gb2JqZWN0IHdoaWNoIHRyYWNrcyB3aGljaCBIaWdoY2hhcnRzXG4gKiBtb2R1bGVzIGhhdmUgYmVlbiBmZXRjaGVkLlxuICogQHBhcmFtIHtib29sZWFufSBzaG91bGRUaHJvd0Vycm9yIC0gQSBmbGFnIHRvIGluZGljYXRlIGlmIHRoZSBlcnJvciBzaG91bGQgYmVcbiAqIHRocm93bi4gVGhpcyBzaG91bGQgYmUgdXNlZCBvbmx5IGZvciB0aGUgY29yZSBzY3JpcHRzLlxuICpcbiAqIEByZXR1cm5zIHtQcm9taXNlPHN0cmluZz59IEEgUHJvbWlzZSByZXNvbHZpbmcgdG8gdGhlIHRleHQgcmVwcmVzZW50YXRpb25cbiAqIG9mIHRoZSBmZXRjaGVkIHNjcmlwdC5cbiAqXG4gKiBAdGhyb3dzIHtFeHBvcnRFcnJvcn0gVGhyb3dzIGFuIEV4cG9ydEVycm9yIGlmIHRoZXJlIGlzIGEgcHJvYmxlbSB3aXRoXG4gKiBmZXRjaGluZyB0aGUgc2NyaXB0LlxuICovXG5leHBvcnQgY29uc3QgZmV0Y2hBbmRQcm9jZXNzU2NyaXB0ID0gYXN5bmMgKFxuICBzY3JpcHQsXG4gIHJlcXVlc3RPcHRpb25zLFxuICBmZXRjaGVkTW9kdWxlcyxcbiAgc2hvdWxkVGhyb3dFcnJvciA9IGZhbHNlXG4pID0+IHtcbiAgLy8gR2V0IHJpZCBvZiB0aGUgLmpzIGZyb20gdGhlIGN1c3RvbSBzdHJpbmdzXG4gIGlmIChzY3JpcHQuZW5kc1dpdGgoJy5qcycpKSB7XG4gICAgc2NyaXB0ID0gc2NyaXB0LnN1YnN0cmluZygwLCBzY3JpcHQubGVuZ3RoIC0gMyk7XG4gIH1cblxuICBsb2coNCwgYFtjYWNoZV0gRmV0Y2hpbmcgc2NyaXB0IC0gJHtzY3JpcHR9LmpzYCk7XG5cbiAgLy8gRmV0Y2ggdGhlIHNjcmlwdFxuICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKGAke3NjcmlwdH0uanNgLCByZXF1ZXN0T3B0aW9ucyk7XG5cbiAgLy8gSWYgT0ssIHJldHVybiBpdHMgdGV4dCByZXByZXNlbnRhdGlvblxuICBpZiAocmVzcG9uc2Uuc3RhdHVzQ29kZSA9PT0gMjAwICYmIHR5cGVvZiByZXNwb25zZS50ZXh0ID09ICdzdHJpbmcnKSB7XG4gICAgaWYgKGZldGNoZWRNb2R1bGVzKSB7XG4gICAgICBjb25zdCBtb2R1bGVOYW1lID0gZXh0cmFjdE1vZHVsZU5hbWUoc2NyaXB0KTtcbiAgICAgIGZldGNoZWRNb2R1bGVzW21vZHVsZU5hbWVdID0gMTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzcG9uc2UudGV4dDtcbiAgfVxuXG4gIGlmIChzaG91bGRUaHJvd0Vycm9yKSB7XG4gICAgdGhyb3cgbmV3IEV4cG9ydEVycm9yKFxuICAgICAgYENvdWxkIG5vdCBmZXRjaCB0aGUgJHtzY3JpcHR9LmpzLiBUaGUgc2NyaXB0IG1pZ2h0IG5vdCBleGlzdCBpbiB0aGUgcmVxdWVzdGVkIHZlcnNpb24gKHN0YXR1cyBjb2RlOiAke3Jlc3BvbnNlLnN0YXR1c0NvZGV9KS5gXG4gICAgKS5zZXRFcnJvcihyZXNwb25zZSk7XG4gIH0gZWxzZSB7XG4gICAgbG9nKFxuICAgICAgMixcbiAgICAgIGBbY2FjaGVdIENvdWxkIG5vdCBmZXRjaCB0aGUgJHtzY3JpcHR9LmpzLiBUaGUgc2NyaXB0IG1pZ2h0IG5vdCBleGlzdCBpbiB0aGUgcmVxdWVzdGVkIHZlcnNpb24uYFxuICAgICk7XG4gIH1cblxuICByZXR1cm4gJyc7XG59O1xuXG4vKipcbiAqIEZldGNoZXMgSGlnaGNoYXJ0cyBzY3JpcHRzIGFuZCBjdXN0b21TY3JpcHRzIGZyb20gdGhlIGdpdmVuIENETnMuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGNvcmVTY3JpcHRzIC0gQXJyYXkgb2YgSGlnaGNoYXJ0cyBjb3JlIHNjcmlwdHMgdG8gZmV0Y2guXG4gKiBAcGFyYW0ge3N0cmluZ30gbW9kdWxlU2NyaXB0cyAtIEFycmF5IG9mIEhpZ2hjaGFydHMgbW9kdWxlcyB0byBmZXRjaC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBjdXN0b21TY3JpcHRzIC0gQXJyYXkgb2YgY3VzdG9tIHNjcmlwdCBwYXRocyB0byBmZXRjaFxuICogKGZ1bGwgVVJMcykuXG4gKiBAcGFyYW0ge29iamVjdH0gcHJveHlPcHRpb25zIC0gT3B0aW9ucyBmb3IgdGhlIHByb3h5IGFnZW50IHRvIHVzZSBmb3JcbiAqIGEgcmVxdWVzdC5cbiAqIEBwYXJhbSB7b2JqZWN0fSBmZXRjaGVkTW9kdWxlcyAtIEFuIG9iamVjdCB3aGljaCB0cmFja3Mgd2hpY2ggSGlnaGNoYXJ0c1xuICogbW9kdWxlcyBoYXZlIGJlZW4gZmV0Y2hlZC5cbiAqXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxzdHJpbmc+fSBUaGUgZmV0Y2hlZCBzY3JpcHRzIGNvbnRlbnQgam9pbmVkLlxuICovXG5leHBvcnQgY29uc3QgZmV0Y2hTY3JpcHRzID0gYXN5bmMgKFxuICBjb3JlU2NyaXB0cyxcbiAgbW9kdWxlU2NyaXB0cyxcbiAgY3VzdG9tU2NyaXB0cyxcbiAgcHJveHlPcHRpb25zLFxuICBmZXRjaGVkTW9kdWxlc1xuKSA9PiB7XG4gIC8vIENvbmZpZ3VyZSBwcm94eSBpZiBleGlzdHNcbiAgbGV0IHByb3h5QWdlbnQ7XG4gIGNvbnN0IHsgaG9zdCwgcG9ydCwgdXNlcm5hbWUsIHBhc3N3b3JkIH0gPSBwcm94eU9wdGlvbnM7XG5cbiAgLy8gVHJ5IHRvIGNyZWF0ZSBhIFByb3h5IEFnZW50XG4gIGlmIChob3N0ICYmIHBvcnQpIHtcbiAgICB0cnkge1xuICAgICAgcHJveHlBZ2VudCA9IG5ldyBIdHRwc1Byb3h5QWdlbnQoe1xuICAgICAgICBob3N0LFxuICAgICAgICBwb3J0LFxuICAgICAgICAuLi4odXNlcm5hbWUgJiYgcGFzc3dvcmQgPyB7IHVzZXJuYW1lLCBwYXNzd29yZCB9IDoge30pXG4gICAgICB9KTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhyb3cgbmV3IEV4cG9ydEVycm9yKCdbY2FjaGVdIENvdWxkIG5vdCBjcmVhdGUgYSBQcm94eSBBZ2VudC4nKS5zZXRFcnJvcihcbiAgICAgICAgZXJyb3JcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLy8gSWYgZXhpc3RzLCBhZGQgcHJveHkgYWdlbnQgdG8gcmVxdWVzdCBvcHRpb25zXG4gIGNvbnN0IHJlcXVlc3RPcHRpb25zID0gcHJveHlBZ2VudFxuICAgID8ge1xuICAgICAgICBhZ2VudDogcHJveHlBZ2VudCxcbiAgICAgICAgdGltZW91dDogZW52cy5TRVJWRVJfUFJPWFlfVElNRU9VVFxuICAgICAgfVxuICAgIDoge307XG5cbiAgY29uc3QgYWxsRmV0Y2hQcm9taXNlcyA9IFtcbiAgICAuLi5jb3JlU2NyaXB0cy5tYXAoKHNjcmlwdCkgPT5cbiAgICAgIGZldGNoQW5kUHJvY2Vzc1NjcmlwdChgJHtzY3JpcHR9YCwgcmVxdWVzdE9wdGlvbnMsIGZldGNoZWRNb2R1bGVzLCB0cnVlKVxuICAgICksXG4gICAgLi4ubW9kdWxlU2NyaXB0cy5tYXAoKHNjcmlwdCkgPT5cbiAgICAgIGZldGNoQW5kUHJvY2Vzc1NjcmlwdChgJHtzY3JpcHR9YCwgcmVxdWVzdE9wdGlvbnMsIGZldGNoZWRNb2R1bGVzKVxuICAgICksXG4gICAgLi4uY3VzdG9tU2NyaXB0cy5tYXAoKHNjcmlwdCkgPT5cbiAgICAgIGZldGNoQW5kUHJvY2Vzc1NjcmlwdChgJHtzY3JpcHR9YCwgcmVxdWVzdE9wdGlvbnMpXG4gICAgKVxuICBdO1xuXG4gIGNvbnN0IGZldGNoZWRTY3JpcHRzID0gYXdhaXQgUHJvbWlzZS5hbGwoYWxsRmV0Y2hQcm9taXNlcyk7XG4gIHJldHVybiBmZXRjaGVkU2NyaXB0cy5qb2luKCc7XFxuJyk7XG59O1xuXG4vKipcbiAqIFVwZGF0ZXMgdGhlIGxvY2FsIGNhY2hlIHdpdGggSGlnaGNoYXJ0cyBzY3JpcHRzIGFuZCB0aGVpciB2ZXJzaW9ucy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIE9iamVjdCBjb250YWluaW5nIGFsbCBvcHRpb25zLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZVBhdGggLSBUaGUgcGF0aCB0byB0aGUgc291cmNlIGZpbGUgaW4gdGhlIGNhY2hlLlxuICpcbiAqIEByZXR1cm5zIHtQcm9taXNlPG9iamVjdD59IEEgUHJvbWlzZSByZXNvbHZpbmcgdG8gYW4gb2JqZWN0IHJlcHJlc2VudGluZ1xuICogdGhlIGZldGNoZWQgbW9kdWxlcy5cbiAqXG4gKiBAdGhyb3dzIHtFeHBvcnRFcnJvcn0gVGhyb3dzIGFuIEV4cG9ydEVycm9yIGlmIHRoZXJlIGlzIGFuIGlzc3VlIHVwZGF0aW5nXG4gKiB0aGUgbG9jYWwgSGlnaGNoYXJ0cyBjYWNoZS5cbiAqL1xuZXhwb3J0IGNvbnN0IHVwZGF0ZUNhY2hlID0gYXN5bmMgKFxuICBoaWdoY2hhcnRzT3B0aW9ucyxcbiAgcHJveHlPcHRpb25zLFxuICBzb3VyY2VQYXRoXG4pID0+IHtcbiAgY29uc3QgdmVyc2lvbiA9IGhpZ2hjaGFydHNPcHRpb25zLnZlcnNpb247XG4gIGNvbnN0IGhjVmVyc2lvbiA9IHZlcnNpb24gPT09ICdsYXRlc3QnIHx8ICF2ZXJzaW9uID8gJycgOiBgJHt2ZXJzaW9ufS9gO1xuICBjb25zdCBjZG5VUkwgPSBoaWdoY2hhcnRzT3B0aW9ucy5jZG5VUkwgfHwgY2FjaGUuY2RuVVJMO1xuXG4gIGxvZyhcbiAgICAzLFxuICAgIGBbY2FjaGVdIFVwZGF0aW5nIGNhY2hlIHZlcnNpb24gdG8gSGlnaGNoYXJ0czogJHtoY1ZlcnNpb24gfHwgJ2xhdGVzdCd9LmBcbiAgKTtcblxuICBjb25zdCBmZXRjaGVkTW9kdWxlcyA9IHt9O1xuICB0cnkge1xuICAgIGNhY2hlLnNvdXJjZXMgPSBhd2FpdCBmZXRjaFNjcmlwdHMoXG4gICAgICBbXG4gICAgICAgIC4uLmhpZ2hjaGFydHNPcHRpb25zLmNvcmVTY3JpcHRzLm1hcCgoYykgPT4gYCR7Y2RuVVJMfSR7aGNWZXJzaW9ufSR7Y31gKVxuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgLi4uaGlnaGNoYXJ0c09wdGlvbnMubW9kdWxlU2NyaXB0cy5tYXAoKG0pID0+XG4gICAgICAgICAgbSA9PT0gJ21hcCdcbiAgICAgICAgICAgID8gYCR7Y2RuVVJMfW1hcHMvJHtoY1ZlcnNpb259bW9kdWxlcy8ke219YFxuICAgICAgICAgICAgOiBgJHtjZG5VUkx9JHtoY1ZlcnNpb259bW9kdWxlcy8ke219YFxuICAgICAgICApLFxuICAgICAgICAuLi5oaWdoY2hhcnRzT3B0aW9ucy5pbmRpY2F0b3JTY3JpcHRzLm1hcChcbiAgICAgICAgICAoaSkgPT4gYCR7Y2RuVVJMfXN0b2NrLyR7aGNWZXJzaW9ufWluZGljYXRvcnMvJHtpfWBcbiAgICAgICAgKVxuICAgICAgXSxcbiAgICAgIGhpZ2hjaGFydHNPcHRpb25zLmN1c3RvbVNjcmlwdHMsXG4gICAgICBwcm94eU9wdGlvbnMsXG4gICAgICBmZXRjaGVkTW9kdWxlc1xuICAgICk7XG5cbiAgICBjYWNoZS5oY1ZlcnNpb24gPSBleHRyYWN0VmVyc2lvbihjYWNoZSk7XG5cbiAgICAvLyBTYXZlIHRoZSBmZXRjaGVkIG1vZHVsZXMgaW50byBjYWNoZXMnIHNvdXJjZSBKU09OXG4gICAgd3JpdGVGaWxlU3luYyhzb3VyY2VQYXRoLCBjYWNoZS5zb3VyY2VzKTtcbiAgICByZXR1cm4gZmV0Y2hlZE1vZHVsZXM7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgdGhyb3cgbmV3IEV4cG9ydEVycm9yKFxuICAgICAgJ1tjYWNoZV0gVW5hYmxlIHRvIHVwZGF0ZSB0aGUgbG9jYWwgSGlnaGNoYXJ0cyBjYWNoZS4nXG4gICAgKS5zZXRFcnJvcihlcnJvcik7XG4gIH1cbn07XG5cbi8qKlxuICogVXBkYXRlcyB0aGUgSGlnaGNoYXJ0cyB2ZXJzaW9uIGluIHRoZSBhcHBsaWVkIGNvbmZpZ3VyYXRpb24gYW5kIGNoZWNrc1xuICogdGhlIGNhY2hlIGZvciB0aGUgbmV3IHZlcnNpb24uXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IG5ld1ZlcnNpb24gLSBUaGUgbmV3IEhpZ2hjaGFydHMgdmVyc2lvbiB0byBiZSBhcHBsaWVkLlxuICpcbiAqIEByZXR1cm5zIHtQcm9taXNlPChvYmplY3R8Ym9vbGVhbik+fSBBIFByb21pc2UgcmVzb2x2aW5nIHRvIHRoZSB1cGRhdGVkXG4gKiBjb25maWd1cmF0aW9uIHdpdGggdGhlIG5ldyB2ZXJzaW9uLCBvciBmYWxzZSBpZiBubyBhcHBsaWVkIGNvbmZpZ3VyYXRpb25cbiAqIGV4aXN0cy5cbiAqL1xuZXhwb3J0IGNvbnN0IHVwZGF0ZVZlcnNpb24gPSBhc3luYyAobmV3VmVyc2lvbikgPT4ge1xuICBjb25zdCBvcHRpb25zID0gZ2V0T3B0aW9ucygpO1xuICBpZiAob3B0aW9ucz8uaGlnaGNoYXJ0cykge1xuICAgIG9wdGlvbnMuaGlnaGNoYXJ0cy52ZXJzaW9uID0gbmV3VmVyc2lvbjtcbiAgfVxuICBhd2FpdCBjaGVja0FuZFVwZGF0ZUNhY2hlKG9wdGlvbnMpO1xufTtcblxuLyoqXG4gKiBDaGVja3MgdGhlIGNhY2hlIGZvciBIaWdoY2hhcnRzIGRlcGVuZGVuY2llcywgdXBkYXRlcyB0aGUgY2FjaGUgaWYgbmVlZGVkLFxuICogYW5kIGxvYWRzIHRoZSBzb3VyY2VzLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gT2JqZWN0IGNvbnRhaW5pbmcgYWxsIG9wdGlvbnMuXG4gKlxuICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IEEgUHJvbWlzZSB0aGF0IHJlc29sdmVzIG9uY2UgdGhlIGNhY2hlIGlzIGNoZWNrZWRcbiAqIGFuZCB1cGRhdGVkLlxuICpcbiAqIEB0aHJvd3Mge0V4cG9ydEVycm9yfSBUaHJvd3MgYW4gRXhwb3J0RXJyb3IgaWYgdGhlcmUgaXMgYW4gaXNzdWUgdXBkYXRpbmdcbiAqIG9yIHJlYWRpbmcgdGhlIGNhY2hlLlxuICovXG5leHBvcnQgY29uc3QgY2hlY2tBbmRVcGRhdGVDYWNoZSA9IGFzeW5jIChvcHRpb25zKSA9PiB7XG4gIGNvbnN0IHsgaGlnaGNoYXJ0cywgc2VydmVyIH0gPSBvcHRpb25zO1xuICBjb25zdCBjYWNoZVBhdGggPSBqb2luKF9fZGlybmFtZSwgaGlnaGNoYXJ0cy5jYWNoZVBhdGgpO1xuXG4gIGxldCBmZXRjaGVkTW9kdWxlcztcbiAgLy8gUHJlcGFyZSBwYXRocyB0byBtYW5pZmVzdCBhbmQgc291cmNlcyBmcm9tIHRoZSAuY2FjaGUgZm9sZGVyXG4gIGNvbnN0IG1hbmlmZXN0UGF0aCA9IGpvaW4oY2FjaGVQYXRoLCAnbWFuaWZlc3QuanNvbicpO1xuICBjb25zdCBzb3VyY2VQYXRoID0gam9pbihjYWNoZVBhdGgsICdzb3VyY2VzLmpzJyk7XG5cbiAgLy8gQ3JlYXRlIHRoZSBjYWNoZSBkZXN0aW5hdGlvbiBpZiBpdCBkb2Vzbid0IGV4aXN0IGFscmVhZHlcbiAgIWV4aXN0c1N5bmMoY2FjaGVQYXRoKSAmJiBta2RpclN5bmMoY2FjaGVQYXRoKTtcblxuICAvLyBGZXRjaCBhbGwgdGhlIHNjcmlwdHMgZWl0aGVyIGlmIG1hbmlmZXN0Lmpzb24gZG9lcyBub3QgZXhpc3RcbiAgLy8gb3IgaWYgdGhlIGZvcmNlRmV0Y2ggb3B0aW9uIGlzIGVuYWJsZWRcbiAgaWYgKCFleGlzdHNTeW5jKG1hbmlmZXN0UGF0aCkgfHwgaGlnaGNoYXJ0cy5mb3JjZUZldGNoKSB7XG4gICAgbG9nKDMsICdbY2FjaGVdIEZldGNoaW5nIGFuZCBjYWNoaW5nIEhpZ2hjaGFydHMgZGVwZW5kZW5jaWVzLicpO1xuICAgIGZldGNoZWRNb2R1bGVzID0gYXdhaXQgdXBkYXRlQ2FjaGUoaGlnaGNoYXJ0cywgc2VydmVyLnByb3h5LCBzb3VyY2VQYXRoKTtcbiAgfSBlbHNlIHtcbiAgICBsZXQgcmVxdWVzdFVwZGF0ZSA9IGZhbHNlO1xuXG4gICAgLy8gUmVhZCB0aGUgbWFuaWZlc3QgSlNPTlxuICAgIGNvbnN0IG1hbmlmZXN0ID0gSlNPTi5wYXJzZShyZWFkRmlsZVN5bmMobWFuaWZlc3RQYXRoKSk7XG5cbiAgICAvLyBDaGVjayBpZiB0aGUgbW9kdWxlcyBpcyBhbiBhcnJheSwgaWYgc28sIHdlIHJld3JpdGUgaXQgdG8gYSBtYXAgdG8gbWFrZVxuICAgIC8vIGl0IGVhc2llciB0byByZXNvbHZlIG1vZHVsZXMuXG4gICAgaWYgKG1hbmlmZXN0Lm1vZHVsZXMgJiYgQXJyYXkuaXNBcnJheShtYW5pZmVzdC5tb2R1bGVzKSkge1xuICAgICAgY29uc3QgbW9kdWxlTWFwID0ge307XG4gICAgICBtYW5pZmVzdC5tb2R1bGVzLmZvckVhY2goKG0pID0+IChtb2R1bGVNYXBbbV0gPSAxKSk7XG4gICAgICBtYW5pZmVzdC5tb2R1bGVzID0gbW9kdWxlTWFwO1xuICAgIH1cblxuICAgIGNvbnN0IHsgY29yZVNjcmlwdHMsIG1vZHVsZVNjcmlwdHMsIGluZGljYXRvclNjcmlwdHMgfSA9IGhpZ2hjaGFydHM7XG4gICAgY29uc3QgbnVtYmVyT2ZNb2R1bGVzID1cbiAgICAgIGNvcmVTY3JpcHRzLmxlbmd0aCArIG1vZHVsZVNjcmlwdHMubGVuZ3RoICsgaW5kaWNhdG9yU2NyaXB0cy5sZW5ndGg7XG5cbiAgICAvLyBDb21wYXJlIHRoZSBsb2FkZWQgaGlnaGNoYXJ0cyBjb25maWcgd2l0aCB0aGUgY29udGVudHMgaW4gY2FjaGUuXG4gICAgLy8gSWYgdGhlcmUgYXJlIGNoYW5nZXMsIGZldGNoIHJlcXVlc3RlZCBtb2R1bGVzIGFuZCBwcm9kdWN0cyxcbiAgICAvLyBhbmQgYmFrZSB0aGVtIGludG8gYSBnaWFudCBibG9iLiBTYXZlIHRoZSBibG9iLlxuICAgIGlmIChtYW5pZmVzdC52ZXJzaW9uICE9PSBoaWdoY2hhcnRzLnZlcnNpb24pIHtcbiAgICAgIGxvZyhcbiAgICAgICAgMixcbiAgICAgICAgJ1tjYWNoZV0gQSBIaWdoY2hhcnRzIHZlcnNpb24gbWlzbWF0Y2ggaW4gdGhlIGNhY2hlLCBuZWVkIHRvIHJlLWZldGNoLidcbiAgICAgICk7XG4gICAgICByZXF1ZXN0VXBkYXRlID0gdHJ1ZTtcbiAgICB9IGVsc2UgaWYgKE9iamVjdC5rZXlzKG1hbmlmZXN0Lm1vZHVsZXMgfHwge30pLmxlbmd0aCAhPT0gbnVtYmVyT2ZNb2R1bGVzKSB7XG4gICAgICBsb2coXG4gICAgICAgIDIsXG4gICAgICAgICdbY2FjaGVdIFRoZSBjYWNoZSBhbmQgdGhlIHJlcXVlc3RlZCBtb2R1bGVzIGRvIG5vdCBtYXRjaCwgbmVlZCB0byByZS1mZXRjaC4nXG4gICAgICApO1xuICAgICAgcmVxdWVzdFVwZGF0ZSA9IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIENoZWNrIGVhY2ggbW9kdWxlLCBpZiBhbnl0aGluZyBpcyBtaXNzaW5nIHJlZmV0Y2ggZXZlcnl0aGluZ1xuICAgICAgcmVxdWVzdFVwZGF0ZSA9IChtb2R1bGVTY3JpcHRzIHx8IFtdKS5zb21lKChtb2R1bGVOYW1lKSA9PiB7XG4gICAgICAgIGlmICghbWFuaWZlc3QubW9kdWxlc1ttb2R1bGVOYW1lXSkge1xuICAgICAgICAgIGxvZyhcbiAgICAgICAgICAgIDIsXG4gICAgICAgICAgICBgW2NhY2hlXSBUaGUgJHttb2R1bGVOYW1lfSBpcyBtaXNzaW5nIGluIHRoZSBjYWNoZSwgbmVlZCB0byByZS1mZXRjaC5gXG4gICAgICAgICAgKTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKHJlcXVlc3RVcGRhdGUpIHtcbiAgICAgIGZldGNoZWRNb2R1bGVzID0gYXdhaXQgdXBkYXRlQ2FjaGUoaGlnaGNoYXJ0cywgc2VydmVyLnByb3h5LCBzb3VyY2VQYXRoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbG9nKDMsICdbY2FjaGVdIERlcGVuZGVuY3kgY2FjaGUgaXMgdXAgdG8gZGF0ZSwgcHJvY2VlZGluZy4nKTtcblxuICAgICAgLy8gTG9hZCB0aGUgc291cmNlc1xuICAgICAgY2FjaGUuc291cmNlcyA9IHJlYWRGaWxlU3luYyhzb3VyY2VQYXRoLCAndXRmOCcpO1xuXG4gICAgICAvLyBHZXQgY3VycmVudCBtb2R1bGVzIG1hcFxuICAgICAgZmV0Y2hlZE1vZHVsZXMgPSBtYW5pZmVzdC5tb2R1bGVzO1xuXG4gICAgICBjYWNoZS5oY1ZlcnNpb24gPSBleHRyYWN0VmVyc2lvbihjYWNoZSk7XG4gICAgfVxuICB9XG5cbiAgLy8gRmluYWxseSwgc2F2ZSB0aGUgbmV3IG1hbmlmZXN0LCB3aGljaCBpcyBiYXNpY2FsbHkgb3VyIGN1cnJlbnQgY29uZmlnXG4gIC8vIGluIGEgc2xpZ2h0bHkgZGlmZmVyZW50IGZvcm1hdFxuICBhd2FpdCBzYXZlQ29uZmlnVG9NYW5pZmVzdChoaWdoY2hhcnRzLCBmZXRjaGVkTW9kdWxlcyk7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0Q2FjaGVQYXRoID0gKCkgPT5cbiAgam9pbihfX2Rpcm5hbWUsIGdldE9wdGlvbnMoKS5oaWdoY2hhcnRzLmNhY2hlUGF0aCk7XG5cbmV4cG9ydCBjb25zdCBnZXRDYWNoZSA9ICgpID0+IGNhY2hlO1xuXG5leHBvcnQgY29uc3QgaGlnaGNoYXJ0cyA9ICgpID0+IGNhY2hlLnNvdXJjZXM7XG5cbmV4cG9ydCBjb25zdCB2ZXJzaW9uID0gKCkgPT4gY2FjaGUuaGNWZXJzaW9uO1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIGNoZWNrQW5kVXBkYXRlQ2FjaGUsXG4gIGdldENhY2hlUGF0aCxcbiAgdXBkYXRlVmVyc2lvbixcbiAgZ2V0Q2FjaGUsXG4gIGhpZ2hjaGFydHMsXG4gIHZlcnNpb25cbn07XG4iLCIvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuXG5IaWdoY2hhcnRzIEV4cG9ydCBTZXJ2ZXJcblxuQ29weXJpZ2h0IChjKSAyMDE2LTIwMjQsIEhpZ2hzb2Z0XG5cbkxpY2VuY2VkIHVuZGVyIHRoZSBNSVQgbGljZW5jZS5cblxuQWRkaXRpb25hbGx5IGEgdmFsaWQgSGlnaGNoYXJ0cyBsaWNlbnNlIGlzIHJlcXVpcmVkIGZvciB1c2UuXG5cblNlZSBMSUNFTlNFIGZpbGUgaW4gcm9vdCBmb3IgZGV0YWlscy5cblxuKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuLyogZXNsaW50LWRpc2FibGUgbm8tdW5kZWYgKi9cblxuLyoqXG4gKiBTZXR0aW5nIHRoZSBhbmltT2JqZWN0LiBDYWxsZWQgd2hlbiBpbml0aW5nIHRoZSBwYWdlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc2V0dXBIaWdoY2hhcnRzKCkge1xuICBIaWdoY2hhcnRzLmFuaW1PYmplY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHsgZHVyYXRpb246IDAgfTtcbiAgfTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIHRoZSBhY3R1YWwgY2hhcnQuXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IGNoYXJ0T3B0aW9ucyAtIFRoZSBvcHRpb25zIGZvciB0aGUgSGlnaGNoYXJ0cyBjaGFydC5cbiAqIEBwYXJhbSB7b2JqZWN0fSBvcHRpb25zIC0gVGhlIGV4cG9ydCBvcHRpb25zLlxuICogQHBhcmFtIHtib29sZWFufSBkaXNwbGF5RXJyb3JzIC0gQSBmbGFnIGluZGljYXRpbmcgd2hldGhlciB0byBkaXNwbGF5IGVycm9ycy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHRyaWdnZXJFeHBvcnQoY2hhcnRPcHRpb25zLCBvcHRpb25zLCBkaXNwbGF5RXJyb3JzKSB7XG4gIC8vIERpc3BsYXkgZXJyb3JzIGZsYWcgdGFrZW4gZnJvbSBjaGFydCBvcHRpb25zIG5hZCBkZWJ1Z2dlciBtb2R1bGVcbiAgd2luZG93Ll9kaXNwbGF5RXJyb3JzID0gZGlzcGxheUVycm9ycztcblxuICAvLyBHZXQgcmVxdWlyZWQgZnVuY3Rpb25zXG4gIGNvbnN0IHsgZ2V0T3B0aW9ucywgbWVyZ2UsIHNldE9wdGlvbnMsIHdyYXAgfSA9IEhpZ2hjaGFydHM7XG5cbiAgLy8gQ3JlYXRlIGEgc2VwYXJhdGUgb2JqZWN0IGZvciBhIHBvdGVudGlhbCBzZXRPcHRpb25zIHVzYWdlcyBpbiBvcmRlciB0b1xuICAvLyBwcmV2ZW50IGZyb20gcG9sbHV0aW5nIG90aGVyIGV4cG9ydHMgdGhhdCBjYW4gaGFwcGVuIG9uIHRoZSBzYW1lIHBhZ2VcbiAgSGlnaGNoYXJ0cy5zZXRPcHRpb25zT2JqID0gbWVyZ2UoZmFsc2UsIHt9LCBnZXRPcHRpb25zKCkpO1xuXG4gIC8vIEJ5IGRlZmF1bHQgYW5pbWF0aW9uIGlzIGRpc2FibGVkXG4gIGNvbnN0IGNoYXJ0ID0ge1xuICAgIGFuaW1hdGlvbjogZmFsc2VcbiAgfTtcblxuICAvLyBXaGVuIHN0cmFpZ2h0IGluamVjdCwgdGhlIHNpemUgaXMgc2V0IHRocm91Z2ggQ1NTIG9ubHlcbiAgaWYgKG9wdGlvbnMuZXhwb3J0LnN0ckluaikge1xuICAgIGNoYXJ0LmhlaWdodCA9IGNoYXJ0T3B0aW9ucy5jaGFydC5oZWlnaHQ7XG4gICAgY2hhcnQud2lkdGggPSBjaGFydE9wdGlvbnMuY2hhcnQud2lkdGg7XG4gIH1cblxuICAvLyBOT1RFOiBJcyB0aGlzIHVzZWQgZm9yIGFueXRoaW5nIHVzZWZ1bD9cbiAgd2luZG93LmlzUmVuZGVyQ29tcGxldGUgPSBmYWxzZTtcbiAgd3JhcChIaWdoY2hhcnRzLkNoYXJ0LnByb3RvdHlwZSwgJ2luaXQnLCBmdW5jdGlvbiAocHJvY2VlZCwgdXNlck9wdGlvbnMsIGNiKSB7XG4gICAgLy8gT3ZlcnJpZGUgdXNlck9wdGlvbnMgd2l0aCBpbWFnZSBmcmllbmRseSBvcHRpb25zXG4gICAgdXNlck9wdGlvbnMgPSBtZXJnZSh1c2VyT3B0aW9ucywge1xuICAgICAgZXhwb3J0aW5nOiB7XG4gICAgICAgIGVuYWJsZWQ6IGZhbHNlXG4gICAgICB9LFxuICAgICAgcGxvdE9wdGlvbnM6IHtcbiAgICAgICAgc2VyaWVzOiB7XG4gICAgICAgICAgbGFiZWw6IHtcbiAgICAgICAgICAgIGVuYWJsZWQ6IGZhbHNlXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgLyogRXhwZWN0cyB0b29sdGlwIGluIHVzZXJPcHRpb25zIHdoZW4gZm9yRXhwb3J0IGlzIHRydWUuXG4gICAgICAgIGh0dHBzOi8vZ2l0aHViLmNvbS9oaWdoY2hhcnRzL2hpZ2hjaGFydHMvYmxvYi8zYWQ0MzBhMzUzYjgwNTZiOWU3NjRhYTRlNWNkNjgyOGFhNDc5ZGIyL2pzL3BhcnRzL0NoYXJ0LmpzI0wyNDFcbiAgICAgICAgKi9cbiAgICAgIHRvb2x0aXA6IHt9XG4gICAgfSk7XG5cbiAgICAodXNlck9wdGlvbnMuc2VyaWVzIHx8IFtdKS5mb3JFYWNoKGZ1bmN0aW9uIChzZXJpZXMpIHtcbiAgICAgIHNlcmllcy5hbmltYXRpb24gPSBmYWxzZTtcbiAgICB9KTtcblxuICAgIC8vIEFkZCBmbGFnIHRvIGtub3cgaWYgY2hhcnQgcmVuZGVyIGhhcyBiZWVuIGNhbGxlZC5cbiAgICBpZiAoIXdpbmRvdy5vbkhpZ2hjaGFydHNSZW5kZXIpIHtcbiAgICAgIHdpbmRvdy5vbkhpZ2hjaGFydHNSZW5kZXIgPSBIaWdoY2hhcnRzLmFkZEV2ZW50KHRoaXMsICdyZW5kZXInLCAoKSA9PiB7XG4gICAgICAgIHdpbmRvdy5pc1JlbmRlckNvbXBsZXRlID0gdHJ1ZTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHByb2NlZWQuYXBwbHkodGhpcywgW3VzZXJPcHRpb25zLCBjYl0pO1xuICB9KTtcblxuICB3cmFwKEhpZ2hjaGFydHMuU2VyaWVzLnByb3RvdHlwZSwgJ2luaXQnLCBmdW5jdGlvbiAocHJvY2VlZCwgY2hhcnQsIG9wdGlvbnMpIHtcbiAgICBwcm9jZWVkLmFwcGx5KHRoaXMsIFtjaGFydCwgb3B0aW9uc10pO1xuICB9KTtcblxuICAvLyBHZXQgdGhlIHVzZXIgb3B0aW9uc1xuICBjb25zdCB1c2VyT3B0aW9ucyA9IG9wdGlvbnMuZXhwb3J0LnN0cklualxuICAgID8gbmV3IEZ1bmN0aW9uKGByZXR1cm4gJHtvcHRpb25zLmV4cG9ydC5zdHJJbmp9YCkoKVxuICAgIDogY2hhcnRPcHRpb25zO1xuXG4gIC8vIFRyaWdnZXIgY3VzdG9tIGNvZGVcbiAgaWYgKG9wdGlvbnMuY3VzdG9tTG9naWMuY3VzdG9tQ29kZSkge1xuICAgIG5ldyBGdW5jdGlvbignb3B0aW9ucycsIG9wdGlvbnMuY3VzdG9tTG9naWMuY3VzdG9tQ29kZSkodXNlck9wdGlvbnMpO1xuICB9XG5cbiAgLy8gTWVyZ2UgdGhlIGdsb2JhbE9wdGlvbnMsIHRoZW1lT3B0aW9ucywgb3B0aW9ucyBmcm9tIHRoZSB3cmFwcGVkXG4gIC8vIHNldE9wdGlvbnMgZnVuY3Rpb24gYW5kIHVzZXIgb3B0aW9ucyB0byBjcmVhdGUgdGhlIGZpbmFsIG9wdGlvbnMgb2JqZWN0XG4gIGNvbnN0IGZpbmFsT3B0aW9ucyA9IG1lcmdlKFxuICAgIGZhbHNlLFxuICAgIEpTT04ucGFyc2Uob3B0aW9ucy5leHBvcnQudGhlbWVPcHRpb25zKSxcbiAgICB1c2VyT3B0aW9ucyxcbiAgICAvLyBQbGFjZWQgaXQgaGVyZSBpbnN0ZWFkIGluIHRoZSBpbml0IGJlY2F1c2Ugb2YgdGhlIHNpemUgaXNzdWVzXG4gICAgeyBjaGFydCB9XG4gICk7XG5cbiAgY29uc3QgZmluYWxDYWxsYmFjayA9IG9wdGlvbnMuY3VzdG9tTG9naWMuY2FsbGJhY2tcbiAgICA/IG5ldyBGdW5jdGlvbihgcmV0dXJuICR7b3B0aW9ucy5jdXN0b21Mb2dpYy5jYWxsYmFja31gKSgpXG4gICAgOiB1bmRlZmluZWQ7XG5cbiAgLy8gU2V0IHRoZSBnbG9iYWwgb3B0aW9ucyBpZiBleGlzdFxuICBjb25zdCBnbG9iYWxPcHRpb25zID0gSlNPTi5wYXJzZShvcHRpb25zLmV4cG9ydC5nbG9iYWxPcHRpb25zKTtcbiAgaWYgKGdsb2JhbE9wdGlvbnMpIHtcbiAgICBzZXRPcHRpb25zKGdsb2JhbE9wdGlvbnMpO1xuICB9XG5cbiAgbGV0IGNvbnN0ciA9IG9wdGlvbnMuZXhwb3J0LmNvbnN0ciB8fCAnY2hhcnQnO1xuICBjb25zdHIgPSB0eXBlb2YgSGlnaGNoYXJ0c1tjb25zdHJdICE9PSAndW5kZWZpbmVkJyA/IGNvbnN0ciA6ICdjaGFydCc7XG5cbiAgSGlnaGNoYXJ0c1tjb25zdHJdKCdjb250YWluZXInLCBmaW5hbE9wdGlvbnMsIGZpbmFsQ2FsbGJhY2spO1xuXG4gIC8vIEdldCB0aGUgY3VycmVudCBnbG9iYWwgb3B0aW9uc1xuICBjb25zdCBkZWZhdWx0T3B0aW9ucyA9IGdldE9wdGlvbnMoKTtcblxuICAvLyBDbGVhciBpdCBqdXN0IGluIGNhc2UgKGUuZy4gdGhlIHNldE9wdGlvbnMgd2FzIHVzZWQgaW4gdGhlIGN1c3RvbUNvZGUpXG4gIGZvciAoY29uc3QgcHJvcCBpbiBkZWZhdWx0T3B0aW9ucykge1xuICAgIGlmICh0eXBlb2YgZGVmYXVsdE9wdGlvbnNbcHJvcF0gIT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGRlbGV0ZSBkZWZhdWx0T3B0aW9uc1twcm9wXTtcbiAgICB9XG4gIH1cblxuICAvLyBTZXQgdGhlIGRlZmF1bHQgb3B0aW9ucyBiYWNrXG4gIHNldE9wdGlvbnMoSGlnaGNoYXJ0cy5zZXRPcHRpb25zT2JqKTtcblxuICAvLyBFbXB0eSB0aGUgY3VzdG9tIGdsb2JhbCBvcHRpb25zIG9iamVjdFxuICBIaWdoY2hhcnRzLnNldE9wdGlvbnNPYmogPSB7fTtcbn1cbiIsIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG5cbkhpZ2hjaGFydHMgRXhwb3J0IFNlcnZlclxuXG5Db3B5cmlnaHQgKGMpIDIwMTYtMjAyNCwgSGlnaHNvZnRcblxuTGljZW5jZWQgdW5kZXIgdGhlIE1JVCBsaWNlbmNlLlxuXG5BZGRpdGlvbmFsbHkgYSB2YWxpZCBIaWdoY2hhcnRzIGxpY2Vuc2UgaXMgcmVxdWlyZWQgZm9yIHVzZS5cblxuU2VlIExJQ0VOU0UgZmlsZSBpbiByb290IGZvciBkZXRhaWxzLlxuXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG5pbXBvcnQgeyByZWFkRmlsZVN5bmMgfSBmcm9tICdmcyc7XG5pbXBvcnQgcGF0aCBmcm9tICdwYXRoJztcblxuaW1wb3J0IHB1cHBldGVlciBmcm9tICdwdXBwZXRlZXInO1xuXG5pbXBvcnQgeyBnZXRDYWNoZVBhdGggfSBmcm9tICcuL2NhY2hlLmpzJztcbmltcG9ydCB7IGdldE9wdGlvbnMgfSBmcm9tICcuL2NvbmZpZy5qcyc7XG5pbXBvcnQgeyBzZXR1cEhpZ2hjaGFydHMgfSBmcm9tICcuL2hpZ2hjaGFydHMuanMnO1xuaW1wb3J0IHsgbG9nLCBsb2dXaXRoU3RhY2sgfSBmcm9tICcuL2xvZ2dlci5qcyc7XG5pbXBvcnQgeyBfX2Rpcm5hbWUgfSBmcm9tICcuL3V0aWxzLmpzJztcblxuaW1wb3J0IEV4cG9ydEVycm9yIGZyb20gJy4vZXJyb3JzL0V4cG9ydEVycm9yLmpzJztcblxuLy8gR2V0IHRoZSB0ZW1wbGF0ZSBmb3IgdGhlIHBhZ2VcbmNvbnN0IHRlbXBsYXRlID0gcmVhZEZpbGVTeW5jKF9fZGlybmFtZSArICcvdGVtcGxhdGVzL3RlbXBsYXRlLmh0bWwnLCAndXRmOCcpO1xuXG5sZXQgYnJvd3NlcjtcblxuLyoqXG4gKiBSZXRyaWV2ZXMgdGhlIGV4aXN0aW5nIFB1cHBldGVlciBicm93c2VyIGluc3RhbmNlLlxuICpcbiAqIEByZXR1cm5zIHtQcm9taXNlPG9iamVjdD59IEEgUHJvbWlzZSByZXNvbHZpbmcgdG8gdGhlIFB1cHBldGVlciBicm93c2VyXG4gKiBpbnN0YW5jZS5cbiAqXG4gKiBAdGhyb3dzIHtFeHBvcnRFcnJvcn0gVGhyb3dzIGFuIEV4cG9ydEVycm9yIGlmIG5vIHZhbGlkIGJyb3dzZXIgaGFzIGJlZW5cbiAqIGNyZWF0ZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXQoKSB7XG4gIGlmICghYnJvd3Nlcikge1xuICAgIHRocm93IG5ldyBFeHBvcnRFcnJvcignW2Jyb3dzZXJdIE5vIHZhbGlkIGJyb3dzZXIgaGFzIGJlZW4gY3JlYXRlZC4nKTtcbiAgfVxuICByZXR1cm4gYnJvd3Nlcjtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgUHVwcGV0ZWVyIGJyb3dzZXIgaW5zdGFuY2Ugd2l0aCB0aGUgc3BlY2lmaWVkIGFyZ3VtZW50cy5cbiAqXG4gKiBAcGFyYW0ge0FycmF5fSBwdXBwZXRlZXJBcmdzIC0gQWRkaXRpb25hbCBhcmd1bWVudHMgZm9yIFB1cHBldGVlciBsYXVuY2guXG4gKlxuICogQHJldHVybnMge1Byb21pc2U8b2JqZWN0Pn0gQSBQcm9taXNlIHJlc29sdmluZyB0byB0aGUgUHVwcGV0ZWVyIGJyb3dzZXJcbiAqIGluc3RhbmNlLlxuICpcbiAqIEB0aHJvd3Mge0V4cG9ydEVycm9yfSBUaHJvd3MgYW4gRXhwb3J0RXJyb3IgaWYgbWF4IHJldHJpZXMgdG8gb3BlbiBhIGJyb3dzZXJcbiAqIGluc3RhbmNlIGFyZSByZWFjaGVkLCBvciBpZiBubyBicm93c2VyIGluc3RhbmNlIGlzIGZvdW5kIGFmdGVyIHJldHJpZXMuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjcmVhdGUocHVwcGV0ZWVyQXJncykge1xuICAvLyBHZXQgZGVidWcgYW5kIG90aGVyIG9wdGlvbnNcbiAgY29uc3QgeyBwdXBwZXRlZXI6IHB1cHBldGVlck9wdGlvbnMsIGRlYnVnLCBvdGhlciB9ID0gZ2V0T3B0aW9ucygpO1xuXG4gIC8vIEdldCB0aGUgZGVidWcgb3B0aW9uc1xuICBjb25zdCB7IGVuYWJsZTogZW5hYmxlZERlYnVnLCAuLi5kZWJ1Z09wdGlvbnMgfSA9IGRlYnVnO1xuXG4gIGNvbnN0IGxhdW5jaE9wdGlvbnMgPSB7XG4gICAgaGVhZGxlc3M6IG90aGVyLmJyb3dzZXJTaGVsbE1vZGUgPyAnc2hlbGwnIDogdHJ1ZSxcbiAgICB1c2VyRGF0YURpcjogcHVwcGV0ZWVyT3B0aW9ucy50ZW1wRGlyIHx8ICcuL3RtcC8nLFxuICAgIGFyZ3M6IHB1cHBldGVlckFyZ3MsXG4gICAgaGFuZGxlU0lHSU5UOiBmYWxzZSxcbiAgICBoYW5kbGVTSUdURVJNOiBmYWxzZSxcbiAgICBoYW5kbGVTSUdIVVA6IGZhbHNlLFxuICAgIHdhaXRGb3JJbml0aWFsUGFnZTogZmFsc2UsXG4gICAgZGVmYXVsdFZpZXdwb3J0OiBudWxsLFxuICAgIC4uLihlbmFibGVkRGVidWcgJiYgZGVidWdPcHRpb25zKVxuICB9O1xuXG4gIC8vIENyZWF0ZSBhIGJyb3dzZXJcbiAgaWYgKCFicm93c2VyKSB7XG4gICAgY29uc3QgbWF4VHJpZXMgPSAyNTtcbiAgICBsZXQgdHJ5Q291bnQgPSAwO1xuXG4gICAgY29uc3Qgb3BlbiA9IGFzeW5jICgpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGxvZyhcbiAgICAgICAgICAzLFxuICAgICAgICAgIGBbYnJvd3Nlcl0gQXR0ZW1wdGluZyB0byBnZXQgYSBicm93c2VyIGluc3RhbmNlICh0cnkgJHsrK3RyeUNvdW50fSkuYFxuICAgICAgICApO1xuICAgICAgICBicm93c2VyID0gYXdhaXQgcHVwcGV0ZWVyLmxhdW5jaChsYXVuY2hPcHRpb25zKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIC8vIFRoaXMgaXNuJ3QgYSBmdWxsIGVycm9yIHlldCBhcyBwdXBwZXRlZXIgc29tZXRpbWVzIHRha2VzIHRpbWUgdG9cbiAgICAgICAgLy8gaW5pdGlhbGl6ZSBwcm9wZXJseS5cbiAgICAgICAgbG9nV2l0aFN0YWNrKFxuICAgICAgICAgIDIsXG4gICAgICAgICAgZXJyb3IsXG4gICAgICAgICAgYFticm93c2VyXSBGYWlsZWQgdG8gbGF1bmNoIGEgYnJvd3NlciBpbnN0YW5jZSAtIHJldHJ5aW5nIChhdHRlbXB0ICR7dHJ5Q291bnR9LyR7bWF4VHJpZXN9KS5gXG4gICAgICAgICk7XG5cbiAgICAgICAgLy8gUmV0cnkgdG8gbGF1bmNoIGJyb3dzZXIgdW50aWwgcmVhY2hpbmcgbWF4IGF0dGVtcHRzXG4gICAgICAgIGlmICh0cnlDb3VudCA8IDI1KSB7XG4gICAgICAgICAgbG9nKFxuICAgICAgICAgICAgMyxcbiAgICAgICAgICAgIGBbYnJvd3Nlcl0gUmV0cnkgdG8gb3BlbiBhIGJyb3dzZXIgKGF0dGVtcHQgJHt0cnlDb3VudH0vJHttYXhUcmllc30pLmBcbiAgICAgICAgICApO1xuICAgICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKChyZXNwb25zZSkgPT4gc2V0VGltZW91dChyZXNwb25zZSwgNDAwMCkpO1xuICAgICAgICAgIGF3YWl0IG9wZW4oKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLy4uLiBub3cgaXQncyBhbiBlcnJvciwgd2hpY2ggaXMgY2F1Z2h0IGJ5IHRoZSBjYWxsZXJcbiAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgb3BlbigpO1xuXG4gICAgICAvLyBTaGVsbCBtb2RlIGluZm9ybVxuICAgICAgaWYgKGxhdW5jaE9wdGlvbnMuaGVhZGxlc3MgPT09ICdzaGVsbCcpIHtcbiAgICAgICAgbG9nKDMsIGBbYnJvd3Nlcl0gTGF1bmNoZWQgYnJvd3NlciBpbiBzaGVsbCBtb2RlLmApO1xuICAgICAgfVxuXG4gICAgICAvLyBEZWJ1ZyBtb2RlIGluZm9ybVxuICAgICAgaWYgKGVuYWJsZWREZWJ1Zykge1xuICAgICAgICBsb2coMywgYFticm93c2VyXSBMYXVuY2hlZCBicm93c2VyIGluIGRlYnVnIG1vZGUuYCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRocm93IG5ldyBFeHBvcnRFcnJvcihcbiAgICAgICAgJ1ticm93c2VyXSBNYXhpbXVtIHJldHJpZXMgdG8gb3BlbiBhIGJyb3dzZXIgaW5zdGFuY2UgcmVhY2hlZC4nXG4gICAgICApLnNldEVycm9yKGVycm9yKTtcbiAgICB9XG5cbiAgICBpZiAoIWJyb3dzZXIpIHtcbiAgICAgIHRocm93IG5ldyBFeHBvcnRFcnJvcignW2Jyb3dzZXJdIENhbm5vdCBmaW5kIGEgYnJvd3NlciB0byBvcGVuLicpO1xuICAgIH1cbiAgfVxuXG4gIC8vIFJldHVybiBhIGJyb3dzZXIgcHJvbWlzZVxuICByZXR1cm4gYnJvd3Nlcjtcbn1cblxuLyoqXG4gKiBDbG9zZXMgdGhlIFB1cHBldGVlciBicm93c2VyIGluc3RhbmNlIGlmIGl0IGlzIGNvbm5lY3RlZC5cbiAqXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxib29sZWFuPn0gQSBQcm9taXNlIHJlc29sdmluZyB0byB0cnVlIGFmdGVyIHRoZSBicm93c2VyXG4gKiBpcyBjbG9zZWQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjbG9zZSgpIHtcbiAgLy8gQ2xvc2UgdGhlIGJyb3dzZXIgd2hlbiBjb25ubmVjdGVkXG4gIGlmIChicm93c2VyPy5jb25uZWN0ZWQpIHtcbiAgICBhd2FpdCBicm93c2VyLmNsb3NlKCk7XG4gIH1cbiAgbG9nKDQsICdbYnJvd3Nlcl0gQ2xvc2VkIHRoZSBicm93c2VyLicpO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgUHVwcGV0ZWVyIFBhZ2Ugd2l0aGluIGFuIGV4aXN0aW5nIGJyb3dzZXIgaW5zdGFuY2UuXG4gKlxuICogSWYgdGhlIGJyb3dzZXIgaW5zdGFuY2UgaXMgbm90IGF2YWlsYWJsZSwgcmV0dXJucyBmYWxzZS5cbiAqXG4gKiBUaGUgZnVuY3Rpb24gY3JlYXRlcyBhIG5ldyBwYWdlLCBkaXNhYmxlcyBjYWNoaW5nLCBzZXRzIGNvbnRlbnQgdXNpbmdcbiAqIHNldFBhZ2VDb250ZW50KCksIGFuZCByZXR1cm5zIHRoZSBjcmVhdGVkIFB1cHBldGVlciBQYWdlLlxuICpcbiAqIEByZXR1cm5zIHsoYm9vbGVhbnxvYmplY3QpfSBSZXR1cm5zIGZhbHNlIGlmIHRoZSBicm93c2VyIGluc3RhbmNlIGlzIG5vdFxuICogYXZhaWxhYmxlLCBvciBhIFB1cHBldGVlciBQYWdlIG9iamVjdCByZXByZXNlbnRpbmcgdGhlIG5ld2x5IGNyZWF0ZWQgcGFnZS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG5ld1BhZ2UoKSB7XG4gIGlmICghYnJvd3Nlcikge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIENyZWF0ZSBhIHBhZ2VcbiAgY29uc3QgcGFnZSA9IGF3YWl0IGJyb3dzZXIubmV3UGFnZSgpO1xuXG4gIC8vIERpc2FibGUgY2FjaGVcbiAgYXdhaXQgcGFnZS5zZXRDYWNoZUVuYWJsZWQoZmFsc2UpO1xuXG4gIC8vIFNldCB0aGUgY29udGVudFxuICBhd2FpdCBzZXRQYWdlQ29udGVudChwYWdlKTtcblxuICAvLyBTZXQgcGFnZSBldmVudHNcbiAgc2V0UGFnZUV2ZW50cyhwYWdlKTtcblxuICByZXR1cm4gcGFnZTtcbn1cblxuLyoqXG4gKiBDbGVhcnMgdGhlIGNvbnRlbnQgb2YgYSBQdXBwZXRlZXIgUGFnZSBiYXNlZCBvbiB0aGUgc3BlY2lmaWVkIG1vZGUuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHBhZ2UgLSBUaGUgUHVwcGV0ZWVyIFBhZ2Ugb2JqZWN0IHRvIGJlIGNsZWFyZWQuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGhhcmRSZXNldCAtIEEgZmxhZyBpbmRpY2F0aW5nIHRoZSB0eXBlIG9mIGNsZWFyaW5nXG4gKiB0byBiZSBwZXJmb3JtZWQuIElmIHRydWUsIG5hdmlnYXRlcyB0byAnYWJvdXQ6YmxhbmsnIGFuZCByZXNldHMgY29udGVudFxuICogYW5kIHNjcmlwdHMuIElmIGZhbHNlLCBjbGVhcnMgdGhlIGJvZHkgY29udGVudCBieSBzZXR0aW5nIGEgcHJlZGVmaW5lZCBIVE1MXG4gKiBzdHJ1Y3R1cmUuXG4gKlxuICogQHRocm93cyB7RXJyb3J9IExvZ3MgdGhyb3duIGVycm9yIGlmIGNsZWFyaW5nIHRoZSBwYWdlIGNvbnRlbnQgZmFpbHMuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjbGVhclBhZ2UocGFnZSwgaGFyZFJlc2V0ID0gZmFsc2UpIHtcbiAgdHJ5IHtcbiAgICBpZiAocGFnZSAmJiAhcGFnZS5pc0Nsb3NlZCgpKSB7XG4gICAgICBpZiAoaGFyZFJlc2V0KSB7XG4gICAgICAgIC8vIE5hdmlnYXRlIHRvIGFib3V0OmJsYW5rXG4gICAgICAgIGF3YWl0IHBhZ2UuZ290bygnYWJvdXQ6YmxhbmsnLCB7IHdhaXRVbnRpbDogJ2RvbWNvbnRlbnRsb2FkZWQnIH0pO1xuXG4gICAgICAgIC8vIFNldCB0aGUgY29udGVudCBhbmQgYW5kIHNjcmlwdHMgYWdhaW5cbiAgICAgICAgYXdhaXQgc2V0UGFnZUNvbnRlbnQocGFnZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBDbGVhciBib2R5IGNvbnRlbnRcbiAgICAgICAgYXdhaXQgcGFnZS5ldmFsdWF0ZSgoKSA9PiB7XG4gICAgICAgICAgZG9jdW1lbnQuYm9keS5pbm5lckhUTUwgPVxuICAgICAgICAgICAgJzxkaXYgaWQ9XCJjaGFydC1jb250YWluZXJcIj48ZGl2IGlkPVwiY29udGFpbmVyXCI+PC9kaXY+PC9kaXY+JztcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgbG9nV2l0aFN0YWNrKFxuICAgICAgMixcbiAgICAgIGVycm9yLFxuICAgICAgJ1ticm93c2VyXSBDb3VsZCBub3QgY2xlYXIgdGhlIGNvbnRlbnQgb2YgdGhlIHBhZ2UuJ1xuICAgICk7XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogQWRkcyBjdXN0b20gSlMgYW5kIENTUyByZXNvdXJjZXMgdG8gYSBQdXBwZXRlZXIgUGFnZSBiYXNlZCBvbiB0aGUgc3BlY2lmaWVkXG4gKiBvcHRpb25zLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYWdlIC0gVGhlIFB1cHBldGVlciBQYWdlIG9iamVjdCB0byB3aGljaCByZXNvdXJjZXMgd2lsbCBiZVxuICogYWRkZWQuXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIEFsbCBvcHRpb25zIGFuZCBjb25maWd1cmF0aW9uLlxuICpcbiAqIEByZXR1cm5zIHtQcm9taXNlPEFycmF5PE9iamVjdD4+fSAtIFByb21pc2UgcmVzb2x2aW5nIHRvIGFuIGFycmF5IG9mIGluamVjdGVkXG4gKiByZXNvdXJjZXMuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBhZGRQYWdlUmVzb3VyY2VzKHBhZ2UsIG9wdGlvbnMpIHtcbiAgLy8gSW5qZWN0ZWQgcmVzb3VyY2VzIGFycmF5XG4gIGNvbnN0IGluamVjdGVkUmVzb3VyY2VzID0gW107XG5cbiAgLy8gVXNlIHJlc291cmNlc1xuICBjb25zdCByZXNvdXJjZXMgPSBvcHRpb25zLmN1c3RvbUxvZ2ljLnJlc291cmNlcztcbiAgaWYgKHJlc291cmNlcykge1xuICAgIGNvbnN0IGluamVjdGVkSnMgPSBbXTtcblxuICAgIC8vIExvYWQgY3VzdG9tIEpTIGNvZGVcbiAgICBpZiAocmVzb3VyY2VzLmpzKSB7XG4gICAgICBpbmplY3RlZEpzLnB1c2goe1xuICAgICAgICBjb250ZW50OiByZXNvdXJjZXMuanNcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIExvYWQgc2NyaXB0cyBmcm9tIGFsbCBjdXN0b20gZmlsZXNcbiAgICBpZiAocmVzb3VyY2VzLmZpbGVzKSB7XG4gICAgICBmb3IgKGNvbnN0IGZpbGUgb2YgcmVzb3VyY2VzLmZpbGVzKSB7XG4gICAgICAgIGNvbnN0IGlzTG9jYWwgPSAhZmlsZS5zdGFydHNXaXRoKCdodHRwJykgPyB0cnVlIDogZmFsc2U7XG5cbiAgICAgICAgLy8gQWRkIGVhY2ggY3VzdG9tIHNjcmlwdCBmcm9tIHJlc291cmNlcycgZmlsZXNcbiAgICAgICAgaW5qZWN0ZWRKcy5wdXNoKFxuICAgICAgICAgIGlzTG9jYWxcbiAgICAgICAgICAgID8ge1xuICAgICAgICAgICAgICAgIGNvbnRlbnQ6IHJlYWRGaWxlU3luYyhmaWxlLCAndXRmOCcpXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDoge1xuICAgICAgICAgICAgICAgIHVybDogZmlsZVxuICAgICAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBqc1Jlc291cmNlIG9mIGluamVjdGVkSnMpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGluamVjdGVkUmVzb3VyY2VzLnB1c2goYXdhaXQgcGFnZS5hZGRTY3JpcHRUYWcoanNSZXNvdXJjZSkpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgbG9nV2l0aFN0YWNrKDIsIGVycm9yLCBgW2V4cG9ydF0gVGhlIEpTIHJlc291cmNlIGNhbm5vdCBiZSBsb2FkZWQuYCk7XG4gICAgICB9XG4gICAgfVxuICAgIGluamVjdGVkSnMubGVuZ3RoID0gMDtcblxuICAgIC8vIExvYWQgQ1NTXG4gICAgY29uc3QgaW5qZWN0ZWRDc3MgPSBbXTtcbiAgICBpZiAocmVzb3VyY2VzLmNzcykge1xuICAgICAgbGV0IGNzc0ltcG9ydHMgPSByZXNvdXJjZXMuY3NzLm1hdGNoKC9AaW1wb3J0XFxzKihbXjtdKik7L2cpO1xuICAgICAgaWYgKGNzc0ltcG9ydHMpIHtcbiAgICAgICAgLy8gSGFuZGxlIGNzcyBzZWN0aW9uXG4gICAgICAgIGZvciAobGV0IGNzc0ltcG9ydFBhdGggb2YgY3NzSW1wb3J0cykge1xuICAgICAgICAgIGlmIChjc3NJbXBvcnRQYXRoKSB7XG4gICAgICAgICAgICBjc3NJbXBvcnRQYXRoID0gY3NzSW1wb3J0UGF0aFxuICAgICAgICAgICAgICAucmVwbGFjZSgndXJsKCcsICcnKVxuICAgICAgICAgICAgICAucmVwbGFjZSgnQGltcG9ydCcsICcnKVxuICAgICAgICAgICAgICAucmVwbGFjZSgvXCIvZywgJycpXG4gICAgICAgICAgICAgIC5yZXBsYWNlKC8nL2csICcnKVxuICAgICAgICAgICAgICAucmVwbGFjZSgvOy8sICcnKVxuICAgICAgICAgICAgICAucmVwbGFjZSgvXFwpL2csICcnKVxuICAgICAgICAgICAgICAudHJpbSgpO1xuXG4gICAgICAgICAgICAvLyBBZGQgZWFjaCBjdXN0b20gY3NzIGZyb20gcmVzb3VyY2VzXG4gICAgICAgICAgICBpZiAoY3NzSW1wb3J0UGF0aC5zdGFydHNXaXRoKCdodHRwJykpIHtcbiAgICAgICAgICAgICAgaW5qZWN0ZWRDc3MucHVzaCh7XG4gICAgICAgICAgICAgICAgdXJsOiBjc3NJbXBvcnRQYXRoXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChvcHRpb25zLmN1c3RvbUxvZ2ljLmFsbG93RmlsZVJlc291cmNlcykge1xuICAgICAgICAgICAgICBpbmplY3RlZENzcy5wdXNoKHtcbiAgICAgICAgICAgICAgICBwYXRoOiBwYXRoLmpvaW4oX19kaXJuYW1lLCBjc3NJbXBvcnRQYXRoKVxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gVGhlIHJlc3Qgb2YgdGhlIENTUyBzZWN0aW9uIHdpbGwgYmUgY29udGVudCBieSBub3dcbiAgICAgIGluamVjdGVkQ3NzLnB1c2goe1xuICAgICAgICBjb250ZW50OiByZXNvdXJjZXMuY3NzLnJlcGxhY2UoL0BpbXBvcnRcXHMqKFteO10qKTsvZywgJycpIHx8ICcgJ1xuICAgICAgfSk7XG5cbiAgICAgIGZvciAoY29uc3QgY3NzUmVzb3VyY2Ugb2YgaW5qZWN0ZWRDc3MpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBpbmplY3RlZFJlc291cmNlcy5wdXNoKGF3YWl0IHBhZ2UuYWRkU3R5bGVUYWcoY3NzUmVzb3VyY2UpKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICBsb2dXaXRoU3RhY2soMiwgZXJyb3IsIGBbZXhwb3J0XSBUaGUgQ1NTIHJlc291cmNlIGNhbm5vdCBiZSBsb2FkZWQuYCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGluamVjdGVkQ3NzLmxlbmd0aCA9IDA7XG4gICAgfVxuICB9XG4gIHJldHVybiBpbmplY3RlZFJlc291cmNlcztcbn1cblxuLyoqXG4gKiBDbGVhcnMgb3V0IGFsbCBzdGF0ZSBzZXQgb24gdGhlIHBhZ2Ugd2l0aCBhZGRTY3JpcHRUYWcvYWRkU3R5bGVUYWcuIFJlbW92ZXNcbiAqIGluamVjdGVkIHJlc291cmNlcyBhbmQgcmVzZXRzIENTUyBhbmQgc2NyaXB0IHRhZ3Mgb24gdGhlIHBhZ2UuIEFkZGl0aW9uYWxseSxcbiAqIGl0IGRlc3Ryb3lzIHByZXZpb3VzbHkgZXhpc3RpbmcgY2hhcnRzLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYWdlIC0gVGhlIFB1cHBldGVlciBQYWdlIG9iamVjdCBmcm9tIHdoaWNoIHJlc291cmNlcyB3aWxsXG4gKiBiZSBjbGVhcmVkLlxuICogQHBhcmFtIHtBcnJheTxPYmplY3Q+fSBpbmplY3RlZFJlc291cmNlcyAtIEFycmF5IG9mIGluamVjdGVkIHJlc291cmNlc1xuICogdG8gYmUgY2xlYXJlZC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNsZWFyUGFnZVJlc291cmNlcyhwYWdlLCBpbmplY3RlZFJlc291cmNlcykge1xuICB0cnkge1xuICAgIGZvciAoY29uc3QgcmVzb3VyY2Ugb2YgaW5qZWN0ZWRSZXNvdXJjZXMpIHtcbiAgICAgIGF3YWl0IHJlc291cmNlLmRpc3Bvc2UoKTtcbiAgICB9XG5cbiAgICAvLyBEZXN0cm95IG9sZCBjaGFydHMgYWZ0ZXIgZXhwb3J0IGlzIGRvbmUgYW5kIHJlc2V0IGFsbCBDU1MgYW5kIHNjcmlwdCB0YWdzXG4gICAgYXdhaXQgcGFnZS5ldmFsdWF0ZSgoKSA9PiB7XG4gICAgICAvLyBXZSBhcmUgbm90IGd1YXJhbnRlZWQgdGhhdCBIaWdoY2hhcnRzIGlzIGxvYWRlZCwgZSxnLCB3aGVuIGRvaW5nIFNWR1xuICAgICAgLy8gZXhwb3J0c1xuICAgICAgaWYgKHR5cGVvZiBIaWdoY2hhcnRzICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW5kZWZcbiAgICAgICAgY29uc3Qgb2xkQ2hhcnRzID0gSGlnaGNoYXJ0cy5jaGFydHM7XG5cbiAgICAgICAgLy8gQ2hlY2sgaW4gYW55IGFscmVhZHkgZXhpc3RpbmcgY2hhcnRzXG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KG9sZENoYXJ0cykgJiYgb2xkQ2hhcnRzLmxlbmd0aCkge1xuICAgICAgICAgIC8vIERlc3Ryb3kgb2xkIGNoYXJ0c1xuICAgICAgICAgIGZvciAoY29uc3Qgb2xkQ2hhcnQgb2Ygb2xkQ2hhcnRzKSB7XG4gICAgICAgICAgICBvbGRDaGFydCAmJiBvbGRDaGFydC5kZXN0cm95KCk7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW5kZWZcbiAgICAgICAgICAgIEhpZ2hjaGFydHMuY2hhcnRzLnNoaWZ0KCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bmRlZlxuICAgICAgY29uc3QgWy4uLnNjcmlwdHNUb1JlbW92ZV0gPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnc2NyaXB0Jyk7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW5kZWZcbiAgICAgIGNvbnN0IFssIC4uLnN0eWxlc1RvUmVtb3ZlXSA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdzdHlsZScpO1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVuZGVmXG4gICAgICBjb25zdCBbLi4ubGlua3NUb1JlbW92ZV0gPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnbGluaycpO1xuXG4gICAgICAvLyBSZW1vdmUgdGFnc1xuICAgICAgZm9yIChjb25zdCBlbGVtZW50IG9mIFtcbiAgICAgICAgLi4uc2NyaXB0c1RvUmVtb3ZlLFxuICAgICAgICAuLi5zdHlsZXNUb1JlbW92ZSxcbiAgICAgICAgLi4ubGlua3NUb1JlbW92ZVxuICAgICAgXSkge1xuICAgICAgICBlbGVtZW50LnJlbW92ZSgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGxvZ1dpdGhTdGFjaygyLCBlcnJvciwgYFticm93c2VyXSBDb3VsZCBub3QgY2xlYXIgcGFnZSdzIHJlc291cmNlcy5gKTtcbiAgfVxufVxuXG4vKipcbiAqIFNldHMgdGhlIGNvbnRlbnQgZm9yIGEgUHVwcGV0ZWVyIFBhZ2UgdXNpbmcgYSBwcmVkZWZpbmVkIHRlbXBsYXRlXG4gKiBhbmQgYWRkaXRpb25hbCBzY3JpcHRzLiBBbHNvLCBzZXRzIHRoZSBwYWdlZXJyb3IgaW4gb3JkZXIgdG8gY2F0Y2hcbiAqIGFuZCBkaXNwbGF5IGVycm9ycyBmcm9tIHRoZSB3aW5kb3cgY29udGV4dC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gcGFnZSAtIFRoZSBQdXBwZXRlZXIgUGFnZSBvYmplY3QgZm9yIHdoaWNoIHRoZSBjb250ZW50XG4gKiBpcyBiZWluZyBzZXQuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHNldFBhZ2VDb250ZW50KHBhZ2UpIHtcbiAgYXdhaXQgcGFnZS5zZXRDb250ZW50KHRlbXBsYXRlLCB7IHdhaXRVbnRpbDogJ2RvbWNvbnRlbnRsb2FkZWQnIH0pO1xuXG4gIC8vIEFkZCBhbGwgcmVnaXN0ZXJlZCBIaWdjaGFydHMgc2NyaXB0cywgcXVpdGUgZGVtYW5kaW5nXG4gIGF3YWl0IHBhZ2UuYWRkU2NyaXB0VGFnKHsgcGF0aDogYCR7Z2V0Q2FjaGVQYXRoKCl9L3NvdXJjZXMuanNgIH0pO1xuXG4gIC8vIFNldCB0aGUgaW5pdGlhbCBhbmltT2JqZWN0XG4gIGF3YWl0IHBhZ2UuZXZhbHVhdGUoc2V0dXBIaWdoY2hhcnRzKTtcbn1cblxuLyoqXG4gKiBTZXQgZXZlbnRzIGZvciBhIFB1cHBldGVlciBQYWdlLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYWdlIC0gVGhlIFB1cHBldGVlciBQYWdlIG9iamVjdCB0byBzZXQgZXZlbnRzIHRvLlxuICovXG5mdW5jdGlvbiBzZXRQYWdlRXZlbnRzKHBhZ2UpIHtcbiAgLy8gR2V0IGRlYnVnIG9wdGlvbnNcbiAgY29uc3QgeyBkZWJ1ZyB9ID0gZ2V0T3B0aW9ucygpO1xuXG4gIC8vIFNldCB0aGUgY29uc29sZSBsaXN0ZW5lciwgaWYgbmVlZGVkXG4gIGlmIChkZWJ1Zy5lbmFibGUgJiYgZGVidWcubGlzdGVuVG9Db25zb2xlKSB7XG4gICAgcGFnZS5vbignY29uc29sZScsIChtZXNzYWdlKSA9PiB7XG4gICAgICBjb25zb2xlLmxvZyhgW2RlYnVnXSAke21lc3NhZ2UudGV4dCgpfWApO1xuICAgIH0pO1xuICB9XG5cbiAgLy8gU2V0IHRoZSBwYWdlZXJyb3IgbGlzdGVuZXJcbiAgcGFnZS5vbigncGFnZWVycm9yJywgYXN5bmMgKGVycm9yKSA9PiB7XG4gICAgLy8gSXQgd291bGQgc2VlbSBsaWtlIHRoaXMgbWF5IGZpcmUgYXQgdGhlIHNhbWUgdGltZSBvciBzaG9ydGx5IGJlZm9yZVxuICAgIC8vIGEgcGFnZSBpcyBjbG9zZWQuXG4gICAgaWYgKHBhZ2UuaXNDbG9zZWQoKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFRPRE86IENvbnNpZGVyIGFkZGluZyBhIHN3aXRjaCBoZXJlIHRoYXQgdHVybnMgb24gbG9nKDApIGxvZ2dpbmdcbiAgICAvLyBvbiBwYWdlIGVycm9ycy5cbiAgICBhd2FpdCBwYWdlLiRldmFsKFxuICAgICAgJyNjb250YWluZXInLFxuICAgICAgKGVsZW1lbnQsIGVycm9yTWVzc2FnZSkgPT4ge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW5kZWZcbiAgICAgICAgaWYgKHdpbmRvdy5fZGlzcGxheUVycm9ycykge1xuICAgICAgICAgIGVsZW1lbnQuaW5uZXJIVE1MID0gZXJyb3JNZXNzYWdlO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgYDxoMT5DaGFydCBpbnB1dCBkYXRhIGVycm9yOiA8L2gxPiR7ZXJyb3IudG9TdHJpbmcoKX1gXG4gICAgKTtcbiAgfSk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgZ2V0LFxuICBjcmVhdGUsXG4gIGNsb3NlLFxuICBuZXdQYWdlLFxuICBjbGVhclBhZ2UsXG4gIGFkZFBhZ2VSZXNvdXJjZXMsXG4gIGNsZWFyUGFnZVJlc291cmNlc1xufTtcbiIsIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG5cbkhpZ2hjaGFydHMgRXhwb3J0IFNlcnZlclxuXG5Db3B5cmlnaHQgKGMpIDIwMTYtMjAyNCwgSGlnaHNvZnRcblxuTGljZW5jZWQgdW5kZXIgdGhlIE1JVCBsaWNlbmNlLlxuXG5BZGRpdGlvbmFsbHkgYSB2YWxpZCBIaWdoY2hhcnRzIGxpY2Vuc2UgaXMgcmVxdWlyZWQgZm9yIHVzZS5cblxuU2VlIExJQ0VOU0UgZmlsZSBpbiByb290IGZvciBkZXRhaWxzLlxuXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG5pbXBvcnQgeyBhZGRQYWdlUmVzb3VyY2VzLCBjbGVhclBhZ2VSZXNvdXJjZXMgfSBmcm9tICcuL2Jyb3dzZXIuanMnO1xuaW1wb3J0IHsgZ2V0Q2FjaGUgfSBmcm9tICcuL2NhY2hlLmpzJztcbmltcG9ydCB7IHRyaWdnZXJFeHBvcnQgfSBmcm9tICcuL2hpZ2hjaGFydHMuanMnO1xuaW1wb3J0IHsgbG9nIH0gZnJvbSAnLi9sb2dnZXIuanMnO1xuXG5pbXBvcnQgc3ZnVGVtcGxhdGUgZnJvbSAnLi8uLi90ZW1wbGF0ZXMvc3ZnX2V4cG9ydC9zdmdfZXhwb3J0LmpzJztcblxuaW1wb3J0IEV4cG9ydEVycm9yIGZyb20gJy4vZXJyb3JzL0V4cG9ydEVycm9yLmpzJztcblxuLyoqXG4gKiBSZXRyaWV2ZXMgdGhlIGNsaXBwaW5nIHJlZ2lvbiBjb29yZGluYXRlcyBvZiB0aGUgc3BlY2lmaWVkIHBhZ2UgZWxlbWVudCB3aXRoXG4gKiB0aGUgaWQgJ2NoYXJ0LWNvbnRhaW5lcicuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHBhZ2UgLSBQdXBwZXRlZXIgcGFnZSBvYmplY3QuXG4gKlxuICogQHJldHVybnMge1Byb21pc2U8T2JqZWN0Pn0gUHJvbWlzZSByZXNvbHZpbmcgdG8gYW4gb2JqZWN0IGNvbnRhaW5pbmdcbiAqIHgsIHksIHdpZHRoLCBhbmQgaGVpZ2h0IHByb3BlcnRpZXMuXG4gKi9cbmNvbnN0IGdldENsaXBSZWdpb24gPSAocGFnZSkgPT5cbiAgcGFnZS4kZXZhbCgnI2NoYXJ0LWNvbnRhaW5lcicsIChlbGVtZW50KSA9PiB7XG4gICAgY29uc3QgeyB4LCB5LCB3aWR0aCwgaGVpZ2h0IH0gPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIHJldHVybiB7XG4gICAgICB4LFxuICAgICAgeSxcbiAgICAgIHdpZHRoLFxuICAgICAgaGVpZ2h0OiBNYXRoLnRydW5jKGhlaWdodCA+IDEgPyBoZWlnaHQgOiA1MDApXG4gICAgfTtcbiAgfSk7XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBpbWFnZSB1c2luZyBQdXBwZXRlZXIncyBwYWdlIHNjcmVlbnNob3QgZnVuY3Rpb25hbGl0eSB3aXRoXG4gKiBzcGVjaWZpZWQgb3B0aW9ucy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gcGFnZSAtIFB1cHBldGVlciBwYWdlIG9iamVjdC5cbiAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIC0gSW1hZ2UgdHlwZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBlbmNvZGluZyAtIEltYWdlIGVuY29kaW5nLlxuICogQHBhcmFtIHtPYmplY3R9IGNsaXAgLSBDbGlwcGluZyByZWdpb24gY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gcmFzdGVyaXphdGlvblRpbWVvdXQgLSBUaW1lb3V0IGZvciByYXN0ZXJpemF0aW9uXG4gKiBpbiBtaWxsaXNlY29uZHMuXG4gKlxuICogQHJldHVybnMge1Byb21pc2U8QnVmZmVyPn0gUHJvbWlzZSByZXNvbHZpbmcgdG8gdGhlIGltYWdlIGJ1ZmZlciBvciByZWplY3RpbmdcbiAqIHdpdGggYW4gRXhwb3J0RXJyb3IgZm9yIHRpbWVvdXQuXG4gKi9cbmNvbnN0IGNyZWF0ZUltYWdlID0gKHBhZ2UsIHR5cGUsIGVuY29kaW5nLCBjbGlwLCByYXN0ZXJpemF0aW9uVGltZW91dCkgPT5cbiAgUHJvbWlzZS5yYWNlKFtcbiAgICBwYWdlLnNjcmVlbnNob3Qoe1xuICAgICAgdHlwZSxcbiAgICAgIGVuY29kaW5nLFxuICAgICAgY2xpcCxcbiAgICAgIGNhcHR1cmVCZXlvbmRWaWV3cG9ydDogdHJ1ZSxcbiAgICAgIGZ1bGxQYWdlOiBmYWxzZSxcbiAgICAgIG9wdGltaXplRm9yU3BlZWQ6IHRydWUsXG4gICAgICAuLi4odHlwZSAhPT0gJ3BuZycgPyB7IHF1YWxpdHk6IDgwIH0gOiB7fSksXG5cbiAgICAgIC8vICM0NDcsICM0NjMgLSBhbHdheXMgcmVuZGVyIG9uIGEgdHJhbnNwYXJlbnQgcGFnZSBpZiB0aGUgZXhwZWN0ZWQgdHlwZVxuICAgICAgLy8gZm9ybWF0IGlzIFBOR1xuICAgICAgb21pdEJhY2tncm91bmQ6IHR5cGUgPT0gJ3BuZydcbiAgICB9KSxcbiAgICBuZXcgUHJvbWlzZSgoX3Jlc29sdmUsIHJlamVjdCkgPT5cbiAgICAgIHNldFRpbWVvdXQoXG4gICAgICAgICgpID0+IHJlamVjdChuZXcgRXhwb3J0RXJyb3IoJ1Jhc3Rlcml6YXRpb24gdGltZW91dCcpKSxcbiAgICAgICAgcmFzdGVyaXphdGlvblRpbWVvdXQgfHwgMTUwMFxuICAgICAgKVxuICAgIClcbiAgXSk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIFBERiB1c2luZyBQdXBwZXRlZXIncyBwYWdlIHBkZiBmdW5jdGlvbmFsaXR5IHdpdGggc3BlY2lmaWVkXG4gKiBvcHRpb25zLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYWdlIC0gUHVwcGV0ZWVyIHBhZ2Ugb2JqZWN0LlxuICogQHBhcmFtIHtudW1iZXJ9IGhlaWdodCAtIFBERiBoZWlnaHQuXG4gKiBAcGFyYW0ge251bWJlcn0gd2lkdGggLSBQREYgd2lkdGguXG4gKiBAcGFyYW0ge3N0cmluZ30gZW5jb2RpbmcgLSBQREYgZW5jb2RpbmcuXG4gKlxuICogQHJldHVybnMge1Byb21pc2U8QnVmZmVyPn0gUHJvbWlzZSByZXNvbHZpbmcgdG8gdGhlIFBERiBidWZmZXIuXG4gKi9cbmNvbnN0IGNyZWF0ZVBERiA9IGFzeW5jIChcbiAgcGFnZSxcbiAgaGVpZ2h0LFxuICB3aWR0aCxcbiAgZW5jb2RpbmcsXG4gIHJhc3Rlcml6YXRpb25UaW1lb3V0XG4pID0+IHtcbiAgYXdhaXQgcGFnZS5lbXVsYXRlTWVkaWFUeXBlKCdzY3JlZW4nKTtcblxuICByZXR1cm4gcGFnZS5wZGYoe1xuICAgIC8vIFRoaXMgd2lsbCByZW1vdmUgYW4gZXh0cmEgZW1wdHkgcGFnZSBpbiBQREYgZXhwb3J0c1xuICAgIGhlaWdodDogaGVpZ2h0ICsgMSxcbiAgICB3aWR0aCxcbiAgICBlbmNvZGluZyxcbiAgICB0aW1lb3V0OiByYXN0ZXJpemF0aW9uVGltZW91dCB8fCAxNTAwXG4gIH0pO1xufTtcblxuLyoqXG4gKiBDcmVhdGVzIGFuIFNWRyBzdHJpbmcgYnkgZXZhbHVhdGluZyB0aGUgb3V0ZXJIVE1MIG9mIHRoZSBmaXJzdCAnc3ZnJyBlbGVtZW50XG4gKiBpbnNpZGUgYW4gZWxlbWVudCB3aXRoIHRoZSBpZCAnY29udGFpbmVyJy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gcGFnZSAtIFB1cHBldGVlciBwYWdlIG9iamVjdC5cbiAqXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxzdHJpbmc+fSBQcm9taXNlIHJlc29sdmluZyB0byB0aGUgU1ZHIHN0cmluZy5cbiAqL1xuY29uc3QgY3JlYXRlU1ZHID0gKHBhZ2UpID0+XG4gIHBhZ2UuJGV2YWwoJyNjb250YWluZXIgc3ZnOmZpcnN0LW9mLXR5cGUnLCAoZWxlbWVudCkgPT4gZWxlbWVudC5vdXRlckhUTUwpO1xuXG4vKipcbiAqIFNldHMgdGhlIHNwZWNpZmllZCBjaGFydCBhbmQgb3B0aW9ucyBhcyBjb25maWd1cmF0aW9uIGludG8gdGhlIHRyaWdnZXJFeHBvcnRcbiAqIGZ1bmN0aW9uIHdpdGhpbiB0aGUgd2luZG93IGNvbnRleHQgdXNpbmcgcGFnZS5ldmFsdWF0ZS5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gcGFnZSAtIFB1cHBldGVlciBwYWdlIG9iamVjdC5cbiAqIEBwYXJhbSB7YW55fSBjaGFydCAtIFRoZSBjaGFydCBvYmplY3QgdG8gYmUgY29uZmlndXJlZC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gQ29uZmlndXJhdGlvbiBvcHRpb25zIGZvciB0aGUgY2hhcnQuXG4gKlxuICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IFByb21pc2UgcmVzb2x2aW5nIGFmdGVyIHRoZSBjb25maWd1cmF0aW9uIGlzIHNldC5cbiAqL1xuY29uc3Qgc2V0QXNDb25maWcgPSBhc3luYyAocGFnZSwgY2hhcnQsIG9wdGlvbnMsIGRpc3BsYXlFcnJvcnMpID0+IHtcbiAgLy8gR2V0IHJpZCBvZiB0aGUgcmVkdW5hbnQgc3RyaW5nIGRhdGFcbiAgb3B0aW9ucy5leHBvcnQuaW5zdHIgPSBudWxsO1xuICBvcHRpb25zLmV4cG9ydC5pbmZpbGUgPSBudWxsO1xuXG4gIC8vIEdldCB0aGUgc2l6ZSBvZiB0aGUgZXhwb3J0IGlucHV0XG4gIGNvbnN0IHRvdGFsU2l6ZSA9IEJ1ZmZlci5ieXRlTGVuZ3RoKFxuICAgIG9wdGlvbnMuZXhwb3J0Py5zdHJJbmogPyBvcHRpb25zLmV4cG9ydD8uc3RySW5qIDogSlNPTi5zdHJpbmdpZnkoY2hhcnQpLFxuICAgICd1dGYtOCdcbiAgKTtcblxuICAvLyBMb2cgdGhlIHNpemUgaW4gTUJcbiAgbG9nKFxuICAgIDQsXG4gICAgYFtleHBvcnRdIFRoZSBjdXJyZW50IHRvdGFsIHNpemUgb2YgZGF0YSBwYXNzZWQgdG8gYSBwYWdlIGlzIGFyb3VuZCAkeyhcbiAgICAgIHRvdGFsU2l6ZSAvXG4gICAgICAoMTAyNCAqIDEwMjQpXG4gICAgKS50b0ZpeGVkKDIpfSBNQmBcbiAgKTtcblxuICAvLyBDaGVjayB0aGUgc2l6ZSBvZiBkYXRhIHBhc3NlZCB0byB0aGUgcGFnZVxuICBpZiAodG90YWxTaXplID49IDEwMCAqIDEwMjQgKiAxMDI0KSB7XG4gICAgdGhyb3cgbmV3IEV4cG9ydEVycm9yKGBbZXhwb3J0XSBUaGUgZGF0YSBwYXNzZWQgdG8gYSBwYWdlIGV4Y2VlZGVkIDEwME1CLmApO1xuICB9XG5cbiAgLy8gVHJpZ2dlciB0aGUgSGlnaGNoYXJ0cyBjaGFydCBjcmVhdGlvblxuICByZXR1cm4gcGFnZS5ldmFsdWF0ZSh0cmlnZ2VyRXhwb3J0LCBjaGFydCwgb3B0aW9ucywgZGlzcGxheUVycm9ycyk7XG59O1xuXG4vKipcbiAqIEV4cG9ydHMgdG8gYSBjaGFydCBmcm9tIGEgcGFnZSB1c2luZyBQdXBwZXRlZXIuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHBhZ2UgLSBQdXBwZXRlZXIgcGFnZSBvYmplY3QuXG4gKiBAcGFyYW0ge2FueX0gY2hhcnQgLSBUaGUgY2hhcnQgb2JqZWN0IG9yIFNWRyBjb25maWd1cmF0aW9uIHRvIGJlIGV4cG9ydGVkLlxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgLSBFeHBvcnQgb3B0aW9ucyBhbmQgY29uZmlndXJhdGlvbi5cbiAqXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxzdHJpbmcgfCBCdWZmZXIgfCBFeHBvcnRFcnJvcj59IFByb21pc2UgcmVzb2x2aW5nIHRvXG4gKiB0aGUgZXhwb3J0ZWQgZGF0YSBvciByZWplY3Rpbmcgd2l0aCBhbiBFeHBvcnRFcnJvci5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgYXN5bmMgKHBhZ2UsIGNoYXJ0LCBvcHRpb25zKSA9PiB7XG4gIC8vIEluamVjdGVkIHJlc291cmNlcyBhcnJheSAoYWRkaXRpb25hbCBKUyBhbmQgQ1NTKVxuICBsZXQgaW5qZWN0ZWRSZXNvdXJjZXMgPSBbXTtcblxuICB0cnkge1xuICAgIGxvZyg0LCAnW2V4cG9ydF0gRGV0ZXJtaW5pbmcgZXhwb3J0IHBhdGguJyk7XG5cbiAgICBjb25zdCBleHBvcnRPcHRpb25zID0gb3B0aW9ucy5leHBvcnQ7XG5cbiAgICAvLyBEZWNpZGUgd2hldGhlciBkaXNwbGF5IGVycm9yIG9yIGRlYmJ1Z2VyIHdyYXBwZXIgYXJvdW5kIGl0XG4gICAgY29uc3QgZGlzcGxheUVycm9ycyA9XG4gICAgICBleHBvcnRPcHRpb25zPy5vcHRpb25zPy5jaGFydD8uZGlzcGxheUVycm9ycyAmJlxuICAgICAgZ2V0Q2FjaGUoKS5hY3RpdmVNYW5pZmVzdC5tb2R1bGVzLmRlYnVnZ2VyO1xuXG4gICAgbGV0IGlzU1ZHO1xuICAgIGlmIChcbiAgICAgIGNoYXJ0LmluZGV4T2YgJiZcbiAgICAgIChjaGFydC5pbmRleE9mKCc8c3ZnJykgPj0gMCB8fCBjaGFydC5pbmRleE9mKCc8P3htbCcpID49IDApXG4gICAgKSB7XG4gICAgICAvLyBTVkcgaW5wdXQgaGFuZGxpbmdcbiAgICAgIGxvZyg0LCAnW2V4cG9ydF0gVHJlYXRpbmcgYXMgU1ZHLicpO1xuXG4gICAgICAvLyBJZiBpbnB1dCBpcyBhbHNvIFNWRywganVzdCByZXR1cm4gaXRcbiAgICAgIGlmIChleHBvcnRPcHRpb25zLnR5cGUgPT09ICdzdmcnKSB7XG4gICAgICAgIHJldHVybiBjaGFydDtcbiAgICAgIH1cblxuICAgICAgaXNTVkcgPSB0cnVlO1xuICAgICAgYXdhaXQgcGFnZS5zZXRDb250ZW50KHN2Z1RlbXBsYXRlKGNoYXJ0KSwge1xuICAgICAgICB3YWl0VW50aWw6ICdkb21jb250ZW50bG9hZGVkJ1xuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEpTT04gY29uZmlnIGhhbmRsaW5nXG4gICAgICBsb2coNCwgJ1tleHBvcnRdIFRyZWF0aW5nIGFzIGNvbmZpZy4nKTtcblxuICAgICAgLy8gTmVlZCB0byBwZXJmb3JtIHN0cmFpZ2h0IGluamVjdFxuICAgICAgaWYgKGV4cG9ydE9wdGlvbnMuc3RySW5qKSB7XG4gICAgICAgIC8vIEluamVjdGlvbiBiYXNlZCBjb25maWd1cmF0aW9uIGV4cG9ydFxuICAgICAgICBhd2FpdCBzZXRBc0NvbmZpZyhcbiAgICAgICAgICBwYWdlLFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGNoYXJ0OiB7XG4gICAgICAgICAgICAgIGhlaWdodDogZXhwb3J0T3B0aW9ucy5oZWlnaHQsXG4gICAgICAgICAgICAgIHdpZHRoOiBleHBvcnRPcHRpb25zLndpZHRoXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgICBvcHRpb25zLFxuICAgICAgICAgIGRpc3BsYXlFcnJvcnNcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIEJhc2ljIGNvbmZpZ3VyYXRpb24gZXhwb3J0XG4gICAgICAgIGNoYXJ0LmNoYXJ0LmhlaWdodCA9IGV4cG9ydE9wdGlvbnMuaGVpZ2h0O1xuICAgICAgICBjaGFydC5jaGFydC53aWR0aCA9IGV4cG9ydE9wdGlvbnMud2lkdGg7XG5cbiAgICAgICAgYXdhaXQgc2V0QXNDb25maWcocGFnZSwgY2hhcnQsIG9wdGlvbnMsIGRpc3BsYXlFcnJvcnMpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEtlZXBzIHRyYWNrIG9mIGFsbCByZXNvdXJjZXMgYWRkZWQgb24gdGhlIHBhZ2Ugd2l0aCBhZGRYWFhUYWcuIGV0Y1xuICAgIC8vIEl0J3MgVklUQUwgdGhhdCBhbGwgYWRkZWQgcmVzb3VyY2VzIGVuZHMgdXAgaGVyZSBzbyB3ZSBjYW4gY2xlYXIgdGhpbmdzXG4gICAgLy8gb3V0IHdoZW4gZG9pbmcgYSBuZXcgZXhwb3J0IGluIHRoZSBzYW1lIHBhZ2UhXG4gICAgaW5qZWN0ZWRSZXNvdXJjZXMgPSBhd2FpdCBhZGRQYWdlUmVzb3VyY2VzKHBhZ2UsIG9wdGlvbnMpO1xuXG4gICAgLy8gR2V0IHRoZSByZWFsIGNoYXJ0IHNpemUgYW5kIHNldCB0aGUgem9vbSBhY2NvcmRpbmdseVxuICAgIGNvbnN0IHNpemUgPSBpc1NWR1xuICAgICAgPyBhd2FpdCBwYWdlLmV2YWx1YXRlKChzY2FsZSkgPT4ge1xuICAgICAgICAgIGNvbnN0IHN2Z0VsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFxuICAgICAgICAgICAgJyNjaGFydC1jb250YWluZXIgc3ZnOmZpcnN0LW9mLXR5cGUnXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIC8vIEdldCB0aGUgdmFsdWVzIGNvcnJlY3RseSBzY2FsZWRcbiAgICAgICAgICBjb25zdCBjaGFydEhlaWdodCA9IHN2Z0VsZW1lbnQuaGVpZ2h0LmJhc2VWYWwudmFsdWUgKiBzY2FsZTtcbiAgICAgICAgICBjb25zdCBjaGFydFdpZHRoID0gc3ZnRWxlbWVudC53aWR0aC5iYXNlVmFsLnZhbHVlICogc2NhbGU7XG5cbiAgICAgICAgICAvLyBJbiBjYXNlIG9mIFNWRyB0aGUgem9vbSBtdXN0IGJlIHNldCBkaXJlY3RseSBmb3IgYm9keVxuICAgICAgICAgIC8vIFNldCB0aGUgem9vbSBhcyBzY2FsZVxuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bmRlZlxuICAgICAgICAgIGRvY3VtZW50LmJvZHkuc3R5bGUuem9vbSA9IHNjYWxlO1xuXG4gICAgICAgICAgLy8gU2V0IHRoZSBtYXJnaW4gdG8gMHB4XG4gICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVuZGVmXG4gICAgICAgICAgZG9jdW1lbnQuYm9keS5zdHlsZS5tYXJnaW4gPSAnMHB4JztcblxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjaGFydEhlaWdodCxcbiAgICAgICAgICAgIGNoYXJ0V2lkdGhcbiAgICAgICAgICB9O1xuICAgICAgICB9LCBwYXJzZUZsb2F0KGV4cG9ydE9wdGlvbnMuc2NhbGUpKVxuICAgICAgOiBhd2FpdCBwYWdlLmV2YWx1YXRlKCgpID0+IHtcbiAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW5kZWZcbiAgICAgICAgICBjb25zdCB7IGNoYXJ0SGVpZ2h0LCBjaGFydFdpZHRoIH0gPSB3aW5kb3cuSGlnaGNoYXJ0cy5jaGFydHNbMF07XG5cbiAgICAgICAgICAvLyBObyBuZWVkIGZvciBzdWNoIHNjYWxlIG1hbmlwdWxhdGlvbiBpbiBjYXNlIG9mIG90aGVyIHR5cGVzIG9mIGV4cG9ydHNcbiAgICAgICAgICAvLyBSZXNldCB0aGUgem9vbSBmb3Igb3RoZXIgZXhwb3J0cyB0aGFuIHRvIFNWR3NcbiAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW5kZWZcbiAgICAgICAgICBkb2N1bWVudC5ib2R5LnN0eWxlLnpvb20gPSAxO1xuXG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNoYXJ0SGVpZ2h0LFxuICAgICAgICAgICAgY2hhcnRXaWR0aFxuICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuXG4gICAgLy8gU2V0IGZpbmFsIGhlaWdodCBhbmQgd2lkdGggZm9yIHZpZXdwb3J0XG4gICAgY29uc3Qgdmlld3BvcnRIZWlnaHQgPSBNYXRoLmFicyhcbiAgICAgIE1hdGguY2VpbChzaXplLmNoYXJ0SGVpZ2h0IHx8IGV4cG9ydE9wdGlvbnMuaGVpZ2h0KVxuICAgICk7XG4gICAgY29uc3Qgdmlld3BvcnRXaWR0aCA9IE1hdGguYWJzKFxuICAgICAgTWF0aC5jZWlsKHNpemUuY2hhcnRXaWR0aCB8fCBleHBvcnRPcHRpb25zLndpZHRoKVxuICAgICk7XG5cbiAgICAvLyBHZXQgdGhlIGNsaXAgcmVnaW9uIGZvciB0aGUgcGFnZVxuICAgIGNvbnN0IHsgeCwgeSB9ID0gYXdhaXQgZ2V0Q2xpcFJlZ2lvbihwYWdlKTtcblxuICAgIC8vIFNldCB0aGUgZmluYWwgdmlld3BvcnQgbm93IHRoYXQgd2UgaGF2ZSB0aGUgcmVhbCBoZWlnaHRcbiAgICBhd2FpdCBwYWdlLnNldFZpZXdwb3J0KHtcbiAgICAgIGhlaWdodDogdmlld3BvcnRIZWlnaHQsXG4gICAgICB3aWR0aDogdmlld3BvcnRXaWR0aCxcbiAgICAgIGRldmljZVNjYWxlRmFjdG9yOiBpc1NWRyA/IDEgOiBwYXJzZUZsb2F0KGV4cG9ydE9wdGlvbnMuc2NhbGUpXG4gICAgfSk7XG5cbiAgICBsZXQgZGF0YTtcbiAgICAvLyBSYXN0ZXJpemF0aW9uIHByb2Nlc3NcbiAgICBpZiAoZXhwb3J0T3B0aW9ucy50eXBlID09PSAnc3ZnJykge1xuICAgICAgLy8gU1ZHXG4gICAgICBkYXRhID0gYXdhaXQgY3JlYXRlU1ZHKHBhZ2UpO1xuICAgIH0gZWxzZSBpZiAoWydwbmcnLCAnanBlZyddLmluY2x1ZGVzKGV4cG9ydE9wdGlvbnMudHlwZSkpIHtcbiAgICAgIC8vIFBORyBvciBKUEVHXG4gICAgICBkYXRhID0gYXdhaXQgY3JlYXRlSW1hZ2UoXG4gICAgICAgIHBhZ2UsXG4gICAgICAgIGV4cG9ydE9wdGlvbnMudHlwZSxcbiAgICAgICAgJ2Jhc2U2NCcsXG4gICAgICAgIHtcbiAgICAgICAgICB3aWR0aDogdmlld3BvcnRXaWR0aCxcbiAgICAgICAgICBoZWlnaHQ6IHZpZXdwb3J0SGVpZ2h0LFxuICAgICAgICAgIHgsXG4gICAgICAgICAgeVxuICAgICAgICB9LFxuICAgICAgICBleHBvcnRPcHRpb25zLnJhc3Rlcml6YXRpb25UaW1lb3V0XG4gICAgICApO1xuICAgIH0gZWxzZSBpZiAoZXhwb3J0T3B0aW9ucy50eXBlID09PSAncGRmJykge1xuICAgICAgLy8gUERGXG4gICAgICBkYXRhID0gYXdhaXQgY3JlYXRlUERGKFxuICAgICAgICBwYWdlLFxuICAgICAgICB2aWV3cG9ydEhlaWdodCxcbiAgICAgICAgdmlld3BvcnRXaWR0aCxcbiAgICAgICAgJ2Jhc2U2NCcsXG4gICAgICAgIGV4cG9ydE9wdGlvbnMucmFzdGVyaXphdGlvblRpbWVvdXRcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFeHBvcnRFcnJvcihcbiAgICAgICAgYFtleHBvcnRdIFVuc3VwcG9ydGVkIG91dHB1dCBmb3JtYXQgJHtleHBvcnRPcHRpb25zLnR5cGV9LmBcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gQ2xlYXIgcHJldmlvdXNseSBpbmplY3RlZCBKUyBhbmQgQ1NTIHJlc291cmNlc1xuICAgIGF3YWl0IGNsZWFyUGFnZVJlc291cmNlcyhwYWdlLCBpbmplY3RlZFJlc291cmNlcyk7XG4gICAgcmV0dXJuIGRhdGE7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgYXdhaXQgY2xlYXJQYWdlUmVzb3VyY2VzKHBhZ2UsIGluamVjdGVkUmVzb3VyY2VzKTtcbiAgICByZXR1cm4gZXJyb3I7XG4gIH1cbn07XG4iLCIvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuXG5IaWdoY2hhcnRzIEV4cG9ydCBTZXJ2ZXJcblxuQ29weXJpZ2h0IChjKSAyMDE2LTIwMjQsIEhpZ2hzb2Z0XG5cbkxpY2VuY2VkIHVuZGVyIHRoZSBNSVQgbGljZW5jZS5cblxuQWRkaXRpb25hbGx5IGEgdmFsaWQgSGlnaGNoYXJ0cyBsaWNlbnNlIGlzIHJlcXVpcmVkIGZvciB1c2UuXG5cblNlZSBMSUNFTlNFIGZpbGUgaW4gcm9vdCBmb3IgZGV0YWlscy5cblxuKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuaW1wb3J0IGNzc1RlbXBsYXRlIGZyb20gJy4vY3NzLmpzJztcblxuZXhwb3J0IGRlZmF1bHQgKGNoYXJ0KSA9PiBgXG48IURPQ1RZUEUgaHRtbD5cbjxodG1sIGxhbmc9J2VuLVVTJz5cbiAgPGhlYWQ+XG4gICAgPG1ldGEgaHR0cC1lcXVpdj1cIkNvbnRlbnQtVHlwZVwiIGNvbnRlbnQ9XCJ0ZXh0L2h0bWw7IGNoYXJzZXQ9dXRmLThcIj5cbiAgICA8dGl0bGU+SGlnaGNoYXJ0cyBFeHBvcnQ8L3RpdGxlPlxuICA8L2hlYWQ+XG4gIDxzdHlsZT5cbiAgICAke2Nzc1RlbXBsYXRlKCl9XG4gIDwvc3R5bGU+XG4gIDxib2R5PlxuICAgIDxkaXYgaWQ9XCJjaGFydC1jb250YWluZXJcIj5cbiAgICAgICR7Y2hhcnR9XG4gICAgPC9kaXY+XG4gIDwvYm9keT5cbjwvaHRtbD5cblxuYDtcbiIsIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG5cbkhpZ2hjaGFydHMgRXhwb3J0IFNlcnZlclxuXG5Db3B5cmlnaHQgKGMpIDIwMTYtMjAyNCwgSGlnaHNvZnRcblxuTGljZW5jZWQgdW5kZXIgdGhlIE1JVCBsaWNlbmNlLlxuXG5BZGRpdGlvbmFsbHkgYSB2YWxpZCBIaWdoY2hhcnRzIGxpY2Vuc2UgaXMgcmVxdWlyZWQgZm9yIHVzZS5cblxuU2VlIExJQ0VOU0UgZmlsZSBpbiByb290IGZvciBkZXRhaWxzLlxuXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG5pbXBvcnQgeyBQb29sIH0gZnJvbSAndGFybic7XG5pbXBvcnQgeyB2NCBhcyB1dWlkIH0gZnJvbSAndXVpZCc7XG5cbmltcG9ydCB7XG4gIGNyZWF0ZSBhcyBjcmVhdGVCcm93c2VyLFxuICBjbG9zZSBhcyBjbG9zZUJyb3dzZXIsXG4gIG5ld1BhZ2UsXG4gIGNsZWFyUGFnZVxufSBmcm9tICcuL2Jyb3dzZXIuanMnO1xuaW1wb3J0IHB1cHBldGVlckV4cG9ydCBmcm9tICcuL2V4cG9ydC5qcyc7XG5pbXBvcnQgeyBsb2csIGxvZ1dpdGhTdGFjayB9IGZyb20gJy4vbG9nZ2VyLmpzJztcbmltcG9ydCB7IG1lYXN1cmVUaW1lIH0gZnJvbSAnLi91dGlscy5qcyc7XG5cbmltcG9ydCBFeHBvcnRFcnJvciBmcm9tICcuL2Vycm9ycy9FeHBvcnRFcnJvci5qcyc7XG5cbi8vIFRoZSBwb29sIGluc3RhbmNlXG5sZXQgcG9vbCA9IGZhbHNlO1xuXG4vLyBQb29sIHN0YXRpc3RpY3NcbmV4cG9ydCBjb25zdCBzdGF0cyA9IHtcbiAgcGVyZm9ybWVkRXhwb3J0czogMCxcbiAgZXhwb3J0QXR0ZW1wdHM6IDAsXG4gIGV4cG9ydEZyb21TdmdBdHRlbXB0czogMCxcbiAgdGltZVNwZW50OiAwLFxuICBkcm9wcGVkRXhwb3J0czogMCxcbiAgc3BlbnRBdmVyYWdlOiAwXG59O1xuXG5sZXQgcG9vbENvbmZpZyA9IHt9O1xuXG5jb25zdCBmYWN0b3J5ID0ge1xuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyB3b3JrZXIgcGFnZSBmb3IgdGhlIGV4cG9ydCBwb29sLlxuICAgKlxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSAtIEFuIG9iamVjdCBjb250YWluaW5nIHRoZSB3b3JrZXIgSUQsIGEgcmVmZXJlbmNlIHRvIHRoZVxuICAgKiBicm93c2VyIHBhZ2UsIGFuZCBpbml0aWFsIHdvcmsgY291bnQuXG4gICAqXG4gICAqIEB0aHJvd3Mge0V4cG9ydEVycm9yfSAtIElmIHRoZXJlJ3MgYW4gZXJyb3IgZHVyaW5nIHRoZSBjcmVhdGlvbiBvZiB0aGUgbmV3XG4gICAqIHBhZ2UuXG4gICAqL1xuICBjcmVhdGU6IGFzeW5jICgpID0+IHtcbiAgICBsZXQgcGFnZSA9IGZhbHNlO1xuXG4gICAgY29uc3QgaWQgPSB1dWlkKCk7XG4gICAgY29uc3Qgc3RhcnREYXRlID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG5cbiAgICB0cnkge1xuICAgICAgcGFnZSA9IGF3YWl0IG5ld1BhZ2UoKTtcblxuICAgICAgaWYgKCFwYWdlIHx8IHBhZ2UuaXNDbG9zZWQoKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXhwb3J0RXJyb3IoJ1RoZSBwYWdlIGlzIGludmFsaWQgb3IgY2xvc2VkLicpO1xuICAgICAgfVxuXG4gICAgICBsb2coXG4gICAgICAgIDMsXG4gICAgICAgIGBbcG9vbF0gU3VjY2Vzc2Z1bGx5IGNyZWF0ZWQgYSB3b3JrZXIgJHtpZH0gLSB0b29rICR7XG4gICAgICAgICAgbmV3IERhdGUoKS5nZXRUaW1lKCkgLSBzdGFydERhdGVcbiAgICAgICAgfSBtcy5gXG4gICAgICApO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aHJvdyBuZXcgRXhwb3J0RXJyb3IoXG4gICAgICAgICdFcnJvciBlbmNvdW50ZXJlZCB3aGVuIGNyZWF0aW5nIGEgbmV3IHBhZ2UuJ1xuICAgICAgKS5zZXRFcnJvcihlcnJvcik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGlkLFxuICAgICAgcGFnZSxcbiAgICAgIC8vIFRyeSB0byBkaXN0cmlidXRlIHRoZSBpbml0aWFsIHdvcmsgY291bnRcbiAgICAgIHdvcmtDb3VudDogTWF0aC5yb3VuZChNYXRoLnJhbmRvbSgpICogKHBvb2xDb25maWcud29ya0xpbWl0IC8gMikpXG4gICAgfTtcbiAgfSxcblxuICAvKipcbiAgICogVmFsaWRhdGVzIGEgd29ya2VyIHBhZ2UgaW4gdGhlIGV4cG9ydCBwb29sLCBjaGVja2luZyBpZiBpdCBoYXMgZXhjZWVkZWRcbiAgICogdGhlIHdvcmsgbGltaXQuXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSB3b3JrZXJIYW5kbGUgLSBUaGUgaGFuZGxlIHRvIHRoZSB3b3JrZXIsIGNvbnRhaW5pbmcgdGhlXG4gICAqIHdvcmtlcidzIElELCBhIHJlZmVyZW5jZSB0byB0aGUgYnJvd3NlciBwYWdlLCBhbmQgd29yayBjb3VudC5cbiAgICpcbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gUmV0dXJucyB0cnVlIGlmIHRoZSB3b3JrZXIgaXMgdmFsaWQgYW5kIHdpdGhpblxuICAgKiB0aGUgd29yayBsaW1pdDsgb3RoZXJ3aXNlLCByZXR1cm5zIGZhbHNlLlxuICAgKi9cbiAgdmFsaWRhdGU6IGFzeW5jICh3b3JrZXJIYW5kbGUpID0+IHtcbiAgICAvLyBOT1RFOiBJbiBjZXJ0YWluIGNhc2VzIGFjcXVpcmluZyB0aHJvd3MgYSBUYXJnZXRDbG9zZUVycm9yLCB3aGljaCBtYXlcbiAgICAvLyAgICAgICBiZSBjYXVzZWQgYnkgdHdvIHRoaW5nczpcbiAgICAvLyAgICAgICAgIC0gVGhlIHBhZ2UgaXMgY2xvc2VkIGFuZCBhdHRlbXB0ZWQgdG8gYmUgcmV1c2VkLlxuICAgIC8vICAgICAgICAgLSBMb3N0IGNvbnRhY3Qgd2l0aCB0aGUgYnJvd3NlclxuICAgIC8vICAgICAgIFdoYXQgd2UncmUgc2VlaW5nIGluIGxvZ3MgaXMgdGhhdCBzdWNjZXNzaXZlIGV4cG9ydHMgdHlwaWNhbGx5XG4gICAgLy8gICAgICAgc3VjY2VlZHMsIGFuZCB0aGUgc2VydmVyIHJlY292ZXJzLCBpbmRpY2F0aW5nIHRoYXQgaXQncyBsaWtlbHlcbiAgICAvLyAgICAgICB0aGUgZmlyc3QgY2FzZS4gVGhpcyBpcyBhbiBhdHRlbXB0IGF0IGFsbGlldmF0aW5nIHRoZSBpc3N1ZSBieVxuICAgIC8vICAgICAgIHNpbXBseSBub3QgdmFsaWRhdGluZyB0aGUgd29ya2VyIGlmIHRoZSBwYWdlIGlzIG51bGwgb3IgY2xvc2VkLlxuICAgIC8vXG4gICAgLy8gICAgICAgVGhlIGFjdHVhbCByZXN1bHQgZnJvbSB3aGVuIHRoaXMgaGFwcGVuZWQsIHdhcyB0aGF0IGEgd29ya2VyIHdvdWxkXG4gICAgLy8gICAgICAgYmUgY29tcGxldGVseSBsb2NrZWQsIHN0b3BwaW5nIGl0IGZyb20gYmVpbmcgYWNxdWlyZWQgdW50aWxcbiAgICAvLyAgICAgICBpdHMgd29yayBjb3VudCByZWFjaGVkIHRoZSBsaW1pdC5cbiAgICBpZiAoIXdvcmtlckhhbmRsZS5wYWdlIHx8IHdvcmtlckhhbmRsZS5wYWdlPy5pc0Nsb3NlZCgpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgcG9vbENvbmZpZy53b3JrTGltaXQgJiZcbiAgICAgICsrd29ya2VySGFuZGxlLndvcmtDb3VudCA+IHBvb2xDb25maWcud29ya0xpbWl0XG4gICAgKSB7XG4gICAgICBsb2coXG4gICAgICAgIDMsXG4gICAgICAgIGBbcG9vbF0gV29ya2VyIGZhaWxlZCB2YWxpZGF0aW9uOiBleGNlZWRlZCB3b3JrIGxpbWl0IChsaW1pdCBpcyAke3Bvb2xDb25maWcud29ya0xpbWl0fSkuYFxuICAgICAgKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH0sXG5cbiAgLyoqXG4gICAqIERlc3Ryb3lzIGEgd29ya2VyIGVudHJ5IGluIHRoZSBleHBvcnQgcG9vbCwgY2xvc2luZyBpdHMgYXNzb2NpYXRlZCBwYWdlLlxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gd29ya2VySGFuZGxlIC0gVGhlIGhhbmRsZSB0byB0aGUgd29ya2VyLCBjb250YWluaW5nXG4gICAqIHRoZSB3b3JrZXIncyBJRCBhbmQgYSByZWZlcmVuY2UgdG8gdGhlIGJyb3dzZXIgcGFnZS5cbiAgICovXG4gIGRlc3Ryb3k6IGFzeW5jICh3b3JrZXJIYW5kbGUpID0+IHtcbiAgICBsb2coMywgYFtwb29sXSBEZXN0cm95aW5nIHBvb2wgZW50cnkgJHt3b3JrZXJIYW5kbGUuaWR9LmApO1xuXG4gICAgaWYgKHdvcmtlckhhbmRsZS5wYWdlICYmICF3b3JrZXJIYW5kbGUucGFnZS5pc0Nsb3NlZCgpKSB7XG4gICAgICBhd2FpdCB3b3JrZXJIYW5kbGUucGFnZS5jbG9zZSgpO1xuICAgIH1cbiAgfVxuXG4gIC8vIGxvZzogKG1lc3NhZ2UsIGxldmVsKSA9PiBsb2coMSwgJ1t0YXJuXSAnICsgIG1lc3NhZ2UpXG59O1xuXG4vKipcbiAqIEluaXRpYWxpemVzIHRoZSBleHBvcnQgcG9vbCB3aXRoIHRoZSBwcm92aWRlZCBjb25maWd1cmF0aW9uLCBjcmVhdGluZ1xuICogYSBicm93c2VyIGluc3RhbmNlIGFuZCBzZXR0aW5nIHVwIHdvcmtlciByZXNvdXJjZXMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZyAtIENvbmZpZ3VyYXRpb24gb3B0aW9ucyBmb3IgdGhlIGV4cG9ydCBwb29sIGFsb25nXG4gKiB3aXRoIGN1c3RvbSBwdXBwZXRlZXIgYXJndW1lbnRzIGZvciB0aGUgcHVwcGV0ZWVyLmxhdW5jaCBmdW5jdGlvbi5cbiAqL1xuZXhwb3J0IGNvbnN0IGluaXRQb29sID0gYXN5bmMgKGNvbmZpZykgPT4ge1xuICAvLyBGb3IgdGhlIG1vZHVsZSBzY29wZSB1c2FnZVxuICBwb29sQ29uZmlnID0gY29uZmlnICYmIGNvbmZpZy5wb29sID8geyAuLi5jb25maWcucG9vbCB9IDoge307XG5cbiAgLy8gQ3JlYXRlIGEgYnJvd3NlciBpbnN0YW5jZSB3aXRoIHRoZSBwdXBwZXRlZXIgYXJndW1lbnRzXG4gIGF3YWl0IGNyZWF0ZUJyb3dzZXIoY29uZmlnLnB1cHBldGVlckFyZ3MpO1xuXG4gIGxvZyhcbiAgICAzLFxuICAgIGBbcG9vbF0gSW5pdGlhbGl6aW5nIHBvb2wgd2l0aCB3b3JrZXJzOiBtaW4gJHtwb29sQ29uZmlnLm1pbldvcmtlcnN9LCBtYXggJHtwb29sQ29uZmlnLm1heFdvcmtlcnN9LmBcbiAgKTtcblxuICBpZiAocG9vbCkge1xuICAgIHJldHVybiBsb2coXG4gICAgICA0LFxuICAgICAgJ1twb29sXSBBbHJlYWR5IGluaXRpYWxpemVkLCBwbGVhc2Uga2lsbCBpdCBiZWZvcmUgY3JlYXRpbmcgYSBuZXcgb25lLidcbiAgICApO1xuICB9XG5cbiAgaWYgKHBhcnNlSW50KHBvb2xDb25maWcubWluV29ya2VycykgPiBwYXJzZUludChwb29sQ29uZmlnLm1heFdvcmtlcnMpKSB7XG4gICAgcG9vbENvbmZpZy5taW5Xb3JrZXJzID0gcG9vbENvbmZpZy5tYXhXb3JrZXJzO1xuICB9XG5cbiAgdHJ5IHtcbiAgICAvLyBDcmVhdGUgYSBwb29sIGFsb25nIHdpdGggYSBtaW5pbWFsIG51bWJlciBvZiByZXNvdXJjZXNcbiAgICBwb29sID0gbmV3IFBvb2woe1xuICAgICAgLy8gR2V0IHRoZSBjcmVhdGUvdmFsaWRhdGUvZGVzdHJveS9sb2cgZnVuY3Rpb25zXG4gICAgICAuLi5mYWN0b3J5LFxuICAgICAgbWluOiBwYXJzZUludChwb29sQ29uZmlnLm1pbldvcmtlcnMpLFxuICAgICAgbWF4OiBwYXJzZUludChwb29sQ29uZmlnLm1heFdvcmtlcnMpLFxuICAgICAgYWNxdWlyZVRpbWVvdXRNaWxsaXM6IHBvb2xDb25maWcuYWNxdWlyZVRpbWVvdXQsXG4gICAgICBjcmVhdGVUaW1lb3V0TWlsbGlzOiBwb29sQ29uZmlnLmNyZWF0ZVRpbWVvdXQsXG4gICAgICBkZXN0cm95VGltZW91dE1pbGxpczogcG9vbENvbmZpZy5kZXN0cm95VGltZW91dCxcbiAgICAgIGlkbGVUaW1lb3V0TWlsbGlzOiBwb29sQ29uZmlnLmlkbGVUaW1lb3V0LFxuICAgICAgY3JlYXRlUmV0cnlJbnRlcnZhbE1pbGxpczogcG9vbENvbmZpZy5jcmVhdGVSZXRyeUludGVydmFsLFxuICAgICAgcmVhcEludGVydmFsTWlsbGlzOiBwb29sQ29uZmlnLnJlYXBlckludGVydmFsLFxuICAgICAgcHJvcGFnYXRlQ3JlYXRlRXJyb3I6IGZhbHNlXG4gICAgfSk7XG5cbiAgICAvLyBTZXQgZXZlbnRzXG4gICAgcG9vbC5vbigncmVsZWFzZScsIGFzeW5jIChyZXNvdXJjZSkgPT4ge1xuICAgICAgLy8gQ2xlYXIgcGFnZVxuICAgICAgY29uc3QgciA9IGF3YWl0IGNsZWFyUGFnZShyZXNvdXJjZS5wYWdlLCBmYWxzZSk7XG4gICAgICBsb2coXG4gICAgICAgIDQsXG4gICAgICAgIGBbcG9vbF0gUmVsZWFzaW5nIGEgd29ya2VyIHdpdGggSUQgJHtyZXNvdXJjZS5pZH0uIENsZWFyIHBhZ2Ugc3RhdHVzOiAke3J9LmBcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBwb29sLm9uKCdkZXN0cm95U3VjY2VzcycsIChldmVudElkLCByZXNvdXJjZSkgPT4ge1xuICAgICAgbG9nKDQsIGBbcG9vbF0gRGVzdHJveWVkIGEgd29ya2VyIHdpdGggSUQgJHtyZXNvdXJjZS5pZH0uYCk7XG4gICAgICByZXNvdXJjZS5wYWdlID0gbnVsbDtcbiAgICB9KTtcblxuICAgIGNvbnN0IGluaXRpYWxSZXNvdXJjZXMgPSBbXTtcbiAgICAvLyBDcmVhdGUgYW4gaW5pdGlhbCBudW1iZXIgb2YgcmVzb3VyY2VzXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwb29sQ29uZmlnLm1pbldvcmtlcnM7IGkrKykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVzb3VyY2UgPSBhd2FpdCBwb29sLmFjcXVpcmUoKS5wcm9taXNlO1xuICAgICAgICBpbml0aWFsUmVzb3VyY2VzLnB1c2gocmVzb3VyY2UpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgbG9nV2l0aFN0YWNrKDIsIGVycm9yLCAnW3Bvb2xdIENvdWxkIG5vdCBjcmVhdGUgYW4gaW5pdGlhbCByZXNvdXJjZS4nKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBSZWxlYXNlIHRoZSBpbml0aWFsIG51bWJlciBvZiByZXNvdXJjZXMgYmFjayB0byB0aGUgcG9vbFxuICAgIGluaXRpYWxSZXNvdXJjZXMuZm9yRWFjaCgocmVzb3VyY2UpID0+IHtcbiAgICAgIHBvb2wucmVsZWFzZShyZXNvdXJjZSk7XG4gICAgfSk7XG5cbiAgICBsb2coXG4gICAgICAzLFxuICAgICAgYFtwb29sXSBUaGUgcG9vbCBpcyByZWFkeSR7aW5pdGlhbFJlc291cmNlcy5sZW5ndGggPyBgIHdpdGggJHtpbml0aWFsUmVzb3VyY2VzLmxlbmd0aH0gaW5pdGlhbCByZXNvdXJjZXMgd2FpdGluZy5gIDogJy4nfWBcbiAgICApO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHRocm93IG5ldyBFeHBvcnRFcnJvcihcbiAgICAgICdbcG9vbF0gQ291bGQgbm90IGNyZWF0ZSB0aGUgcG9vbCBvZiB3b3JrZXJzLidcbiAgICApLnNldEVycm9yKGVycm9yKTtcbiAgfVxufTtcblxuLyoqXG4gKiBLaWxscyBhbGwgd29ya2VycyBpbiB0aGUgcG9vbCwgZGVzdHJveXMgdGhlIHBvb2wsIGFuZCBjbG9zZXMgdGhlIGJyb3dzZXJcbiAqIGluc3RhbmNlLlxuICpcbiAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyBhZnRlciB0aGUgd29ya2VycyBhcmVcbiAqIGtpbGxlZCwgdGhlIHBvb2wgaXMgZGVzdHJveWVkLCBhbmQgdGhlIGJyb3dzZXIgaXMgY2xvc2VkLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24ga2lsbFBvb2woKSB7XG4gIGxvZygzLCAnW3Bvb2xdIEtpbGxpbmcgcG9vbCB3aXRoIGFsbCB3b3JrZXJzIGFuZCBjbG9zaW5nIGJyb3dzZXIuJyk7XG5cbiAgLy8gSWYgc3RpbGwgYWxpdmUsIGRlc3Ryb3kgdGhlIHBvb2wgb2YgcGFnZXMgYmVmb3JlIGNsb3NpbmcgYSBicm93c2VyXG4gIGlmIChwb29sKSB7XG4gICAgLy8gRnJlZSB1cCBub3QgcmVsZWFzZWQgd29ya2Vyc1xuICAgIGZvciAoY29uc3Qgd29ya2VyIG9mIHBvb2wudXNlZCkge1xuICAgICAgcG9vbC5yZWxlYXNlKHdvcmtlci5yZXNvdXJjZSk7XG4gICAgfVxuXG4gICAgLy8gRGVzdHJveSB0aGUgcG9vbCBpZiBpdCBpcyBzdGlsbCBhdmFpbGFibGVcbiAgICBpZiAoIXBvb2wuZGVzdHJveWVkKSB7XG4gICAgICBhd2FpdCBwb29sLmRlc3Ryb3koKTtcbiAgICAgIGxvZyg0LCAnW2Jyb3dzZXJdIERlc3Ryb3llZCB0aGUgcG9vbCBvZiByZXNvdXJjZXMuJyk7XG4gICAgfVxuICB9XG5cbiAgLy8gQ2xvc2UgdGhlIGJyb3dzZXIgaW5zdGFuY2VcbiAgYXdhaXQgY2xvc2VCcm93c2VyKCk7XG59XG5cbi8qKlxuICogUHJvY2Vzc2VzIHRoZSBleHBvcnQgd29yayB1c2luZyBhIHdvcmtlciBmcm9tIHRoZSBwb29sLiBBY3F1aXJlcyBhIHdvcmtlclxuICogaGFuZGxlIGZyb20gdGhlIHBvb2wsIHBlcmZvcm1zIHRoZSBleHBvcnQgdXNpbmcgcHVwcGV0ZWVyLCBhbmQgcmVsZWFzZXNcbiAqIHRoZSB3b3JrZXIgaGFuZGxlIGJhY2sgdG8gdGhlIHBvb2wuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGNoYXJ0IC0gVGhlIGNoYXJ0IGRhdGEgb3IgY29uZmlndXJhdGlvbiB0byBiZSBleHBvcnRlZC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gRXhwb3J0IG9wdGlvbnMgYW5kIGNvbmZpZ3VyYXRpb24uXG4gKlxuICogQHJldHVybnMge1Byb21pc2U8T2JqZWN0Pn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2l0aCB0aGUgZXhwb3J0IHJlc3VsdGFuZFxuICogb3B0aW9ucy5cbiAqXG4gKiBAdGhyb3dzIHtFeHBvcnRFcnJvcn0gSWYgYW4gZXJyb3Igb2NjdXJzIGR1cmluZyB0aGUgZXhwb3J0IHByb2Nlc3MuXG4gKi9cbmV4cG9ydCBjb25zdCBwb3N0V29yayA9IGFzeW5jIChjaGFydCwgb3B0aW9ucykgPT4ge1xuICBsZXQgd29ya2VySGFuZGxlO1xuXG4gIHRyeSB7XG4gICAgbG9nKDQsICdbcG9vbF0gV29yayByZWNlaXZlZCwgc3RhcnRpbmcgdG8gcHJvY2Vzcy4nKTtcblxuICAgICsrc3RhdHMuZXhwb3J0QXR0ZW1wdHM7XG4gICAgaWYgKHBvb2xDb25maWcuYmVuY2htYXJraW5nKSB7XG4gICAgICBnZXRQb29sSW5mbygpO1xuICAgIH1cblxuICAgIGlmICghcG9vbCkge1xuICAgICAgdGhyb3cgbmV3IEV4cG9ydEVycm9yKCdXb3JrIHJlY2VpdmVkLCBidXQgcG9vbCBoYXMgbm90IGJlZW4gc3RhcnRlZC4nKTtcbiAgICB9XG5cbiAgICAvLyBBY3F1aXJlIHRoZSB3b3JrZXIgYWxvbmcgd2l0aCB0aGUgaWQgb2YgcmVzb3VyY2UgYW5kIHdvcmsgY291bnRcbiAgICBjb25zdCBhY3F1aXJlQ291bnRlciA9IG1lYXN1cmVUaW1lKCk7XG4gICAgdHJ5IHtcbiAgICAgIGxvZyg0LCAnW3Bvb2xdIEFjcXVpcmluZyBhIHdvcmtlciBoYW5kbGUuJyk7XG4gICAgICB3b3JrZXJIYW5kbGUgPSBhd2FpdCBwb29sLmFjcXVpcmUoKS5wcm9taXNlO1xuXG4gICAgICAvLyBDaGVjayB0aGUgcGFnZSBhY3F1aXJlIHRpbWVcbiAgICAgIGlmIChvcHRpb25zLnNlcnZlci5iZW5jaG1hcmtpbmcpIHtcbiAgICAgICAgbG9nKFxuICAgICAgICAgIDUsXG4gICAgICAgICAgb3B0aW9ucy5wYXlsb2FkPy5yZXF1ZXN0SWRcbiAgICAgICAgICAgID8gYFtiZW5jaG1hcmtdIFJlcXVlc3Qgd2l0aCBJRCAke29wdGlvbnMucGF5bG9hZD8ucmVxdWVzdElkfSAtYFxuICAgICAgICAgICAgOiAnW2JlbmNobWFya10nLFxuICAgICAgICAgIGBBY3F1aXJlZCBhIHdvcmtlciBoYW5kbGU6ICR7YWNxdWlyZUNvdW50ZXIoKX1tcy5gXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRocm93IG5ldyBFeHBvcnRFcnJvcihcbiAgICAgICAgKG9wdGlvbnMucGF5bG9hZD8ucmVxdWVzdElkXG4gICAgICAgICAgPyBgRm9yIHJlcXVlc3Qgd2l0aCBJRCAke29wdGlvbnMucGF5bG9hZD8ucmVxdWVzdElkfSAtIGBcbiAgICAgICAgICA6ICcnKSArXG4gICAgICAgICAgYEVycm9yIGVuY291bnRlcmVkIHdoZW4gYWNxdWlyaW5nIGFuIGF2YWlsYWJsZSBlbnRyeTogJHthY3F1aXJlQ291bnRlcigpfW1zLmBcbiAgICAgICkuc2V0RXJyb3IoZXJyb3IpO1xuICAgIH1cbiAgICBsb2coNCwgJ1twb29sXSBBY3F1aXJlZCBhIHdvcmtlciBoYW5kbGUuJyk7XG5cbiAgICBpZiAoIXdvcmtlckhhbmRsZS5wYWdlKSB7XG4gICAgICB0aHJvdyBuZXcgRXhwb3J0RXJyb3IoXG4gICAgICAgICdSZXNvbHZlZCB3b3JrZXIgcGFnZSBpcyBpbnZhbGlkOiB0aGUgcG9vbCBzZXR1cCBpcyB3b25reS4nXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIFNhdmUgdGhlIHN0YXJ0IHRpbWVcbiAgICBsZXQgd29ya1N0YXJ0ID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG5cbiAgICBsb2coNCwgYFtwb29sXSBTdGFydGluZyB3b3JrIG9uIHBvb2wgZW50cnkgd2l0aCBJRCAke3dvcmtlckhhbmRsZS5pZH0uYCk7XG5cbiAgICAvLyBQZXJmb3JtIGFuIGV4cG9ydCBvbiBhIHB1cHBldGVlciBsZXZlbFxuICAgIGNvbnN0IGV4cG9ydENvdW50ZXIgPSBtZWFzdXJlVGltZSgpO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHB1cHBldGVlckV4cG9ydCh3b3JrZXJIYW5kbGUucGFnZSwgY2hhcnQsIG9wdGlvbnMpO1xuXG4gICAgLy8gQ2hlY2sgaWYgaXQncyBhbiBlcnJvclxuICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgLy8gTk9URTogSWYgdGhlcmUncyBhIHJhc3Rlcml6YXRpb24gdGltZW91dCwgd2Ugd2FudCBuZWVkIHRvIGZsdXNoIHRoZSBwYWdlLlxuICAgICAgLy8gICAgICAgVGhpcyBpcyBiZWNhdXNlIHRoZSBwYWdlIG1heSBiZSBpbiBhIHN0YXRlIHdoZXJlIGl0J3Mgd2FpdGluZyBmb3JcbiAgICAgIC8vICAgICAgIHRoZSBzY3JlZW5zaG90IHRvIGZpbmlzaCBldmVuIHRob3VnaCB0aGUgdGltZW91dCBoYXMgb2NjdXJlZC5cbiAgICAgIC8vICAgICAgIFdoaWNoIG9mIGNvdXJzZSBjYXVzZXMgYSBsb3Qgb2YgaXNzdWVzIHdpdGggdGhlIGV2ZW50IHN5c3RlbSxcbiAgICAgIC8vICAgICAgIGFuZCBwYWdlIGNvbnNpc3RlbmN5LlxuICAgICAgLy9cbiAgICAgIC8vIE5PVEU6IE9ubHkgcGFnZS5zY3JlZW5zaG90IHdpbGwgdGhyb3cgdGhpcywgdGltZW91dHMgZm9yIFBERidzIGFyZVxuICAgICAgLy8gICAgICAgaGFuZGxlZCBieSB0aGUgcGFnZS5wZGYgZnVuY3Rpb24gaXRzZWxmLlxuICAgICAgLy9cbiAgICAgIC8vICAgICAgIC4uLnllcywgdGhpcyBpcyB1Z2x5LlxuICAgICAgaWYgKHJlc3VsdC5tZXNzYWdlID09PSAnUmFzdGVyaXphdGlvbiB0aW1lb3V0Jykge1xuICAgICAgICB3b3JrZXJIYW5kbGUud29ya0NvdW50ID0gcG9vbENvbmZpZy53b3JrTGltaXQgKyAxO1xuICAgICAgICB3b3JrZXJIYW5kbGUucGFnZSA9IG51bGw7XG4gICAgICB9XG5cbiAgICAgIGlmIChcbiAgICAgICAgcmVzdWx0Lm5hbWUgPT09ICdUaW1lb3V0RXJyb3InIHx8XG4gICAgICAgIHJlc3VsdC5tZXNzYWdlID09PSAnUmFzdGVyaXphdGlvbiB0aW1lb3V0J1xuICAgICAgKSB7XG4gICAgICAgIHRocm93IG5ldyBFeHBvcnRFcnJvcihcbiAgICAgICAgICAnUmFzdGVyaXphdGlvbiB0aW1lb3V0OiB5b3VyIGNoYXJ0IG1heSBiZSB0b28gY29tcGxleCBvciBsYXJnZSwgYW5kIGZhaWxlZCB0byByZW5kZXIgd2l0aGluIHRoZSBhbGxvdHRlZCB0aW1lLidcbiAgICAgICAgKS5zZXRFcnJvcihyZXN1bHQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEV4cG9ydEVycm9yKFxuICAgICAgICAgIChvcHRpb25zLnBheWxvYWQ/LnJlcXVlc3RJZFxuICAgICAgICAgICAgPyBgRm9yIHJlcXVlc3Qgd2l0aCBJRCAke29wdGlvbnMucGF5bG9hZD8ucmVxdWVzdElkfSAtIGBcbiAgICAgICAgICAgIDogJycpICsgYEVycm9yIGVuY291bnRlcmVkIGR1cmluZyBleHBvcnQ6ICR7ZXhwb3J0Q291bnRlcigpfW1zLmBcbiAgICAgICAgKS5zZXRFcnJvcihyZXN1bHQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIENoZWNrIHRoZSBQdXBwZXRlZXIgZXhwb3J0IHRpbWVcbiAgICBpZiAob3B0aW9ucy5zZXJ2ZXIuYmVuY2htYXJraW5nKSB7XG4gICAgICBsb2coXG4gICAgICAgIDUsXG4gICAgICAgIG9wdGlvbnMucGF5bG9hZD8ucmVxdWVzdElkXG4gICAgICAgICAgPyBgW2JlbmNobWFya10gUmVxdWVzdCB3aXRoIElEICR7b3B0aW9ucy5wYXlsb2FkPy5yZXF1ZXN0SWR9IC1gXG4gICAgICAgICAgOiAnW2JlbmNobWFya10nLFxuICAgICAgICBgRXhwb3J0ZWQgYSBjaGFydCBzdWNlc3NmdWxseTogJHtleHBvcnRDb3VudGVyKCl9bXMuYFxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBSZWxlYXNlIHRoZSByZXNvdXJjZSBiYWNrIHRvIHRoZSBwb29sXG4gICAgcG9vbC5yZWxlYXNlKHdvcmtlckhhbmRsZSk7XG5cbiAgICAvLyBVc2VkIGZvciBzdGF0aXN0aWNzIGluIGF2ZXJhZ2VUaW1lIGFuZCBwcm9jZXNzZWRXb3JrQ291bnQsIHdoaWNoXG4gICAgLy8gaW4gdHVybiBpcyB1c2VkIGJ5IHRoZSAvaGVhbHRoIHJvdXRlLlxuICAgIGNvbnN0IHdvcmtFbmQgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgICBjb25zdCBleHBvcnRUaW1lID0gd29ya0VuZCAtIHdvcmtTdGFydDtcbiAgICBzdGF0cy50aW1lU3BlbnQgKz0gZXhwb3J0VGltZTtcbiAgICBzdGF0cy5zcGVudEF2ZXJhZ2UgPSBzdGF0cy50aW1lU3BlbnQgLyArK3N0YXRzLnBlcmZvcm1lZEV4cG9ydHM7XG5cbiAgICBsb2coNCwgYFtwb29sXSBXb3JrIGNvbXBsZXRlZCBpbiAke2V4cG9ydFRpbWV9IG1zLmApO1xuXG4gICAgLy8gT3RoZXJ3aXNlIHJldHVybiB0aGUgcmVzdWx0XG4gICAgcmV0dXJuIHtcbiAgICAgIHJlc3VsdCxcbiAgICAgIG9wdGlvbnNcbiAgICB9O1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgICsrc3RhdHMuZHJvcHBlZEV4cG9ydHM7XG5cbiAgICBpZiAod29ya2VySGFuZGxlKSB7XG4gICAgICBwb29sLnJlbGVhc2Uod29ya2VySGFuZGxlKTtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgRXhwb3J0RXJyb3IoYFtwb29sXSBJbiBwb29sLnBvc3RXb3JrOiAke2Vycm9yLm1lc3NhZ2V9YCkuc2V0RXJyb3IoXG4gICAgICBlcnJvclxuICAgICk7XG4gIH1cbn07XG5cbi8qKlxuICogUmV0cmlldmVzIHRoZSBjdXJyZW50IHBvb2wgaW5zdGFuY2UuXG4gKlxuICogQHJldHVybnMge09iamVjdHxudWxsfSBUaGUgY3VycmVudCBwb29sIGluc3RhbmNlIGlmIGluaXRpYWxpemVkLCBvciBudWxsXG4gKiBpZiB0aGUgcG9vbCBoYXMgbm90IGJlZW4gY3JlYXRlZC5cbiAqL1xuZXhwb3J0IGNvbnN0IGdldFBvb2wgPSAoKSA9PiBwb29sO1xuXG4vKipcbiAqIFJldHJpZXZlcyBwb29sIGluZm9ybWF0aW9uIGluIEpTT04gZm9ybWF0LCBpbmNsdWRpbmcgbWluaW11bSBhbmQgbWF4aW11bVxuICogd29ya2VycywgYXZhaWxhYmxlIHdvcmtlcnMsIHdvcmtlcnMgaW4gdXNlLCBhbmQgcGVuZGluZyBhY3F1aXJlIHJlcXVlc3RzLlxuICpcbiAqIEByZXR1cm5zIHtPYmplY3R9IFBvb2wgaW5mb3JtYXRpb24gaW4gSlNPTiBmb3JtYXQuXG4gKi9cbmV4cG9ydCBjb25zdCBnZXRQb29sSW5mb0pTT04gPSAoKSA9PiAoe1xuICBtaW46IHBvb2wubWluLFxuICBtYXg6IHBvb2wubWF4LFxuICBhbGw6IHBvb2wubnVtRnJlZSgpICsgcG9vbC5udW1Vc2VkKCksXG4gIGF2YWlsYWJsZTogcG9vbC5udW1GcmVlKCksXG4gIHVzZWQ6IHBvb2wubnVtVXNlZCgpLFxuICBwZW5kaW5nOiBwb29sLm51bVBlbmRpbmdBY3F1aXJlcygpXG59KTtcblxuLyoqXG4gKiBMb2dzIGluZm9ybWF0aW9uIGFib3V0IHRoZSBjdXJyZW50IHN0YXRlIG9mIHRoZSBwb29sLCBpbmNsdWRpbmcgdGhlIG1pbmltdW1cbiAqIGFuZCBtYXhpbXVtIHdvcmtlcnMsIGF2YWlsYWJsZSB3b3JrZXJzLCB3b3JrZXJzIGluIHVzZSwgYW5kIHBlbmRpbmcgYWNxdWlyZVxuICogcmVxdWVzdHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRQb29sSW5mbygpIHtcbiAgY29uc3QgeyBtaW4sIG1heCwgYWxsLCBhdmFpbGFibGUsIHVzZWQsIHBlbmRpbmcgfSA9IGdldFBvb2xJbmZvSlNPTigpO1xuXG4gIGxvZyg1LCBgW3Bvb2xdIFRoZSBtaW5pbXVtIG51bWJlciBvZiByZXNvdXJjZXMgYWxsb3dlZCBieSBwb29sOiAke21pbn0uYCk7XG4gIGxvZyg1LCBgW3Bvb2xdIFRoZSBtYXhpbXVtIG51bWJlciBvZiByZXNvdXJjZXMgYWxsb3dlZCBieSBwb29sOiAke21heH0uYCk7XG4gIGxvZyg1LCBgW3Bvb2xdIFRoZSBudW1iZXIgb2YgYWxsIGNyZWF0ZWQgcmVzb3VyY2VzOiAke2FsbH0uYCk7XG4gIGxvZyg1LCBgW3Bvb2xdIFRoZSBudW1iZXIgb2YgYXZhaWxhYmxlIHJlc291cmNlczogJHthdmFpbGFibGV9LmApO1xuICBsb2coNSwgYFtwb29sXSBUaGUgbnVtYmVyIG9mIGFjcXVpcmVkIHJlc291cmNlczogJHt1c2VkfS5gKTtcbiAgbG9nKDUsIGBbcG9vbF0gVGhlIG51bWJlciBvZiByZXNvdXJjZXMgd2FpdGluZyB0byBiZSBhY3F1aXJlZDogJHtwZW5kaW5nfS5gKTtcbn1cblxuZXhwb3J0IGRlZmF1bHQge1xuICBpbml0UG9vbCxcbiAga2lsbFBvb2wsXG4gIHBvc3RXb3JrLFxuICBnZXRQb29sLFxuICBnZXRQb29sSW5mbyxcbiAgZ2V0UG9vbEluZm9KU09OLFxuICBnZXRTdGF0czogKCkgPT4gc3RhdHNcbn07XG4iLCIvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuXG5IaWdoY2hhcnRzIEV4cG9ydCBTZXJ2ZXJcblxuQ29weXJpZ2h0IChjKSAyMDE2LTIwMjQsIEhpZ2hzb2Z0XG5cbkxpY2VuY2VkIHVuZGVyIHRoZSBNSVQgbGljZW5jZS5cblxuQWRkaXRpb25hbGx5IGEgdmFsaWQgSGlnaGNoYXJ0cyBsaWNlbnNlIGlzIHJlcXVpcmVkIGZvciB1c2UuXG5cblNlZSBMSUNFTlNFIGZpbGUgaW4gcm9vdCBmb3IgZGV0YWlscy5cblxuKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuaW1wb3J0IHsgcmVhZEZpbGVTeW5jLCB3cml0ZUZpbGVTeW5jIH0gZnJvbSAnZnMnO1xuXG5pbXBvcnQgeyBnZXRPcHRpb25zLCBpbml0RXhwb3J0U2V0dGluZ3MgfSBmcm9tICcuL2NvbmZpZy5qcyc7XG5pbXBvcnQgeyBsb2csIGxvZ1dpdGhTdGFjayB9IGZyb20gJy4vbG9nZ2VyLmpzJztcbmltcG9ydCB7IGtpbGxQb29sLCBwb3N0V29yaywgc3RhdHMgfSBmcm9tICcuL3Bvb2wuanMnO1xuaW1wb3J0IHtcbiAgZml4VHlwZSxcbiAgaGFuZGxlUmVzb3VyY2VzLFxuICBpc0NvcnJlY3RKU09OLFxuICBvcHRpb25zU3RyaW5naWZ5LFxuICByb3VuZE51bWJlcixcbiAgdG9Cb29sZWFuLFxuICB3cmFwQXJvdW5kXG59IGZyb20gJy4vdXRpbHMuanMnO1xuaW1wb3J0IHsgc2FuaXRpemUgfSBmcm9tICcuL3Nhbml0aXplLmpzJztcbmltcG9ydCBFeHBvcnRFcnJvciBmcm9tICcuL2Vycm9ycy9FeHBvcnRFcnJvci5qcyc7XG5cbmxldCBhbGxvd0NvZGVFeGVjdXRpb24gPSBmYWxzZTtcblxuLyoqXG4gKiBTdGFydHMgYW4gZXhwb3J0IHByb2Nlc3MuIFRoZSBgc2V0dGluZ3NgIGNvbnRhaW5zIGZpbmFsIG9wdGlvbnMgZ2F0aGVyZWRcbiAqIGZyb20gYWxsIHBvc3NpYmxlIHNvdXJjZXMgKGNvbmZpZywgZW52LCBjbGksIGpzb24pLiBUaGUgYGVuZENhbGxiYWNrYCBpc1xuICogY2FsbGVkIHdoZW4gdGhlIGV4cG9ydCBpcyBjb21wbGV0ZWQsIHdpdGggYW4gZXJyb3Igb2JqZWN0IGFzIHRoZSBmaXJzdFxuICogYXJndW1lbnQgYW5kIHRoZSBzZWNvbmQgY29udGFpbmluZyB0aGUgYmFzZTY0IHJlc3ByZXNlbnRhdGlvbiBvZiBhIGNoYXJ0LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBzZXR0aW5ncyAtIFRoZSBzZXR0aW5ncyBvYmplY3QgY29udGFpbmluZyBleHBvcnRcbiAqIGNvbmZpZ3VyYXRpb24uXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBlbmRDYWxsYmFjayAtIFRoZSBjYWxsYmFjayBmdW5jdGlvbiB0byBiZSBpbnZva2VkIHVwb25cbiAqIGZpbmFsaXppbmcgd29yayBvciB1cG9uIGVycm9yIG9jY3VyYW5jZSBvZiB0aGUgZXhwb3J0aW5nIHByb2Nlc3MuXG4gKlxuICogQHJldHVybnMge3ZvaWR9IFRoaXMgZnVuY3Rpb24gZG9lcyBub3QgcmV0dXJuIGEgdmFsdWUgZGlyZWN0bHk7IGluc3RlYWQsXG4gKiBpdCBjb21tdW5pY2F0ZXMgcmVzdWx0cyB2aWEgdGhlIGVuZENhbGxiYWNrLlxuICovXG5leHBvcnQgY29uc3Qgc3RhcnRFeHBvcnQgPSBhc3luYyAoc2V0dGluZ3MsIGVuZENhbGxiYWNrKSA9PiB7XG4gIC8vIFN0YXJ0aW5nIGV4cG9ydGluZyBwcm9jZXNzIG1lc3NhZ2VcbiAgbG9nKDQsICdbY2hhcnRdIFN0YXJ0aW5nIHRoZSBleHBvcnRpbmcgcHJvY2Vzcy4nKTtcblxuICAvLyBJbml0aWFsaXplIG9wdGlvbnNcbiAgY29uc3Qgb3B0aW9ucyA9IGluaXRFeHBvcnRTZXR0aW5ncyhzZXR0aW5ncywgZ2V0T3B0aW9ucygpKTtcblxuICAvLyBHZXQgdGhlIGV4cG9ydCBvcHRpb25zXG4gIGNvbnN0IGV4cG9ydE9wdGlvbnMgPSBvcHRpb25zLmV4cG9ydDtcblxuICAvLyBJZiBTVkcgaXMgYW4gaW5wdXQgKGFyZ3VtZW50IGNhbiBiZSBzZW50IG9ubHkgYnkgdGhlIHJlcXVlc3QpXG4gIGlmIChvcHRpb25zLnBheWxvYWQ/LnN2ZyAmJiBvcHRpb25zLnBheWxvYWQuc3ZnICE9PSAnJykge1xuICAgIHRyeSB7XG4gICAgICBsb2coNCwgJ1tjaGFydF0gQXR0ZW1wdGluZyB0byBleHBvcnQgZnJvbSBhIFNWRyBpbnB1dC4nKTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gZXhwb3J0QXNTdHJpbmcoXG4gICAgICAgIHNhbml0aXplKG9wdGlvbnMucGF5bG9hZC5zdmcpLCAvLyAjMjA5XG4gICAgICAgIG9wdGlvbnMsXG4gICAgICAgIGVuZENhbGxiYWNrXG4gICAgICApO1xuXG4gICAgICArK3N0YXRzLmV4cG9ydEZyb21TdmdBdHRlbXB0cztcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHJldHVybiBlbmRDYWxsYmFjayhcbiAgICAgICAgbmV3IEV4cG9ydEVycm9yKCdbY2hhcnRdIEVycm9yIGxvYWRpbmcgU1ZHIGlucHV0LicpLnNldEVycm9yKGVycm9yKVxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvLyBFeHBvcnQgdXNpbmcgb3B0aW9ucyBmcm9tIHRoZSBmaWxlXG4gIGlmIChleHBvcnRPcHRpb25zLmluZmlsZSAmJiBleHBvcnRPcHRpb25zLmluZmlsZS5sZW5ndGgpIHtcbiAgICAvLyBUcnkgdG8gcmVhZCB0aGUgZmlsZSB0byBnZXQgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvblxuICAgIHRyeSB7XG4gICAgICBsb2coNCwgJ1tjaGFydF0gQXR0ZW1wdGluZyB0byBleHBvcnQgZnJvbSBhbiBpbnB1dCBmaWxlLicpO1xuICAgICAgb3B0aW9ucy5leHBvcnQuaW5zdHIgPSByZWFkRmlsZVN5bmMoZXhwb3J0T3B0aW9ucy5pbmZpbGUsICd1dGY4Jyk7XG4gICAgICByZXR1cm4gZXhwb3J0QXNTdHJpbmcob3B0aW9ucy5leHBvcnQuaW5zdHIudHJpbSgpLCBvcHRpb25zLCBlbmRDYWxsYmFjayk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHJldHVybiBlbmRDYWxsYmFjayhcbiAgICAgICAgbmV3IEV4cG9ydEVycm9yKCdbY2hhcnRdIEVycm9yIGxvYWRpbmcgaW5wdXQgZmlsZS4nKS5zZXRFcnJvcihlcnJvcilcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLy8gRXhwb3J0IHdpdGggb3B0aW9ucyBmcm9tIHRoZSByYXcgcmVwcmVzZW50YXRpb25cbiAgaWYgKFxuICAgIChleHBvcnRPcHRpb25zLmluc3RyICYmIGV4cG9ydE9wdGlvbnMuaW5zdHIgIT09ICcnKSB8fFxuICAgIChleHBvcnRPcHRpb25zLm9wdGlvbnMgJiYgZXhwb3J0T3B0aW9ucy5vcHRpb25zICE9PSAnJylcbiAgKSB7XG4gICAgdHJ5IHtcbiAgICAgIGxvZyg0LCAnW2NoYXJ0XSBBdHRlbXB0aW5nIHRvIGV4cG9ydCBmcm9tIGEgcmF3IGlucHV0LicpO1xuXG4gICAgICAvLyBVc2Ugd2hpY2hldmVyIG9uZSBpcyBhdmFpbGFibGVcbiAgICAgIGV4cG9ydE9wdGlvbnMuaW5zdHIgPSBleHBvcnRPcHRpb25zLmluc3RyIHx8IGV4cG9ydE9wdGlvbnMub3B0aW9ucztcblxuICAgICAgLy8gUGVyZm9ybSBhIGRpcmVjdCBpbmplY3Qgd2hlbiBmb3JjZWRcbiAgICAgIGlmICh0b0Jvb2xlYW4ob3B0aW9ucy5jdXN0b21Mb2dpYz8uYWxsb3dDb2RlRXhlY3V0aW9uKSkge1xuICAgICAgICByZXR1cm4gZG9TdHJhaWdodEluamVjdChvcHRpb25zLCBlbmRDYWxsYmFjayk7XG4gICAgICB9XG5cbiAgICAgIC8vIEVpdGhlciB0cnkgdG8gcGFyc2UgdG8gSlNPTiBmaXJzdCBvciBkbyB0aGUgZGlyZWN0IGV4cG9ydFxuICAgICAgcmV0dXJuIHR5cGVvZiBleHBvcnRPcHRpb25zLmluc3RyID09PSAnc3RyaW5nJ1xuICAgICAgICA/IGV4cG9ydEFzU3RyaW5nKGV4cG9ydE9wdGlvbnMuaW5zdHIudHJpbSgpLCBvcHRpb25zLCBlbmRDYWxsYmFjaylcbiAgICAgICAgOiBkb0V4cG9ydChcbiAgICAgICAgICAgIG9wdGlvbnMsXG4gICAgICAgICAgICBleHBvcnRPcHRpb25zLmluc3RyIHx8IGV4cG9ydE9wdGlvbnMub3B0aW9ucyxcbiAgICAgICAgICAgIGVuZENhbGxiYWNrXG4gICAgICAgICAgKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcmV0dXJuIGVuZENhbGxiYWNrKFxuICAgICAgICBuZXcgRXhwb3J0RXJyb3IoJ1tjaGFydF0gRXJyb3IgbG9hZGluZyByYXcgaW5wdXQuJykuc2V0RXJyb3IoZXJyb3IpXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8vIE5vIGlucHV0IHNwZWNpZmllZCwgcGFzcyBhbiBlcnJvciBtZXNzYWdlIHRvIHRoZSBjYWxsYmFja1xuICByZXR1cm4gZW5kQ2FsbGJhY2soXG4gICAgbmV3IEV4cG9ydEVycm9yKFxuICAgICAgYFtjaGFydF0gTm8gdmFsaWQgaW5wdXQgc3BlY2lmaWVkLiBDaGVjayBpZiBhdCBsZWFzdCBvbmUgb2YgdGhlIGZvbGxvd2luZyBwYXJhbWV0ZXJzIGlzIGNvcnJlY3RseSBzZXQ6ICdpbmZpbGUnLCAnaW5zdHInLCAnb3B0aW9ucycsIG9yICdzdmcnLmBcbiAgICApXG4gICk7XG59O1xuXG4vKipcbiAqIFN0YXJ0cyBhIGJhdGNoIGV4cG9ydCBwcm9jZXNzIGZvciBtdWx0aXBsZSBjaGFydHMgYmFzZWQgb24gdGhlIGluZm9ybWF0aW9uXG4gKiBpbiB0aGUgYmF0Y2ggb3B0aW9uLiBUaGUgYmF0Y2ggaXMgYSBzdHJpbmcgaW4gdGhlIGZvbGxvd2luZyBmb3JtYXQ6XG4gKiBcImluZmlsZTEuanNvbj1vdXRmaWxlMS5wbmc7aW5maWxlMi5qc29uPW91dGZpbGUyLnBuZzsuLi5cIlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gVGhlIG9wdGlvbnMgb2JqZWN0IGNvbnRhaW5pbmcgY29uZmlndXJhdGlvbiBmb3JcbiAqIGEgYmF0Y2ggZXhwb3J0LlxuICpcbiAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSBBIFByb21pc2UgdGhhdCByZXNvbHZlcyBvbmNlIHRoZSBiYXRjaCBleHBvcnRcbiAqIHByb2Nlc3MgaXMgY29tcGxldGVkLlxuICpcbiAqIEB0aHJvd3Mge0V4cG9ydEVycm9yfSBUaHJvd3MgYW4gRXhwb3J0RXJyb3IgaWYgYW4gZXJyb3Igb2NjdXJzIGR1cmluZ1xuICogYW55IG9mIHRoZSBiYXRjaCBleHBvcnQgcHJvY2Vzcy5cbiAqL1xuZXhwb3J0IGNvbnN0IGJhdGNoRXhwb3J0ID0gYXN5bmMgKG9wdGlvbnMpID0+IHtcbiAgY29uc3QgYmF0Y2hGdW5jdGlvbnMgPSBbXTtcblxuICAvLyBTcGxpdCBhbmQgcGFpciB0aGUgLS1iYXRjaCBhcmd1bWVudHNcbiAgZm9yIChsZXQgcGFpciBvZiBvcHRpb25zLmV4cG9ydC5iYXRjaC5zcGxpdCgnOycpKSB7XG4gICAgcGFpciA9IHBhaXIuc3BsaXQoJz0nKTtcbiAgICBpZiAocGFpci5sZW5ndGggPT09IDIpIHtcbiAgICAgIGJhdGNoRnVuY3Rpb25zLnB1c2goXG4gICAgICAgIHN0YXJ0RXhwb3J0KFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIC4uLm9wdGlvbnMsXG4gICAgICAgICAgICBleHBvcnQ6IHtcbiAgICAgICAgICAgICAgLi4ub3B0aW9ucy5leHBvcnQsXG4gICAgICAgICAgICAgIGluZmlsZTogcGFpclswXSxcbiAgICAgICAgICAgICAgb3V0ZmlsZTogcGFpclsxXVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgICAgKGVycm9yLCBpbmZvKSA9PiB7XG4gICAgICAgICAgICAvLyBUaHJvdyBhbiBlcnJvclxuICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBTYXZlIHRoZSBiYXNlNjQgZnJvbSBhIGJ1ZmZlciB0byBhIGNvcnJlY3QgaW1hZ2UgZmlsZVxuICAgICAgICAgICAgd3JpdGVGaWxlU3luYyhcbiAgICAgICAgICAgICAgaW5mby5vcHRpb25zLmV4cG9ydC5vdXRmaWxlLFxuICAgICAgICAgICAgICBpbmZvLm9wdGlvbnMuZXhwb3J0LnR5cGUgIT09ICdzdmcnXG4gICAgICAgICAgICAgICAgPyBCdWZmZXIuZnJvbShpbmZvLnJlc3VsdCwgJ2Jhc2U2NCcpXG4gICAgICAgICAgICAgICAgOiBpbmZvLnJlc3VsdFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIClcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgdHJ5IHtcbiAgICAvLyBBd2FpdCBhbGwgZXhwb3J0cyBhcmUgZG9uZVxuICAgIGF3YWl0IFByb21pc2UuYWxsKGJhdGNoRnVuY3Rpb25zKTtcblxuICAgIC8vIEtpbGwgcG9vbCBhbmQgY2xvc2UgYnJvd3NlciBhZnRlciBmaW5pc2hpbmcgYmF0Y2ggZXhwb3J0XG4gICAgYXdhaXQga2lsbFBvb2woKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICB0aHJvdyBuZXcgRXhwb3J0RXJyb3IoXG4gICAgICAnW2NoYXJ0XSBFcnJvciBlbmNvdW50ZXJlZCBkdXJpbmcgYmF0Y2ggZXhwb3J0LidcbiAgICApLnNldEVycm9yKGVycm9yKTtcbiAgfVxufTtcblxuLyoqXG4gKiBTdGFydHMgYSBzaW5nbGUgZXhwb3J0IHByb2Nlc3MgYmFzZWQgb24gdGhlIHNwZWNpZmllZCBvcHRpb25zLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gVGhlIG9wdGlvbnMgb2JqZWN0IGNvbnRhaW5pbmcgY29uZmlndXJhdGlvbiBmb3JcbiAqIGEgc2luZ2xlIGV4cG9ydC5cbiAqXG4gKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gQSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgb25jZSB0aGUgc2luZ2xlIGV4cG9ydFxuICogcHJvY2VzcyBpcyBjb21wbGV0ZWQuXG4gKlxuICogQHRocm93cyB7RXhwb3J0RXJyb3J9IFRocm93cyBhbiBFeHBvcnRFcnJvciBpZiBhbiBlcnJvciBvY2N1cnMgZHVyaW5nXG4gKiB0aGUgc2luZ2xlIGV4cG9ydCBwcm9jZXNzLlxuICovXG5leHBvcnQgY29uc3Qgc2luZ2xlRXhwb3J0ID0gYXN5bmMgKG9wdGlvbnMpID0+IHtcbiAgLy8gVXNlIGluc3RyIG9yIGl0cyBhbGlhcywgb3B0aW9uc1xuICBvcHRpb25zLmV4cG9ydC5pbnN0ciA9IG9wdGlvbnMuZXhwb3J0Lmluc3RyIHx8IG9wdGlvbnMuZXhwb3J0Lm9wdGlvbnM7XG5cbiAgLy8gUGVyZm9ybSBhbiBleHBvcnRcbiAgYXdhaXQgc3RhcnRFeHBvcnQob3B0aW9ucywgYXN5bmMgKGVycm9yLCBpbmZvKSA9PiB7XG4gICAgLy8gRXhpdCBwcm9jZXNzIHdoZW4gZXJyb3JcbiAgICBpZiAoZXJyb3IpIHtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cblxuICAgIGNvbnN0IHsgb3V0ZmlsZSwgdHlwZSB9ID0gaW5mby5vcHRpb25zLmV4cG9ydDtcblxuICAgIC8vIFNhdmUgdGhlIGJhc2U2NCBmcm9tIGEgYnVmZmVyIHRvIGEgY29ycmVjdCBpbWFnZSBmaWxlXG4gICAgd3JpdGVGaWxlU3luYyhcbiAgICAgIG91dGZpbGUgfHwgYGNoYXJ0LiR7dHlwZX1gLFxuICAgICAgdHlwZSAhPT0gJ3N2ZycgPyBCdWZmZXIuZnJvbShpbmZvLnJlc3VsdCwgJ2Jhc2U2NCcpIDogaW5mby5yZXN1bHRcbiAgICApO1xuXG4gICAgLy8gS2lsbCBwb29sIGFuZCBjbG9zZSBicm93c2VyIGFmdGVyIGZpbmlzaGluZyBzaW5nbGUgZXhwb3J0XG4gICAgYXdhaXQga2lsbFBvb2woKTtcbiAgfSk7XG59O1xuXG4vKipcbiAqIERldGVybWluZXMgdGhlIHNpemUgYW5kIHNjYWxlIGZvciBjaGFydCBleHBvcnQgYmFzZWQgb24gdGhlIHByb3ZpZGVkIG9wdGlvbnMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgLSBUaGUgb3B0aW9ucyBvYmplY3QgY29udGFpbmluZyBjb25maWd1cmF0aW9uIGZvclxuICogY2hhcnQgZXhwb3J0LlxuICpcbiAqIEByZXR1cm5zIHtPYmplY3R9IEFuIG9iamVjdCBjb250YWluaW5nIHRoZSBjYWxjdWxhdGVkIGhlaWdodCwgd2lkdGgsXG4gKiBhbmQgc2NhbGUgZm9yIHRoZSBjaGFydCBleHBvcnQuXG4gKi9cbmV4cG9ydCBjb25zdCBmaW5kQ2hhcnRTaXplID0gKG9wdGlvbnMpID0+IHtcbiAgY29uc3QgeyBjaGFydCwgZXhwb3J0aW5nIH0gPVxuICAgIG9wdGlvbnMuZXhwb3J0Py5vcHRpb25zIHx8IGlzQ29ycmVjdEpTT04ob3B0aW9ucy5leHBvcnQ/Lmluc3RyKTtcblxuICAvLyBTZWUgaWYgZ2xvYmFsT3B0aW9ucyBob2xkcyBjaGFydCBvciBleHBvcnRpbmcgc2l6ZVxuICBjb25zdCBnbG9iYWxPcHRpb25zID0gaXNDb3JyZWN0SlNPTihvcHRpb25zLmV4cG9ydD8uZ2xvYmFsT3B0aW9ucyk7XG5cbiAgLy8gU2VjdXJlIHNjYWxlIHZhbHVlXG4gIGxldCBzY2FsZSA9XG4gICAgb3B0aW9ucy5leHBvcnQ/LnNjYWxlIHx8XG4gICAgZXhwb3J0aW5nPy5zY2FsZSB8fFxuICAgIGdsb2JhbE9wdGlvbnM/LmV4cG9ydGluZz8uc2NhbGUgfHxcbiAgICBvcHRpb25zLmV4cG9ydD8uZGVmYXVsdFNjYWxlIHx8XG4gICAgMTtcblxuICAvLyB0aGUgc2NhbGUgY2Fubm90IGJlIGxvd2VyIHRoYW4gMC4xIGFuZCBjYW5ub3QgYmUgaGlnaGVyIHRoYW4gNS4wXG4gIHNjYWxlID0gTWF0aC5tYXgoMC4xLCBNYXRoLm1pbihzY2FsZSwgNS4wKSk7XG5cbiAgLy8gd2Ugd2FudCB0byByb3VuZCB0aGUgbnVtYmVycyBsaWtlIDAuMjMyMzQgLT4gMC4yM1xuICBzY2FsZSA9IHJvdW5kTnVtYmVyKHNjYWxlLCAyKTtcblxuICAvLyBGaW5kIGNoYXJ0IHNpemUgYW5kIHNjYWxlXG4gIGNvbnN0IHNpemUgPSB7XG4gICAgaGVpZ2h0OlxuICAgICAgb3B0aW9ucy5leHBvcnQ/LmhlaWdodCB8fFxuICAgICAgZXhwb3J0aW5nPy5zb3VyY2VIZWlnaHQgfHxcbiAgICAgIGNoYXJ0Py5oZWlnaHQgfHxcbiAgICAgIGdsb2JhbE9wdGlvbnM/LmV4cG9ydGluZz8uc291cmNlSGVpZ2h0IHx8XG4gICAgICBnbG9iYWxPcHRpb25zPy5jaGFydD8uaGVpZ2h0IHx8XG4gICAgICBvcHRpb25zLmV4cG9ydD8uZGVmYXVsdEhlaWdodCB8fFxuICAgICAgNDAwLFxuICAgIHdpZHRoOlxuICAgICAgb3B0aW9ucy5leHBvcnQ/LndpZHRoIHx8XG4gICAgICBleHBvcnRpbmc/LnNvdXJjZVdpZHRoIHx8XG4gICAgICBjaGFydD8ud2lkdGggfHxcbiAgICAgIGdsb2JhbE9wdGlvbnM/LmV4cG9ydGluZz8uc291cmNlV2lkdGggfHxcbiAgICAgIGdsb2JhbE9wdGlvbnM/LmNoYXJ0Py53aWR0aCB8fFxuICAgICAgb3B0aW9ucy5leHBvcnQ/LmRlZmF1bHRXaWR0aCB8fFxuICAgICAgNjAwLFxuICAgIHNjYWxlXG4gIH07XG5cbiAgLy8gR2V0IHJpZCBvZiBwb3RlbnRpYWwgcHggYW5kICVcbiAgZm9yIChsZXQgW3BhcmFtLCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoc2l6ZSkpIHtcbiAgICBzaXplW3BhcmFtXSA9XG4gICAgICB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnID8gK3ZhbHVlLnJlcGxhY2UoL3B4fCUvZ2ksICcnKSA6IHZhbHVlO1xuICB9XG4gIHJldHVybiBzaXplO1xufTtcblxuLyoqXG4gKiBGdW5jdGlvbiBmb3IgZmluYWxpemluZyBvcHRpb25zIGJlZm9yZSBleHBvcnQuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgLSBUaGUgb3B0aW9ucyBvYmplY3QgY29udGFpbmluZyBjb25maWd1cmF0aW9uIGZvclxuICogdGhlIGV4cG9ydCBwcm9jZXNzLlxuICogQHBhcmFtIHtPYmplY3R9IGNoYXJ0SnNvbiAtIFRoZSBKU09OIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBjaGFydC5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGVuZENhbGxiYWNrIC0gVGhlIGNhbGxiYWNrIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZCB1cG9uXG4gKiBjb21wbGV0aW9uIG9yIGVycm9yLlxuICogQHBhcmFtIHtzdHJpbmd9IHN2ZyAtIFRoZSBTVkcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGNoYXJ0LlxuICpcbiAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSBBIFByb21pc2UgdGhhdCByZXNvbHZlcyBvbmNlIHRoZSBleHBvcnQgcHJvY2Vzc1xuICogaXMgY29tcGxldGVkLlxuICovXG5jb25zdCBkb0V4cG9ydCA9IGFzeW5jIChvcHRpb25zLCBjaGFydEpzb24sIGVuZENhbGxiYWNrLCBzdmcpID0+IHtcbiAgbGV0IHsgZXhwb3J0OiBleHBvcnRPcHRpb25zLCBjdXN0b21Mb2dpYzogY3VzdG9tTG9naWNPcHRpb25zIH0gPSBvcHRpb25zO1xuXG4gIGNvbnN0IGFsbG93Q29kZUV4ZWN1dGlvblNjb3BlZCA9XG4gICAgdHlwZW9mIGN1c3RvbUxvZ2ljT3B0aW9ucy5hbGxvd0NvZGVFeGVjdXRpb24gPT09ICdib29sZWFuJ1xuICAgICAgPyBjdXN0b21Mb2dpY09wdGlvbnMuYWxsb3dDb2RlRXhlY3V0aW9uXG4gICAgICA6IGFsbG93Q29kZUV4ZWN1dGlvbjtcblxuICBpZiAoIWN1c3RvbUxvZ2ljT3B0aW9ucykge1xuICAgIGN1c3RvbUxvZ2ljT3B0aW9ucyA9IG9wdGlvbnMuY3VzdG9tTG9naWMgPSB7fTtcbiAgfSBlbHNlIGlmIChhbGxvd0NvZGVFeGVjdXRpb25TY29wZWQpIHtcbiAgICBpZiAodHlwZW9mIG9wdGlvbnMuY3VzdG9tTG9naWMucmVzb3VyY2VzID09PSAnc3RyaW5nJykge1xuICAgICAgLy8gUHJvY2VzcyByZXNvdXJjZXNcbiAgICAgIG9wdGlvbnMuY3VzdG9tTG9naWMucmVzb3VyY2VzID0gaGFuZGxlUmVzb3VyY2VzKFxuICAgICAgICBvcHRpb25zLmN1c3RvbUxvZ2ljLnJlc291cmNlcyxcbiAgICAgICAgdG9Cb29sZWFuKG9wdGlvbnMuY3VzdG9tTG9naWMuYWxsb3dGaWxlUmVzb3VyY2VzKVxuICAgICAgKTtcbiAgICB9IGVsc2UgaWYgKCFvcHRpb25zLmN1c3RvbUxvZ2ljLnJlc291cmNlcykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVzb3VyY2VzID0gcmVhZEZpbGVTeW5jKCdyZXNvdXJjZXMuanNvbicsICd1dGY4Jyk7XG4gICAgICAgIG9wdGlvbnMuY3VzdG9tTG9naWMucmVzb3VyY2VzID0gaGFuZGxlUmVzb3VyY2VzKFxuICAgICAgICAgIHJlc291cmNlcyxcbiAgICAgICAgICB0b0Jvb2xlYW4ob3B0aW9ucy5jdXN0b21Mb2dpYy5hbGxvd0ZpbGVSZXNvdXJjZXMpXG4gICAgICAgICk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBsb2coMiwgYFtjaGFydF0gVW5hYmxlIHRvIGxvYWQgdGhlIGRlZmF1bHQgcmVzb3VyY2VzLmpzb24gZmlsZS5gKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBJZiB0aGUgYWxsb3dDb2RlRXhlY3V0aW9uIGZsYWcgaXNuJ3Qgc2V0LCB3ZSBzaG91bGQgcmVmdXNlIHRoZSB1c2FnZVxuICAvLyBvZiBjYWxsYmFjaywgcmVzb3VyY2VzLCBhbmQgY3VzdG9tIGNvZGUuIEFkZGl0aW9uYWxseSwgdGhlIHdvcmtlciB3aWxsXG4gIC8vIHJlZnVzZSB0byBydW4gYXJiaXRyYXJ5IEphdmFTY3JpcHQuIFByaW9yaXRpemVkIHNob3VsZCBiZSB0aGUgc2NvcGVkXG4gIC8vIG9wdGlvbiwgdGhlbiB3ZSBzaG91bGQgdGFrZSBhIGxvb2sgYXQgdGhlIG92ZXJhbGwgcG9vbCBvcHRpb24uXG4gIGlmICghYWxsb3dDb2RlRXhlY3V0aW9uU2NvcGVkICYmIGN1c3RvbUxvZ2ljT3B0aW9ucykge1xuICAgIGlmIChcbiAgICAgIGN1c3RvbUxvZ2ljT3B0aW9ucy5jYWxsYmFjayB8fFxuICAgICAgY3VzdG9tTG9naWNPcHRpb25zLnJlc291cmNlcyB8fFxuICAgICAgY3VzdG9tTG9naWNPcHRpb25zLmN1c3RvbUNvZGVcbiAgICApIHtcbiAgICAgIC8vIFNlbmQgYmFjayBhIGZyaWVuZGx5IG1lc3NhZ2Ugc2F5aW5nIHRoYXQgdGhlIGV4cG9ydGVyIGRvZXMgbm90IHN1cHBvcnRcbiAgICAgIC8vIHRoZXNlIHNldHRpbmdzLlxuICAgICAgcmV0dXJuIGVuZENhbGxiYWNrKFxuICAgICAgICBuZXcgRXhwb3J0RXJyb3IoXG4gICAgICAgICAgYFtjaGFydF0gVGhlICdjYWxsYmFjaycsICdyZXNvdXJjZXMnIGFuZCAnY3VzdG9tQ29kZScgb3B0aW9ucyBoYXZlIGJlZW4gZGlzYWJsZWQgZm9yIHRoaXMgc2VydmVyLmBcbiAgICAgICAgKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBSZXNldCBhbGwgYWRkaXRpb25hbCBjdXN0b20gY29kZVxuICAgIGN1c3RvbUxvZ2ljT3B0aW9ucy5jYWxsYmFjayA9IGZhbHNlO1xuICAgIGN1c3RvbUxvZ2ljT3B0aW9ucy5yZXNvdXJjZXMgPSBmYWxzZTtcbiAgICBjdXN0b21Mb2dpY09wdGlvbnMuY3VzdG9tQ29kZSA9IGZhbHNlO1xuICB9XG5cbiAgLy8gQ2xlYW4gcHJvcGVydGllcyB0byBrZWVwIGl0IGxlYW4gYW5kIG1lYW5cbiAgaWYgKGNoYXJ0SnNvbikge1xuICAgIGNoYXJ0SnNvbi5jaGFydCA9IGNoYXJ0SnNvbi5jaGFydCB8fCB7fTtcbiAgICBjaGFydEpzb24uZXhwb3J0aW5nID0gY2hhcnRKc29uLmV4cG9ydGluZyB8fCB7fTtcbiAgICBjaGFydEpzb24uZXhwb3J0aW5nLmVuYWJsZWQgPSBmYWxzZTtcbiAgfVxuXG4gIGV4cG9ydE9wdGlvbnMuY29uc3RyID0gZXhwb3J0T3B0aW9ucy5jb25zdHIgfHwgJ2NoYXJ0JztcbiAgZXhwb3J0T3B0aW9ucy50eXBlID0gZml4VHlwZShleHBvcnRPcHRpb25zLnR5cGUsIGV4cG9ydE9wdGlvbnMub3V0ZmlsZSk7XG4gIGlmIChleHBvcnRPcHRpb25zLnR5cGUgPT09ICdzdmcnKSB7XG4gICAgZXhwb3J0T3B0aW9ucy53aWR0aCA9IGZhbHNlO1xuICB9XG5cbiAgLy8gUHJlcGFyZSBnbG9iYWwgYW5kIHRoZW1lIG9wdGlvbnNcbiAgWydnbG9iYWxPcHRpb25zJywgJ3RoZW1lT3B0aW9ucyddLmZvckVhY2goKG9wdGlvbnNOYW1lKSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGlmIChleHBvcnRPcHRpb25zICYmIGV4cG9ydE9wdGlvbnNbb3B0aW9uc05hbWVdKSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICB0eXBlb2YgZXhwb3J0T3B0aW9uc1tvcHRpb25zTmFtZV0gPT09ICdzdHJpbmcnICYmXG4gICAgICAgICAgZXhwb3J0T3B0aW9uc1tvcHRpb25zTmFtZV0uZW5kc1dpdGgoJy5qc29uJylcbiAgICAgICAgKSB7XG4gICAgICAgICAgZXhwb3J0T3B0aW9uc1tvcHRpb25zTmFtZV0gPSBpc0NvcnJlY3RKU09OKFxuICAgICAgICAgICAgcmVhZEZpbGVTeW5jKGV4cG9ydE9wdGlvbnNbb3B0aW9uc05hbWVdLCAndXRmOCcpLFxuICAgICAgICAgICAgdHJ1ZVxuICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZXhwb3J0T3B0aW9uc1tvcHRpb25zTmFtZV0gPSBpc0NvcnJlY3RKU09OKFxuICAgICAgICAgICAgZXhwb3J0T3B0aW9uc1tvcHRpb25zTmFtZV0sXG4gICAgICAgICAgICB0cnVlXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBleHBvcnRPcHRpb25zW29wdGlvbnNOYW1lXSA9IHt9O1xuICAgICAgbG9nV2l0aFN0YWNrKDIsIGVycm9yLCBgW2NoYXJ0XSBUaGUgJyR7b3B0aW9uc05hbWV9JyBjYW5ub3QgYmUgbG9hZGVkLmApO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gUHJlcGFyZSB0aGUgY3VzdG9tQ29kZVxuICBpZiAoY3VzdG9tTG9naWNPcHRpb25zLmFsbG93Q29kZUV4ZWN1dGlvbikge1xuICAgIHRyeSB7XG4gICAgICBjdXN0b21Mb2dpY09wdGlvbnMuY3VzdG9tQ29kZSA9IHdyYXBBcm91bmQoXG4gICAgICAgIGN1c3RvbUxvZ2ljT3B0aW9ucy5jdXN0b21Db2RlLFxuICAgICAgICBjdXN0b21Mb2dpY09wdGlvbnMuYWxsb3dGaWxlUmVzb3VyY2VzXG4gICAgICApO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dXaXRoU3RhY2soMiwgZXJyb3IsIGBbY2hhcnRdIFRoZSAnY3VzdG9tQ29kZScgY2Fubm90IGJlIGxvYWRlZC5gKTtcbiAgICB9XG4gIH1cblxuICAvLyBHZXQgdGhlIGNhbGxiYWNrXG4gIGlmIChcbiAgICBjdXN0b21Mb2dpY09wdGlvbnMgJiZcbiAgICBjdXN0b21Mb2dpY09wdGlvbnMuY2FsbGJhY2sgJiZcbiAgICBjdXN0b21Mb2dpY09wdGlvbnMuY2FsbGJhY2s/LmluZGV4T2YoJ3snKSA8IDBcbiAgKSB7XG4gICAgLy8gVGhlIGFsbG93RmlsZVJlc291cmNlcyBpcyBhbHdheXMgc2V0IHRvIGZhbHNlIGZvciBIVFRQIHJlcXVlc3RzIHRvIGF2b2lkXG4gICAgLy8gaW5qZWN0aW5nIGFyYml0cmFyeSBmaWxlcyBmcm9tIHRoZSBmc1xuICAgIGlmIChjdXN0b21Mb2dpY09wdGlvbnMuYWxsb3dGaWxlUmVzb3VyY2VzKSB7XG4gICAgICB0cnkge1xuICAgICAgICBjdXN0b21Mb2dpY09wdGlvbnMuY2FsbGJhY2sgPSByZWFkRmlsZVN5bmMoXG4gICAgICAgICAgY3VzdG9tTG9naWNPcHRpb25zLmNhbGxiYWNrLFxuICAgICAgICAgICd1dGY4J1xuICAgICAgICApO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgY3VzdG9tTG9naWNPcHRpb25zLmNhbGxiYWNrID0gZmFsc2U7XG4gICAgICAgIGxvZ1dpdGhTdGFjaygyLCBlcnJvciwgYFtjaGFydF0gVGhlICdjYWxsYmFjaycgY2Fubm90IGJlIGxvYWRlZC5gKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgY3VzdG9tTG9naWNPcHRpb25zLmNhbGxiYWNrID0gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgLy8gU2l6ZSBzZWFyY2hcbiAgb3B0aW9ucy5leHBvcnQgPSB7XG4gICAgLi4ub3B0aW9ucy5leHBvcnQsXG4gICAgLi4uZmluZENoYXJ0U2l6ZShvcHRpb25zKVxuICB9O1xuXG4gIC8vIFBvc3QgdGhlIHdvcmsgdG8gdGhlIHBvb2xcbiAgdHJ5IHtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBwb3N0V29yayhcbiAgICAgIGV4cG9ydE9wdGlvbnMuc3RySW5qIHx8IGNoYXJ0SnNvbiB8fCBzdmcsXG4gICAgICBvcHRpb25zXG4gICAgKTtcbiAgICByZXR1cm4gZW5kQ2FsbGJhY2soZmFsc2UsIHJlc3VsdCk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgcmV0dXJuIGVuZENhbGxiYWNrKGVycm9yKTtcbiAgfVxufTtcblxuLyoqXG4gKiBQZXJmb3JtcyBhIGRpcmVjdCBpbmplY3Qgb2Ygb3B0aW9ucyBiZWZvcmUgZXhwb3J0LiBUaGUgZnVuY3Rpb24gYXR0ZW1wdHNcbiAqIHRvIHN0cmluZ2lmeSB0aGUgcHJvdmlkZWQgb3B0aW9ucyBhbmQgcmVtb3ZlcyB1bm5lY2Vzc2FyeSBjaGFyYWN0ZXJzLFxuICogZW5zdXJpbmcgYSBjbGVhbiBhbmQgZm9ybWF0dGVkIGlucHV0LiBUaGUgcmVzdWx0aW5nIHN0cmluZyBpcyBzYXZlZCBhc1xuICogYSBcInN0cmlnaHQgaW5qZWN0XCIgc3RyaW5nIGluIHRoZSBleHBvcnQgb3B0aW9ucy4gSXQgdGhlbiBpbnZva2VzIHRoZVxuICogZG9FeHBvcnQgZnVuY3Rpb24gd2l0aCB0aGUgdXBkYXRlZCBvcHRpb25zLlxuICpcbiAqIElNUE9SVEFOVDogRGFuZ2Vyb3VzIGFuZCBtdXN0IGJlIHVzZWQgZGVsaWJlcmF0ZWx5IGJ5IHNvbWVvbmUgd2hvIHNldHMgdXBcbiAqIGEgc2VydmVyIChzZWUgdGhlICAtLWFsbG93Q29kZUV4ZWN1dGlvbiBvcHRpb24pLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gVGhlIGV4cG9ydCBvcHRpb25zIGNvbnRhaW5pbmcgdGhlIGlucHV0XG4gKiB0byBiZSBpbmplY3RlZC5cbiAqIEBwYXJhbSB7ZnVuY3Rpb259IGVuZENhbGxiYWNrIC0gVGhlIGNhbGxiYWNrIGZ1bmN0aW9uIHRvIGJlIGludm9rZWRcbiAqIGF0IHRoZSBlbmQgb2YgdGhlIHByb2Nlc3MuXG4gKlxuICogQHJldHVybnMge1Byb21pc2V9IEEgUHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGggdGhlIHJlc3VsdCBvZiB0aGUgZXhwb3J0XG4gKiBvcGVyYXRpb24gb3IgcmVqZWN0cyB3aXRoIGFuIGVycm9yIGlmIGFueSBpc3N1ZXMgb2NjdXIgZHVyaW5nIHRoZSBwcm9jZXNzLlxuICovXG5jb25zdCBkb1N0cmFpZ2h0SW5qZWN0ID0gKG9wdGlvbnMsIGVuZENhbGxiYWNrKSA9PiB7XG4gIHRyeSB7XG4gICAgbGV0IHN0ckluajtcbiAgICBsZXQgaW5zdHIgPSBvcHRpb25zLmV4cG9ydC5pbnN0ciB8fCBvcHRpb25zLmV4cG9ydC5vcHRpb25zO1xuXG4gICAgaWYgKHR5cGVvZiBpbnN0ciAhPT0gJ3N0cmluZycpIHtcbiAgICAgIC8vIFRyeSB0byBzdHJpbmdpZnkgb3B0aW9uc1xuICAgICAgc3RySW5qID0gaW5zdHIgPSBvcHRpb25zU3RyaW5naWZ5KFxuICAgICAgICBpbnN0cixcbiAgICAgICAgb3B0aW9ucy5jdXN0b21Mb2dpYz8uYWxsb3dDb2RlRXhlY3V0aW9uXG4gICAgICApO1xuICAgIH1cbiAgICBzdHJJbmogPSBpbnN0ci5yZXBsYWNlQWxsKC9cXHR8XFxufFxcci9nLCAnJykudHJpbSgpO1xuXG4gICAgLy8gR2V0IHJpZCBvZiB0aGUgO1xuICAgIGlmIChzdHJJbmpbc3RySW5qLmxlbmd0aCAtIDFdID09PSAnOycpIHtcbiAgICAgIHN0ckluaiA9IHN0ckluai5zdWJzdHJpbmcoMCwgc3RySW5qLmxlbmd0aCAtIDEpO1xuICAgIH1cblxuICAgIC8vIFNhdmUgYXMgc3RyaWdodCBpbmplY3Qgc3RyaW5nXG4gICAgb3B0aW9ucy5leHBvcnQuc3RySW5qID0gc3RySW5qO1xuICAgIHJldHVybiBkb0V4cG9ydChvcHRpb25zLCBmYWxzZSwgZW5kQ2FsbGJhY2spO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJldHVybiBlbmRDYWxsYmFjayhcbiAgICAgIG5ldyBFeHBvcnRFcnJvcihcbiAgICAgICAgYFtjaGFydF0gTWFsZm9ybWVkIGlucHV0IGRldGVjdGVkIGZvciAke29wdGlvbnMuZXhwb3J0Py5yZXF1ZXN0SWQgfHwgJz8nfS4gUGxlYXNlIG1ha2Ugc3VyZSB0aGF0IHlvdXIgSlNPTi9KYXZhU2NyaXB0IG9wdGlvbnMgYXJlIHNlbnQgdXNpbmcgdGhlIFwib3B0aW9uc1wiIGF0dHJpYnV0ZSwgYW5kIHRoYXQgaWYgeW91J3JlIHVzaW5nIFNWRywgaXQgaXMgdW5lc2NhcGVkLmBcbiAgICAgICkuc2V0RXJyb3IoZXJyb3IpXG4gICAgKTtcbiAgfVxufTtcblxuLyoqXG4gKiBFeHBvcnRzIGEgc3RyaW5nIGJhc2VkIG9uIHRoZSBwcm92aWRlZCBvcHRpb25zIGFuZCBpbnZva2VzIGFuIGVuZCBjYWxsYmFjay5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nVG9FeHBvcnQgLSBUaGUgc3RyaW5nIGNvbnRlbnQgdG8gYmUgZXhwb3J0ZWQuXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIEV4cG9ydCBvcHRpb25zLCBpbmNsdWRpbmcgY3VzdG9tTG9naWMgd2l0aFxuICogYWxsb3dDb2RlRXhlY3V0aW9uIGZsYWcuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBlbmRDYWxsYmFjayAtIENhbGxiYWNrIGZ1bmN0aW9uIHRvIGJlIGludm9rZWQgYXQgdGhlIGVuZFxuICogb2YgdGhlIGV4cG9ydCBwcm9jZXNzLlxuICpcbiAqIEByZXR1cm5zIHthbnl9IFJlc3VsdCBvZiB0aGUgZXhwb3J0IHByb2Nlc3Mgb3IgYW4gZXJyb3IgaWYgZW5jb3VudGVyZWQuXG4gKi9cbmNvbnN0IGV4cG9ydEFzU3RyaW5nID0gKHN0cmluZ1RvRXhwb3J0LCBvcHRpb25zLCBlbmRDYWxsYmFjaykgPT4ge1xuICBjb25zdCB7IGFsbG93Q29kZUV4ZWN1dGlvbiB9ID0gb3B0aW9ucy5jdXN0b21Mb2dpYztcblxuICAvLyBDaGVjayBpZiBpdCBpcyBTVkdcbiAgaWYgKFxuICAgIHN0cmluZ1RvRXhwb3J0LmluZGV4T2YoJzxzdmcnKSA+PSAwIHx8XG4gICAgc3RyaW5nVG9FeHBvcnQuaW5kZXhPZignPD94bWwnKSA+PSAwXG4gICkge1xuICAgIGxvZyg0LCAnW2NoYXJ0XSBQYXJzaW5nIGlucHV0IGFzIFNWRy4nKTtcbiAgICByZXR1cm4gZG9FeHBvcnQob3B0aW9ucywgZmFsc2UsIGVuZENhbGxiYWNrLCBzdHJpbmdUb0V4cG9ydCk7XG4gIH1cblxuICB0cnkge1xuICAgIC8vIFRyeSB0byBwYXJzZSB0byBKU09OIGFuZCBjYWxsIHRoZSBkb0V4cG9ydCBmdW5jdGlvblxuICAgIGNvbnN0IGNoYXJ0SlNPTiA9IEpTT04ucGFyc2Uoc3RyaW5nVG9FeHBvcnQucmVwbGFjZUFsbCgvXFx0fFxcbnxcXHIvZywgJyAnKSk7XG5cbiAgICAvLyBJZiBhIGNvcnJlY3QgSlNPTiwgZG8gdGhlIGV4cG9ydFxuICAgIHJldHVybiBkb0V4cG9ydChvcHRpb25zLCBjaGFydEpTT04sIGVuZENhbGxiYWNrKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAvLyBOb3QgYSB2YWxpZCBKU09OXG4gICAgaWYgKHRvQm9vbGVhbihhbGxvd0NvZGVFeGVjdXRpb24pKSB7XG4gICAgICByZXR1cm4gZG9TdHJhaWdodEluamVjdChvcHRpb25zLCBlbmRDYWxsYmFjayk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIERvIG5vdCBhbGxvdyBzdHJhaWdodCBpbmplY3Rpb24gd2l0aG91dCB0aGUgYWxsb3dDb2RlRXhlY3V0aW9uIGZsYWdcbiAgICAgIHJldHVybiBlbmRDYWxsYmFjayhcbiAgICAgICAgbmV3IEV4cG9ydEVycm9yKFxuICAgICAgICAgICdbY2hhcnRdIE9ubHkgSlNPTiBjb25maWd1cmF0aW9ucyBhbmQgU1ZHIGFyZSBhbGxvd2VkIGZvciB0aGlzIHNlcnZlci4gSWYgdGhpcyBpcyB5b3VyIHNlcnZlciwgSmF2YVNjcmlwdCBjdXN0b20gY29kZSBjYW4gYmUgZW5hYmxlZCBieSBzdGFydGluZyB0aGUgc2VydmVyIHdpdGggdGhlIC0tYWxsb3dDb2RlRXhlY3V0aW9uIGZsYWcuJ1xuICAgICAgICApLnNldEVycm9yKGVycm9yKVxuICAgICAgKTtcbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogUmV0cmlldmVzIGFuZCByZXR1cm5zIHRoZSBjdXJyZW50IHN0YXR1cyBvZiBjb2RlIGV4ZWN1dGlvbiBwZXJtaXNzaW9uLlxuICpcbiAqIEByZXR1cm5zIHthbnl9IFRoZSB2YWx1ZSBvZiBhbGxvd0NvZGVFeGVjdXRpb24uXG4gKi9cbmV4cG9ydCBjb25zdCBnZXRBbGxvd0NvZGVFeGVjdXRpb24gPSAoKSA9PiBhbGxvd0NvZGVFeGVjdXRpb247XG5cbi8qKlxuICogU2V0cyB0aGUgY29kZSBleGVjdXRpb24gcGVybWlzc2lvbiBiYXNlZCBvbiB0aGUgcHJvdmlkZWQgYm9vbGVhbiB2YWx1ZS5cbiAqXG4gKiBAcGFyYW0ge2FueX0gdmFsdWUgLSBUaGUgdmFsdWUgdG8gYmUgY29udmVydGVkIGFuZCBhc3NpZ25lZFxuICogdG8gYWxsb3dDb2RlRXhlY3V0aW9uLlxuICovXG5leHBvcnQgY29uc3Qgc2V0QWxsb3dDb2RlRXhlY3V0aW9uID0gKHZhbHVlKSA9PiB7XG4gIGFsbG93Q29kZUV4ZWN1dGlvbiA9IHRvQm9vbGVhbih2YWx1ZSk7XG59O1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIGJhdGNoRXhwb3J0LFxuICBzaW5nbGVFeHBvcnQsXG4gIGdldEFsbG93Q29kZUV4ZWN1dGlvbixcbiAgc2V0QWxsb3dDb2RlRXhlY3V0aW9uLFxuICBzdGFydEV4cG9ydCxcbiAgZmluZENoYXJ0U2l6ZVxufTtcbiIsIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG5cbkhpZ2hjaGFydHMgRXhwb3J0IFNlcnZlclxuXG5Db3B5cmlnaHQgKGMpIDIwMTYtMjAyNCwgSGlnaHNvZnRcblxuTGljZW5jZWQgdW5kZXIgdGhlIE1JVCBsaWNlbmNlLlxuXG5BZGRpdGlvbmFsbHkgYSB2YWxpZCBIaWdoY2hhcnRzIGxpY2Vuc2UgaXMgcmVxdWlyZWQgZm9yIHVzZS5cblxuU2VlIExJQ0VOU0UgZmlsZSBpbiByb290IGZvciBkZXRhaWxzLlxuXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG4vKipcbiAqIEBvdmVydmlldyBVc2VkIHRvIHNhbml0aXplIHRoZSBzdHJpbmdzIGNvbWluZyBmcm9tIHRoZSBleHBvcnRpbmcgbW9kdWxlXG4gKiB0byBwcmV2ZW50IFhTUyBhdHRhY2tzICh3aXRoIHRoZSBET01QdXJpZnkgbGlicmFyeSkuXG4gKiovXG5cbmltcG9ydCB7IEpTRE9NIH0gZnJvbSAnanNkb20nO1xuaW1wb3J0IERPTVB1cmlmeSBmcm9tICdkb21wdXJpZnknO1xuXG5pbXBvcnQgeyBlbnZzIH0gZnJvbSAnLi9lbnZzLmpzJztcbi8qKlxuICogU2FuaXRpemVzIGEgZ2l2ZW4gSFRNTCBzdHJpbmcgYnkgcmVtb3ZpbmcgPHNjcmlwdD4gdGFncy5cbiAqIFRoaXMgZnVuY3Rpb24gdXNlcyBhIHJlZ3VsYXIgZXhwcmVzc2lvbiB0byBmaW5kIGFuZCByZW1vdmUgYWxsXG4gKiBvY2N1cnJlbmNlcyBvZiA8c2NyaXB0Pi4uLjwvc2NyaXB0PiB0YWdzIGFuZCBhbnkgY29udGVudCB3aXRoaW4gdGhlbS5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gaW5wdXQgVGhlIEhUTUwgc3RyaW5nIHRvIGJlIHNhbml0aXplZC5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBzYW5pdGl6ZWQgSFRNTCBzdHJpbmcuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzYW5pdGl6ZShpbnB1dCkge1xuICBjb25zdCBmb3JiaWRkZW4gPSBbXTtcblxuICBpZiAoIWVudnMuT1RIRVJfQUxMT1dfWExJTkspIHtcbiAgICBmb3JiaWRkZW4ucHVzaCgneGxpbms6aHJlZicpO1xuICB9XG5cbiAgY29uc3Qgd2luZG93ID0gbmV3IEpTRE9NKCcnKS53aW5kb3c7XG4gIGNvbnN0IHB1cmlmeSA9IERPTVB1cmlmeSh3aW5kb3cpO1xuICByZXR1cm4gcHVyaWZ5LnNhbml0aXplKGlucHV0LCB7XG4gICAgQUREX1RBR1M6IFsnZm9yZWlnbk9iamVjdCddLFxuICAgIEZPUkJJRF9BVFRSOiBmb3JiaWRkZW5cbiAgfSk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IHNhbml0aXplO1xuIiwiLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcblxuSGlnaGNoYXJ0cyBFeHBvcnQgU2VydmVyXG5cbkNvcHlyaWdodCAoYykgMjAxNi0yMDI0LCBIaWdoc29mdFxuXG5MaWNlbmNlZCB1bmRlciB0aGUgTUlUIGxpY2VuY2UuXG5cbkFkZGl0aW9uYWxseSBhIHZhbGlkIEhpZ2hjaGFydHMgbGljZW5zZSBpcyByZXF1aXJlZCBmb3IgdXNlLlxuXG5TZWUgTElDRU5TRSBmaWxlIGluIHJvb3QgZm9yIGRldGFpbHMuXG5cbioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG5cbmltcG9ydCB7IGxvZyB9IGZyb20gJy4vbG9nZ2VyLmpzJztcblxuLy8gQXJyYXkgdGhhdCBjb250YWlucyBpZHMgb2YgYWxsIG9uZ29pbmcgaW50ZXJ2YWxzXG5jb25zdCBpbnRlcnZhbElkcyA9IFtdO1xuXG4vKipcbiAqIEFkZHMgaWQgb2YgYSBzZXRJbnRlcnZhbCB0byB0aGUgaW50ZXJ2YWxJZHMgYXJyYXkuXG4gKlxuICogQHBhcmFtIHtOb2RlSlMuVGltZW91dH0gaWQgLSBJZCBvZiBhbiBpbnRlcnZhbC5cbiAqL1xuZXhwb3J0IGNvbnN0IGFkZEludGVydmFsID0gKGlkKSA9PiB7XG4gIGludGVydmFsSWRzLnB1c2goaWQpO1xufTtcblxuLyoqXG4gKiBDbGVhcnMgYWxsIG9mIG9uZ29pbmcgaW50ZXJ2YWxzIGJ5IGlkcyBnYXRoZXJlZCBpbiB0aGUgaW50ZXJ2YWxJZHMgYXJyYXkuXG4gKi9cbmV4cG9ydCBjb25zdCBjbGVhckFsbEludGVydmFscyA9ICgpID0+IHtcbiAgbG9nKDQsIGBbc2VydmVyXSBDbGVhcmluZyBhbGwgcmVnaXN0ZXJlZCBpbnRlcnZhbHMuYCk7XG4gIGZvciAoY29uc3QgaWQgb2YgaW50ZXJ2YWxJZHMpIHtcbiAgICBjbGVhckludGVydmFsKGlkKTtcbiAgfVxufTtcblxuZXhwb3J0IGRlZmF1bHQge1xuICBhZGRJbnRlcnZhbCxcbiAgY2xlYXJBbGxJbnRlcnZhbHNcbn07XG4iLCJpbXBvcnQgeyBlbnZzIH0gZnJvbSAnLi4vZW52cy5qcyc7XG5pbXBvcnQgeyBsb2dXaXRoU3RhY2sgfSBmcm9tICcuLi9sb2dnZXIuanMnO1xuXG4vKipcbiAqIE1pZGRsZXdhcmUgZm9yIGxvZ2dpbmcgZXJyb3JzIHdpdGggc3RhY2sgdHJhY2UgYW5kIGhhbmRsaW5nIGVycm9yIHJlc3BvbnNlLlxuICpcbiAqIEBwYXJhbSB7RXJyb3J9IGVycm9yIC0gVGhlIGVycm9yIG9iamVjdC5cbiAqIEBwYXJhbSB7RXhwcmVzcy5SZXF1ZXN0fSByZXEgLSBUaGUgRXhwcmVzcyByZXF1ZXN0IG9iamVjdC5cbiAqIEBwYXJhbSB7RXhwcmVzcy5SZXNwb25zZX0gcmVzIC0gVGhlIEV4cHJlc3MgcmVzcG9uc2Ugb2JqZWN0LlxuICogQHBhcmFtIHtGdW5jdGlvbn0gbmV4dCAtIFRoZSBuZXh0IG1pZGRsZXdhcmUgZnVuY3Rpb24uXG4gKi9cbmNvbnN0IGxvZ0Vycm9yTWlkZGxld2FyZSA9IChlcnJvciwgcmVxLCByZXMsIG5leHQpID0+IHtcbiAgLy8gRGlzcGxheSB0aGUgZXJyb3Igd2l0aCBzdGFjayBpbiBhIGNvcnJlY3QgZm9ybWF0XG4gIGxvZ1dpdGhTdGFjaygxLCBlcnJvcik7XG5cbiAgLy8gRGVsZXRlIHRoZSBzdGFjayBmb3IgdGhlIGVudmlyb25tZW50IG90aGVyIHRoYW4gdGhlIGRldmVsb3BtZW50XG4gIGlmIChlbnZzLk9USEVSX05PREVfRU5WICE9PSAnZGV2ZWxvcG1lbnQnKSB7XG4gICAgZGVsZXRlIGVycm9yLnN0YWNrO1xuICB9XG5cbiAgLy8gQ2FsbCB0aGUgcmV0dXJuRXJyb3JNaWRkbGV3YXJlXG4gIG5leHQoZXJyb3IpO1xufTtcblxuLyoqXG4gKiBNaWRkbGV3YXJlIGZvciByZXR1cm5pbmcgZXJyb3IgcmVzcG9uc2UuXG4gKlxuICogQHBhcmFtIHtFcnJvcn0gZXJyb3IgLSBUaGUgZXJyb3Igb2JqZWN0LlxuICogQHBhcmFtIHtFeHByZXNzLlJlcXVlc3R9IHJlcSAtIFRoZSBFeHByZXNzIHJlcXVlc3Qgb2JqZWN0LlxuICogQHBhcmFtIHtFeHByZXNzLlJlc3BvbnNlfSByZXMgLSBUaGUgRXhwcmVzcyByZXNwb25zZSBvYmplY3QuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBuZXh0IC0gVGhlIG5leHQgbWlkZGxld2FyZSBmdW5jdGlvbi5cbiAqL1xuY29uc3QgcmV0dXJuRXJyb3JNaWRkbGV3YXJlID0gKGVycm9yLCByZXEsIHJlcywgbmV4dCkgPT4ge1xuICAvLyBHYXRoZXIgYWxsIHJlcXVpZWQgaW5mb3JtYXRpb24gZm9yIHRoZSByZXNwb25zZVxuICBjb25zdCB7IHN0YXR1c0NvZGU6IHN0Q29kZSwgc3RhdHVzLCBtZXNzYWdlLCBzdGFjayB9ID0gZXJyb3I7XG4gIGNvbnN0IHN0YXR1c0NvZGUgPSBzdENvZGUgfHwgc3RhdHVzIHx8IDQwMDtcblxuICAvLyBTZXQgYW5kIHJldHVybiByZXNwb25zZVxuICByZXMuc3RhdHVzKHN0YXR1c0NvZGUpLmpzb24oeyBzdGF0dXNDb2RlLCBtZXNzYWdlLCBzdGFjayB9KTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IChhcHApID0+IHtcbiAgLy8gQWRkIGxvZyBlcnJvciBtaWRkbGV3YXJlXG4gIGFwcC51c2UobG9nRXJyb3JNaWRkbGV3YXJlKTtcblxuICAvLyBBZGQgc2V0IHN0YXR1cyBhbmQgcmV0dXJuIGVycm9yIG1pZGRsZXdhcmVcbiAgYXBwLnVzZShyZXR1cm5FcnJvck1pZGRsZXdhcmUpO1xufTtcbiIsIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG5cbkhpZ2hjaGFydHMgRXhwb3J0IFNlcnZlclxuXG5Db3B5cmlnaHQgKGMpIDIwMTYtMjAyNCwgSGlnaHNvZnRcblxuTGljZW5jZWQgdW5kZXIgdGhlIE1JVCBsaWNlbmNlLlxuXG5BZGRpdGlvbmFsbHkgYSB2YWxpZCBIaWdoY2hhcnRzIGxpY2Vuc2UgaXMgcmVxdWlyZWQgZm9yIHVzZS5cblxuU2VlIExJQ0VOU0UgZmlsZSBpbiByb290IGZvciBkZXRhaWxzLlxuXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG5pbXBvcnQgcmF0ZUxpbWl0IGZyb20gJ2V4cHJlc3MtcmF0ZS1saW1pdCc7XG5cbmltcG9ydCB7IGxvZyB9IGZyb20gJy4uL2xvZ2dlci5qcyc7XG5cbi8qKlxuICogTWlkZGxld2FyZSBmb3IgZW5hYmxpbmcgcmF0ZSBsaW1pdGluZyBvbiB0aGUgc3BlY2lmaWVkIEV4cHJlc3MgYXBwLlxuICpcbiAqIEBwYXJhbSB7RXhwcmVzc30gYXBwIC0gVGhlIEV4cHJlc3MgYXBwIGluc3RhbmNlLlxuICogQHBhcmFtIHtPYmplY3R9IGxpbWl0Q29uZmlnIC0gQ29uZmlndXJhdGlvbiBvcHRpb25zIGZvciByYXRlIGxpbWl0aW5nLlxuICovXG5leHBvcnQgZGVmYXVsdCAoYXBwLCBsaW1pdENvbmZpZykgPT4ge1xuICBjb25zdCBtc2cgPVxuICAgICdUb28gbWFueSByZXF1ZXN0cywgeW91IGhhdmUgYmVlbiByYXRlIGxpbWl0ZWQuIFBsZWFzZSB0cnkgYWdhaW4gbGF0ZXIuJztcblxuICAvLyBPcHRpb25zIGZvciB0aGUgcmF0ZSBsaW1pdGVyXG4gIGNvbnN0IHJhdGVPcHRpb25zID0ge1xuICAgIG1heDogbGltaXRDb25maWcubWF4UmVxdWVzdHMgfHwgMzAsXG4gICAgd2luZG93OiBsaW1pdENvbmZpZy53aW5kb3cgfHwgMSxcbiAgICBkZWxheTogbGltaXRDb25maWcuZGVsYXkgfHwgMCxcbiAgICB0cnVzdFByb3h5OiBsaW1pdENvbmZpZy50cnVzdFByb3h5IHx8IGZhbHNlLFxuICAgIHNraXBLZXk6IGxpbWl0Q29uZmlnLnNraXBLZXkgfHwgZmFsc2UsXG4gICAgc2tpcFRva2VuOiBsaW1pdENvbmZpZy5za2lwVG9rZW4gfHwgZmFsc2VcbiAgfTtcblxuICAvLyBTZXQgaWYgYmVoaW5kIGEgcHJveHlcbiAgaWYgKHJhdGVPcHRpb25zLnRydXN0UHJveHkpIHtcbiAgICBhcHAuZW5hYmxlKCd0cnVzdCBwcm94eScpO1xuICB9XG5cbiAgLy8gQ3JlYXRlIGEgbGltaXRlclxuICBjb25zdCBsaW1pdGVyID0gcmF0ZUxpbWl0KHtcbiAgICB3aW5kb3dNczogcmF0ZU9wdGlvbnMud2luZG93ICogNjAgKiAxMDAwLFxuICAgIC8vIExpbWl0IGVhY2ggSVAgdG8gMTAwIHJlcXVlc3RzIHBlciB3aW5kb3dNc1xuICAgIG1heDogcmF0ZU9wdGlvbnMubWF4LFxuICAgIC8vIERpc2FibGUgZGVsYXlpbmcsIGZ1bGwgc3BlZWQgdW50aWwgdGhlIG1heCBsaW1pdCBpcyByZWFjaGVkXG4gICAgZGVsYXlNczogcmF0ZU9wdGlvbnMuZGVsYXksXG4gICAgaGFuZGxlcjogKHJlcXVlc3QsIHJlc3BvbnNlKSA9PiB7XG4gICAgICByZXNwb25zZS5mb3JtYXQoe1xuICAgICAgICBqc29uOiAoKSA9PiB7XG4gICAgICAgICAgcmVzcG9uc2Uuc3RhdHVzKDQyOSkuc2VuZCh7IG1lc3NhZ2U6IG1zZyB9KTtcbiAgICAgICAgfSxcbiAgICAgICAgZGVmYXVsdDogKCkgPT4ge1xuICAgICAgICAgIHJlc3BvbnNlLnN0YXR1cyg0MjkpLnNlbmQobXNnKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSxcbiAgICBza2lwOiAocmVxdWVzdCkgPT4ge1xuICAgICAgLy8gQWxsb3cgYnlwYXNzaW5nIHRoZSBsaW1pdGVyIGlmIGEgdmFsaWQga2V5L3Rva2VuIGhhcyBiZWVuIHNlbnRcbiAgICAgIGlmIChcbiAgICAgICAgcmF0ZU9wdGlvbnMuc2tpcEtleSAhPT0gZmFsc2UgJiZcbiAgICAgICAgcmF0ZU9wdGlvbnMuc2tpcFRva2VuICE9PSBmYWxzZSAmJlxuICAgICAgICByZXF1ZXN0LnF1ZXJ5LmtleSA9PT0gcmF0ZU9wdGlvbnMuc2tpcEtleSAmJlxuICAgICAgICByZXF1ZXN0LnF1ZXJ5LmFjY2Vzc190b2tlbiA9PT0gcmF0ZU9wdGlvbnMuc2tpcFRva2VuXG4gICAgICApIHtcbiAgICAgICAgbG9nKDQsICdbcmF0ZSBsaW1pdGluZ10gU2tpcHBpbmcgcmF0ZSBsaW1pdGVyLicpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIFVzZSBhIGxpbWl0ZXIgYXMgYSBtaWRkbGV3YXJlXG4gIGFwcC51c2UobGltaXRlcik7XG5cbiAgbG9nKFxuICAgIDMsXG4gICAgYFtyYXRlIGxpbWl0aW5nXSBFbmFibGVkIHJhdGUgbGltaXRpbmcgd2l0aCAke3JhdGVPcHRpb25zLm1heH0gcmVxdWVzdHMgcGVyICR7cmF0ZU9wdGlvbnMud2luZG93fSBtaW51dGUgZm9yIGVhY2ggSVAsIHRydXN0aW5nIHByb3h5OiAke3JhdGVPcHRpb25zLnRydXN0UHJveHl9LmBcbiAgKTtcbn07XG4iLCJpbXBvcnQgRXhwb3J0RXJyb3IgZnJvbSAnLi9FeHBvcnRFcnJvci5qcyc7XG5cbmNsYXNzIEh0dHBFcnJvciBleHRlbmRzIEV4cG9ydEVycm9yIHtcbiAgY29uc3RydWN0b3IobWVzc2FnZSwgc3RhdHVzKSB7XG4gICAgc3VwZXIobWVzc2FnZSk7XG4gICAgdGhpcy5zdGF0dXMgPSB0aGlzLnN0YXR1c0NvZGUgPSBzdGF0dXM7XG4gIH1cblxuICBzZXRTdGF0dXMoc3RhdHVzKSB7XG4gICAgdGhpcy5zdGF0dXMgPSBzdGF0dXM7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgSHR0cEVycm9yO1xuIiwiLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcblxuSGlnaGNoYXJ0cyBFeHBvcnQgU2VydmVyXG5cbkNvcHlyaWdodCAoYykgMjAxNi0yMDI0LCBIaWdoc29mdFxuXG5MaWNlbmNlZCB1bmRlciB0aGUgTUlUIGxpY2VuY2UuXG5cbkFkZGl0aW9uYWxseSBhIHZhbGlkIEhpZ2hjaGFydHMgbGljZW5zZSBpcyByZXF1aXJlZCBmb3IgdXNlLlxuXG5TZWUgTElDRU5TRSBmaWxlIGluIHJvb3QgZm9yIGRldGFpbHMuXG5cbioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG5cbmltcG9ydCB7IHVwZGF0ZVZlcnNpb24sIHZlcnNpb24gfSBmcm9tICcuLi8uLi9jYWNoZS5qcyc7XG5pbXBvcnQgeyBlbnZzIH0gZnJvbSAnLi4vLi4vZW52cy5qcyc7XG5cbmltcG9ydCBIdHRwRXJyb3IgZnJvbSAnLi4vLi4vZXJyb3JzL0h0dHBFcnJvci5qcyc7XG5cbi8qKlxuICogQWRkcyB0aGUgUE9TVCAvY2hhbmdlX2hjX3ZlcnNpb24vOm5ld1ZlcnNpb24gcm91dGUgdGhhdCBjYW4gYmUgdXRpbGl6ZWQgdG8gbW9kaWZ5XG4gKiB0aGUgSGlnaGNoYXJ0cyB2ZXJzaW9uIG9uIHRoZSBzZXJ2ZXIuXG4gKlxuICogVE9ETzogQWRkIGF1dGggdG9rZW4gYW5kIGNvbm5lY3QgdG8gQVBJXG4gKi9cbmV4cG9ydCBkZWZhdWx0IChhcHApID0+XG4gICFhcHBcbiAgICA/IGZhbHNlXG4gICAgOiBhcHAucG9zdChcbiAgICAgICAgJy92ZXJzaW9uL2NoYW5nZS86bmV3VmVyc2lvbicsXG4gICAgICAgIGFzeW5jIChyZXF1ZXN0LCByZXNwb25zZSwgbmV4dCkgPT4ge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBhZG1pblRva2VuID0gZW52cy5ISUdIQ0hBUlRTX0FETUlOX1RPS0VOO1xuXG4gICAgICAgICAgICAvLyBDaGVjayB0aGUgZXhpc3RlbmNlIG9mIHRoZSB0b2tlblxuICAgICAgICAgICAgaWYgKCFhZG1pblRva2VuIHx8ICFhZG1pblRva2VuLmxlbmd0aCkge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgSHR0cEVycm9yKFxuICAgICAgICAgICAgICAgICdUaGUgc2VydmVyIGlzIG5vdCBjb25maWd1cmVkIHRvIHBlcmZvcm0gcnVuLXRpbWUgdmVyc2lvbiBjaGFuZ2VzOiBISUdIQ0hBUlRTX0FETUlOX1RPS0VOIGlzIG5vdCBzZXQuJyxcbiAgICAgICAgICAgICAgICA0MDFcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIGhjLWF1dGggaGVhZGVyIGNvbnRhaW4gYSBjb3JyZWN0IHRva2VuXG4gICAgICAgICAgICBjb25zdCB0b2tlbiA9IHJlcXVlc3QuZ2V0KCdoYy1hdXRoJyk7XG4gICAgICAgICAgICBpZiAoIXRva2VuIHx8IHRva2VuICE9PSBhZG1pblRva2VuKSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBIdHRwRXJyb3IoXG4gICAgICAgICAgICAgICAgJ0ludmFsaWQgb3IgbWlzc2luZyB0b2tlbjogU2V0IHRoZSB0b2tlbiBpbiB0aGUgaGMtYXV0aCBoZWFkZXIuJyxcbiAgICAgICAgICAgICAgICA0MDFcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQ29tcGFyZSB2ZXJzaW9uc1xuICAgICAgICAgICAgY29uc3QgbmV3VmVyc2lvbiA9IHJlcXVlc3QucGFyYW1zLm5ld1ZlcnNpb247XG4gICAgICAgICAgICBpZiAobmV3VmVyc2lvbikge1xuICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tbmFtZWQtYXMtZGVmYXVsdC1tZW1iZXJcbiAgICAgICAgICAgICAgICBhd2FpdCB1cGRhdGVWZXJzaW9uKG5ld1ZlcnNpb24pO1xuICAgICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBIdHRwRXJyb3IoXG4gICAgICAgICAgICAgICAgICBgVmVyc2lvbiBjaGFuZ2U6ICR7ZXJyb3IubWVzc2FnZX1gLFxuICAgICAgICAgICAgICAgICAgZXJyb3Iuc3RhdHVzQ29kZVxuICAgICAgICAgICAgICAgICkuc2V0RXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgLy8gU3VjY2Vzc1xuICAgICAgICAgICAgICByZXNwb25zZS5zdGF0dXMoMjAwKS5zZW5kKHtcbiAgICAgICAgICAgICAgICBzdGF0dXNDb2RlOiAyMDAsXG4gICAgICAgICAgICAgICAgdmVyc2lvbjogdmVyc2lvbigpLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGBTdWNjZXNzZnVsbHkgdXBkYXRlZCBIaWdoY2hhcnRzIHRvIHZlcnNpb246ICR7bmV3VmVyc2lvbn0uYFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIC8vIE5vIHZlcnNpb24gc3BlY2lmaWVkXG4gICAgICAgICAgICAgIHRocm93IG5ldyBIdHRwRXJyb3IoJ05vIG5ldyB2ZXJzaW9uIHN1cHBsaWVkLicsIDQwMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIG5leHQoZXJyb3IpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiIsIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG5cbkhpZ2hjaGFydHMgRXhwb3J0IFNlcnZlclxuXG5Db3B5cmlnaHQgKGMpIDIwMTYtMjAyNCwgSGlnaHNvZnRcblxuTGljZW5jZWQgdW5kZXIgdGhlIE1JVCBsaWNlbmNlLlxuXG5BZGRpdGlvbmFsbHkgYSB2YWxpZCBIaWdoY2hhcnRzIGxpY2Vuc2UgaXMgcmVxdWlyZWQgZm9yIHVzZS5cblxuU2VlIExJQ0VOU0UgZmlsZSBpbiByb290IGZvciBkZXRhaWxzLlxuXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG5pbXBvcnQgeyB2NCBhcyB1dWlkIH0gZnJvbSAndXVpZCc7XG5cbmltcG9ydCB7IGdldEFsbG93Q29kZUV4ZWN1dGlvbiwgc3RhcnRFeHBvcnQgfSBmcm9tICcuLi8uLi9jaGFydC5qcyc7XG5pbXBvcnQgeyBnZXRPcHRpb25zLCBtZXJnZUNvbmZpZ09wdGlvbnMgfSBmcm9tICcuLi8uLi9jb25maWcuanMnO1xuaW1wb3J0IHsgbG9nIH0gZnJvbSAnLi4vLi4vbG9nZ2VyLmpzJztcbmltcG9ydCB7XG4gIGZpeFR5cGUsXG4gIGlzQ29ycmVjdEpTT04sXG4gIGlzT2JqZWN0RW1wdHksXG4gIGlzUHJpdmF0ZVJhbmdlVXJsRm91bmQsXG4gIG9wdGlvbnNTdHJpbmdpZnksXG4gIG1lYXN1cmVUaW1lXG59IGZyb20gJy4uLy4uL3V0aWxzLmpzJztcblxuaW1wb3J0IEh0dHBFcnJvciBmcm9tICcuLi8uLi9lcnJvcnMvSHR0cEVycm9yLmpzJztcblxuLy8gUmV2ZXJzZWQgTUlNRSB0eXBlc1xuY29uc3QgcmV2ZXJzZWRNaW1lID0ge1xuICBwbmc6ICdpbWFnZS9wbmcnLFxuICBqcGVnOiAnaW1hZ2UvanBlZycsXG4gIGdpZjogJ2ltYWdlL2dpZicsXG4gIHBkZjogJ2FwcGxpY2F0aW9uL3BkZicsXG4gIHN2ZzogJ2ltYWdlL3N2Zyt4bWwnXG59O1xuXG4vLyBUaGUgcmVxdWVzdHMgY291bnRlclxubGV0IHJlcXVlc3RzQ291bnRlciA9IDA7XG5cbi8vIFRoZSBhcnJheSBvZiBjYWxsYmFja3MgdG8gY2FsbCBiZWZvcmUgYSByZXF1ZXN0XG5jb25zdCBiZWZvcmVSZXF1ZXN0ID0gW107XG5cbi8vIFRoZSBhcnJheSBvZiBjYWxsYmFja3MgdG8gY2FsbCBhZnRlciBhIHJlcXVlc3RcbmNvbnN0IGFmdGVyUmVxdWVzdCA9IFtdO1xuXG4vKipcbiAqIEludm9rZXMgYW4gYXJyYXkgb2YgY2FsbGJhY2sgZnVuY3Rpb25zIHdpdGggc3BlY2lmaWVkIHBhcmFtZXRlcnMsIGFsbG93aW5nXG4gKiBjdXN0b21pemF0aW9uIG9mIHJlcXVlc3QgaGFuZGxpbmcuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbltdfSBjYWxsYmFja3MgLSBBbiBhcnJheSBvZiBjYWxsYmFjayBmdW5jdGlvbnNcbiAqIHRvIGJlIGV4ZWN1dGVkLlxuICogQHBhcmFtIHtFeHByZXNzLlJlcXVlc3R9IHJlcXVlc3QgLSBUaGUgRXhwcmVzcyByZXF1ZXN0IG9iamVjdC5cbiAqIEBwYXJhbSB7RXhwcmVzcy5SZXNwb25zZX0gcmVzcG9uc2UgLSBUaGUgRXhwcmVzcyByZXNwb25zZSBvYmplY3QuXG4gKiBAcGFyYW0ge09iamVjdH0gZGF0YSAtIEFuIG9iamVjdCBjb250YWluaW5nIHBhcmFtZXRlcnMgbGlrZSBpZCwgdW5pcXVlSWQsXG4gKiB0eXBlLCBhbmQgYm9keS5cbiAqXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBSZXR1cm5zIGEgYm9vbGVhbiBpbmRpY2F0aW5nIHRoZSBvdmVyYWxsIHJlc3VsdFxuICogb2YgdGhlIGNhbGxiYWNrIGludm9jYXRpb25zLlxuICovXG5jb25zdCBkb0NhbGxiYWNrcyA9IChjYWxsYmFja3MsIHJlcXVlc3QsIHJlc3BvbnNlLCBkYXRhKSA9PiB7XG4gIGxldCByZXN1bHQgPSB0cnVlO1xuICBjb25zdCB7IGlkLCB1bmlxdWVJZCwgdHlwZSwgYm9keSB9ID0gZGF0YTtcblxuICBjYWxsYmFja3Muc29tZSgoY2FsbGJhY2spID0+IHtcbiAgICBpZiAoY2FsbGJhY2spIHtcbiAgICAgIGxldCBjYWxsUmVzcG9uc2UgPSBjYWxsYmFjayhyZXF1ZXN0LCByZXNwb25zZSwgaWQsIHVuaXF1ZUlkLCB0eXBlLCBib2R5KTtcblxuICAgICAgaWYgKGNhbGxSZXNwb25zZSAhPT0gdW5kZWZpbmVkICYmIGNhbGxSZXNwb25zZSAhPT0gdHJ1ZSkge1xuICAgICAgICByZXN1bHQgPSBjYWxsUmVzcG9uc2U7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cbi8qKlxuICogSGFuZGxlcyB0aGUgZXhwb3J0IHJlcXVlc3RzIGZyb20gdGhlIGNsaWVudC5cbiAqXG4gKiBAcGFyYW0ge0V4cHJlc3MuUmVxdWVzdH0gcmVxdWVzdCAtIFRoZSBFeHByZXNzIHJlcXVlc3Qgb2JqZWN0LlxuICogQHBhcmFtIHtFeHByZXNzLlJlc3BvbnNlfSByZXNwb25zZSAtIFRoZSBFeHByZXNzIHJlc3BvbnNlIG9iamVjdC5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IG5leHQgLSBUaGUgbmV4dCBtaWRkbGV3YXJlIGZ1bmN0aW9uLlxuICpcbiAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIG9uY2UgdGhlIGV4cG9ydCBwcm9jZXNzXG4gKiBpcyBjb21wbGV0ZS5cbiAqL1xuY29uc3QgZXhwb3J0SGFuZGxlciA9IGFzeW5jIChyZXF1ZXN0LCByZXNwb25zZSwgbmV4dCkgPT4ge1xuICB0cnkge1xuICAgIC8vIFN0YXJ0IGNvdW50aW5nIHRpbWVcbiAgICBjb25zdCBzdG9wQ291bnRlciA9IG1lYXN1cmVUaW1lKCk7XG5cbiAgICAvLyBDcmVhdGUgYSB1bmlxdWUgSUQgZm9yIGEgcmVxdWVzdFxuICAgIGNvbnN0IHVuaXF1ZUlkID0gdXVpZCgpLnJlcGxhY2UoLy0vZywgJycpO1xuXG4gICAgLy8gR2V0IHRoZSBjdXJyZW50IHNlcnZlcidzIGdlbmVyYWwgb3B0aW9uc1xuICAgIGNvbnN0IGRlZmF1bHRPcHRpb25zID0gZ2V0T3B0aW9ucygpO1xuXG4gICAgY29uc3QgYm9keSA9IHJlcXVlc3QuYm9keTtcbiAgICBjb25zdCBpZCA9ICsrcmVxdWVzdHNDb3VudGVyO1xuXG4gICAgbGV0IHR5cGUgPSBmaXhUeXBlKGJvZHkudHlwZSk7XG5cbiAgICAvLyBUaHJvdyAnQmFkIFJlcXVlc3QnIGlmIHRoZXJlJ3Mgbm8gYm9keVxuICAgIGlmICghYm9keSB8fCBpc09iamVjdEVtcHR5KGJvZHkpKSB7XG4gICAgICB0aHJvdyBuZXcgSHR0cEVycm9yKFxuICAgICAgICAnVGhlIHJlcXVlc3QgYm9keSBpcyByZXF1aXJlZC4gUGxlYXNlIGVuc3VyZSB0aGF0IHlvdXIgQ29udGVudC1UeXBlIGhlYWRlciBpcyBjb3JyZWN0IChhY2NlcHRlZCB0eXBlcyBhcmUgYXBwbGljYXRpb24vanNvbiBhbmQgbXVsdGlwYXJ0L2Zvcm0tZGF0YSkuJyxcbiAgICAgICAgNDAwXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIEFsbCBvZiB0aGUgYmVsb3cgY2FuIGJlIHVzZWRcbiAgICBsZXQgaW5zdHIgPSBpc0NvcnJlY3RKU09OKGJvZHkuaW5maWxlIHx8IGJvZHkub3B0aW9ucyB8fCBib2R5LmRhdGEpO1xuXG4gICAgLy8gVGhyb3cgJ0JhZCBSZXF1ZXN0JyBpZiB0aGVyZSdzIG5vIEpTT04gb3IgU1ZHIHRvIGV4cG9ydFxuICAgIGlmICghaW5zdHIgJiYgIWJvZHkuc3ZnKSB7XG4gICAgICBsb2coXG4gICAgICAgIDIsXG4gICAgICAgIGBUaGUgcmVxdWVzdCB3aXRoIElEICR7dW5pcXVlSWR9IGZyb20gJHtcbiAgICAgICAgICByZXF1ZXN0LmhlYWRlcnNbJ3gtZm9yd2FyZGVkLWZvciddIHx8IHJlcXVlc3QuY29ubmVjdGlvbi5yZW1vdGVBZGRyZXNzXG4gICAgICAgIH0gd2FzIGluY29ycmVjdDpcbiAgQ29udGVudC1UeXBlOiAke3JlcXVlc3QuaGVhZGVyc1snY29udGVudC10eXBlJ119LiBcbiAgQ2hhcnQgY29uc3RydWN0b3I6ICR7Ym9keS5jb25zdHJ9LlxuICBEaW1lbnNpb25zOiAke2JvZHkud2lkdGh9eCR7Ym9keS5oZWlnaHR9IEAgJHtib2R5LnNjYWxlfSBzY2FsZS5cbiAgVHlwZTogJHt0eXBlfS5cbiAgSXMgU1ZHIHNldD8gJHt0eXBlb2YgYm9keS5zdmcgIT09ICd1bmRlZmluZWQnfS5cbiAgQjY0PyAke3R5cGVvZiBib2R5LmI2NCAhPT0gJ3VuZGVmaW5lZCd9LlxuICBObyBkb3dubG9hZD8gJHt0eXBlb2YgYm9keS5ub0Rvd25sb2FkICE9PSAndW5kZWZpbmVkJ30uXG5cbiAgUGF5bG9hZCByZWNlaXZlZDogJHtKU09OLnN0cmluZ2lmeShib2R5LmluZmlsZSB8fCBib2R5Lm9wdGlvbnMgfHwgYm9keS5kYXRhIHx8IGJvZHkuc3ZnKX1cblxuICBgXG4gICAgICApO1xuXG4gICAgICB0aHJvdyBuZXcgSHR0cEVycm9yKFxuICAgICAgICBcIk5vIGNvcnJlY3QgY2hhcnQgZGF0YSBmb3VuZC4gRW5zdXJlIHRoYXQgeW91IGFyZSB1c2luZyBlaXRoZXIgYXBwbGljYXRpb24vanNvbiBvciBtdWx0aXBhcnQvZm9ybS1kYXRhIGhlYWRlcnMuIElmIHNlbmRpbmcgSlNPTiwgbWFrZSBzdXJlIHRoZSBjaGFydCBkYXRhIGlzIGluIHRoZSAnaW5maWxlJywgJ29wdGlvbnMnLCBvciAnZGF0YScgYXR0cmlidXRlLiBJZiBzZW5kaW5nIFNWRywgZW5zdXJlIGl0IGlzIGluIHRoZSAnc3ZnJyBhdHRyaWJ1dGUuXCIsXG4gICAgICAgIDQwMFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBsZXQgY2FsbFJlc3BvbnNlID0gZmFsc2U7XG5cbiAgICAvLyBDYWxsIHRoZSBiZWZvcmUgcmVxdWVzdCBmdW5jdGlvbnNcbiAgICBjYWxsUmVzcG9uc2UgPSBkb0NhbGxiYWNrcyhiZWZvcmVSZXF1ZXN0LCByZXF1ZXN0LCByZXNwb25zZSwge1xuICAgICAgaWQsXG4gICAgICB1bmlxdWVJZCxcbiAgICAgIHR5cGUsXG4gICAgICBib2R5XG4gICAgfSk7XG5cbiAgICAvLyBCbG9jayB0aGUgcmVxdWVzdCBpZiBvbmUgb2YgYSBjYWxsYmFja3MgZmFpbGVkXG4gICAgaWYgKGNhbGxSZXNwb25zZSAhPT0gdHJ1ZSkge1xuICAgICAgcmV0dXJuIHJlc3BvbnNlLnNlbmQoY2FsbFJlc3BvbnNlKTtcbiAgICB9XG5cbiAgICBsZXQgY29ubmVjdGlvbkFib3J0ZWQgPSBmYWxzZTtcblxuICAgIC8vIEluIGNhc2UgdGhlIGNvbm5lY3Rpb24gaXMgY2xvc2VkLCBmb3JjZSB0byBhYm9ydCBmdXJ0aGVyIGFjdGlvbnNcbiAgICByZXF1ZXN0LnNvY2tldC5vbignY2xvc2UnLCAoaGFkRXJyb3JzKSA9PiB7XG4gICAgICBpZiAoaGFkRXJyb3JzKSB7XG4gICAgICAgIGNvbm5lY3Rpb25BYm9ydGVkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGxvZyg0LCBgW2V4cG9ydF0gR290IGFuIGluY29taW5nIEhUVFAgcmVxdWVzdCB3aXRoIElEICR7dW5pcXVlSWR9LmApO1xuXG4gICAgYm9keS5jb25zdHIgPSAodHlwZW9mIGJvZHkuY29uc3RyID09PSAnc3RyaW5nJyAmJiBib2R5LmNvbnN0cikgfHwgJ2NoYXJ0JztcblxuICAgIC8vIEdhdGhlciBhbmQgb3JnYW5pemUgb3B0aW9ucyBmcm9tIHRoZSBwYXlsb2FkXG4gICAgY29uc3QgcmVxdWVzdE9wdGlvbnMgPSB7XG4gICAgICBleHBvcnQ6IHtcbiAgICAgICAgaW5zdHIsXG4gICAgICAgIHR5cGUsXG4gICAgICAgIGNvbnN0cjogYm9keS5jb25zdHJbMF0udG9Mb3dlckNhc2UoKSArIGJvZHkuY29uc3RyLnN1YnN0cigxKSxcbiAgICAgICAgaGVpZ2h0OiBib2R5LmhlaWdodCxcbiAgICAgICAgd2lkdGg6IGJvZHkud2lkdGgsXG4gICAgICAgIHNjYWxlOiBib2R5LnNjYWxlIHx8IGRlZmF1bHRPcHRpb25zLmV4cG9ydC5zY2FsZSxcbiAgICAgICAgZ2xvYmFsT3B0aW9uczogaXNDb3JyZWN0SlNPTihib2R5Lmdsb2JhbE9wdGlvbnMsIHRydWUpLFxuICAgICAgICB0aGVtZU9wdGlvbnM6IGlzQ29ycmVjdEpTT04oYm9keS50aGVtZU9wdGlvbnMsIHRydWUpXG4gICAgICB9LFxuICAgICAgY3VzdG9tTG9naWM6IHtcbiAgICAgICAgYWxsb3dDb2RlRXhlY3V0aW9uOiBnZXRBbGxvd0NvZGVFeGVjdXRpb24oKSxcbiAgICAgICAgYWxsb3dGaWxlUmVzb3VyY2VzOiBmYWxzZSxcbiAgICAgICAgcmVzb3VyY2VzOiBpc0NvcnJlY3RKU09OKGJvZHkucmVzb3VyY2VzLCB0cnVlKSxcbiAgICAgICAgY2FsbGJhY2s6IGJvZHkuY2FsbGJhY2ssXG4gICAgICAgIGN1c3RvbUNvZGU6IGJvZHkuY3VzdG9tQ29kZVxuICAgICAgfVxuICAgIH07XG5cbiAgICBpZiAoaW5zdHIpIHtcbiAgICAgIC8vIFN0cmluZ2lmeSBKU09OIHdpdGggb3B0aW9uc1xuICAgICAgcmVxdWVzdE9wdGlvbnMuZXhwb3J0Lmluc3RyID0gb3B0aW9uc1N0cmluZ2lmeShcbiAgICAgICAgaW5zdHIsXG4gICAgICAgIHJlcXVlc3RPcHRpb25zLmN1c3RvbUxvZ2ljLmFsbG93Q29kZUV4ZWN1dGlvblxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBNZXJnZSB0aGUgcmVxdWVzdCBvcHRpb25zIGludG8gZGVmYXVsdCBvbmVzXG4gICAgY29uc3Qgb3B0aW9ucyA9IG1lcmdlQ29uZmlnT3B0aW9ucyhkZWZhdWx0T3B0aW9ucywgcmVxdWVzdE9wdGlvbnMpO1xuXG4gICAgLy8gU2F2ZSB0aGUgSlNPTiBpZiBleGlzdHNcbiAgICBvcHRpb25zLmV4cG9ydC5vcHRpb25zID0gaW5zdHI7XG5cbiAgICAvLyBMYXN0bHksIGFkZCB0aGUgc2VydmVyIHNwZWNpZmljIGFyZ3VtZW50cyBpbnRvIG9wdGlvbnMgYXMgcGF5bG9hZFxuICAgIG9wdGlvbnMucGF5bG9hZCA9IHtcbiAgICAgIHN2ZzogYm9keS5zdmcgfHwgZmFsc2UsXG4gICAgICBiNjQ6IGJvZHkuYjY0IHx8IGZhbHNlLFxuICAgICAgbm9Eb3dubG9hZDogYm9keS5ub0Rvd25sb2FkIHx8IGZhbHNlLFxuICAgICAgcmVxdWVzdElkOiB1bmlxdWVJZFxuICAgIH07XG5cbiAgICAvLyBUZXN0IHhsaW5rOmhyZWYgZWxlbWVudHMgZnJvbSBwYXlsb2FkJ3MgU1ZHXG4gICAgaWYgKGJvZHkuc3ZnICYmIGlzUHJpdmF0ZVJhbmdlVXJsRm91bmQob3B0aW9ucy5wYXlsb2FkLnN2ZykpIHtcbiAgICAgIHRocm93IG5ldyBIdHRwRXJyb3IoXG4gICAgICAgICdTVkcgcG90ZW50aWFsbHkgY29udGFpbiBhdCBsZWFzdCBvbmUgZm9yYmlkZGVuIFVSTCBpbiB4bGluazpocmVmIGVsZW1lbnQuIFBsZWFzZSByZXZpZXcgdGhlIFNWRyBjb250ZW50IGFuZCBlbnN1cmUgdGhhdCBhbGwgcmVmZXJlbmNlZCBVUkxzIGNvbXBseSB3aXRoIHNlY3VyaXR5IHBvbGljaWVzLicsXG4gICAgICAgIDQwMFxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBTdGFydCB0aGUgZXhwb3J0IHByb2Nlc3NcbiAgICBhd2FpdCBzdGFydEV4cG9ydChvcHRpb25zLCAoZXJyb3IsIGluZm8pID0+IHtcbiAgICAgIC8vIFJlbW92ZSB0aGUgY2xvc2UgZXZlbnQgZnJvbSB0aGUgc29ja2V0XG4gICAgICByZXF1ZXN0LnNvY2tldC5yZW1vdmVBbGxMaXN0ZW5lcnMoJ2Nsb3NlJyk7XG5cbiAgICAgIC8vIEFmdGVyIHRoZSB3aG9sZSBleHBvcnRpbmcgcHJvY2Vzc1xuICAgICAgaWYgKGRlZmF1bHRPcHRpb25zLnNlcnZlci5iZW5jaG1hcmtpbmcpIHtcbiAgICAgICAgbG9nKFxuICAgICAgICAgIDUsXG4gICAgICAgICAgYFtiZW5jaG1hcmtdIFJlcXVlc3Qgd2l0aCBJRCAke3VuaXF1ZUlkfSAtIEFmdGVyIHRoZSB3aG9sZSBleHBvcnRpbmcgcHJvY2VzczogJHtzdG9wQ291bnRlcigpfW1zLmBcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgLy8gSWYgdGhlIGNvbm5lY3Rpb24gd2FzIGNsb3NlZCwgZG8gbm90aGluZ1xuICAgICAgaWYgKGNvbm5lY3Rpb25BYm9ydGVkKSB7XG4gICAgICAgIHJldHVybiBsb2coXG4gICAgICAgICAgMyxcbiAgICAgICAgICBgW2V4cG9ydF0gVGhlIGNsaWVudCBjbG9zZWQgdGhlIGNvbm5lY3Rpb24gYmVmb3JlIHRoZSBjaGFydCBmaW5pc2hlZCBwcm9jZXNzaW5nLmBcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgLy8gSWYgZXJyb3IsIGxvZyBpdCBhbmQgc2VuZCBpdCB0byB0aGUgZXJyb3IgbWlkZGxld2FyZVxuICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfVxuXG4gICAgICAvLyBJZiBkYXRhIGlzIG1pc3NpbmcsIGxvZyB0aGUgbWVzc2FnZSBhbmQgc2VuZCBpdCB0byB0aGUgZXJyb3IgbWlkZGxld2FyZVxuICAgICAgaWYgKCFpbmZvIHx8ICFpbmZvLnJlc3VsdCkge1xuICAgICAgICB0aHJvdyBuZXcgSHR0cEVycm9yKFxuICAgICAgICAgIGBVbmV4cGVjdGVkIHJldHVybiBmcm9tIGNoYXJ0IGdlbmVyYXRpb24uIFBsZWFzZSBjaGVjayB5b3VyIHJlcXVlc3QgZGF0YS4gRm9yIHRoZSByZXF1ZXN0IHdpdGggSUQgJHt1bmlxdWVJZH0sIHRoZSByZXN1bHQgaXMgJHtpbmZvLnJlc3VsdH0uYCxcbiAgICAgICAgICA0MDBcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgLy8gR2V0IHRoZSB0eXBlIGZyb20gb3B0aW9uc1xuICAgICAgdHlwZSA9IGluZm8ub3B0aW9ucy5leHBvcnQudHlwZTtcblxuICAgICAgLy8gVGhlIGFmdGVyIHJlcXVlc3QgY2FsbGJhY2tzXG4gICAgICBkb0NhbGxiYWNrcyhhZnRlclJlcXVlc3QsIHJlcXVlc3QsIHJlc3BvbnNlLCB7IGlkLCBib2R5OiBpbmZvLnJlc3VsdCB9KTtcblxuICAgICAgaWYgKGluZm8ucmVzdWx0KSB7XG4gICAgICAgIC8vIElmIG9ubHkgYmFzZTY0IGlzIHJlcXVpcmVkLCByZXR1cm4gaXRcbiAgICAgICAgaWYgKGJvZHkuYjY0KSB7XG4gICAgICAgICAgLy8gU1ZHIEV4Y2VwdGlvbiBmb3IgdGhlIEhpZ2hjaGFydHMgMTEuMy4wIHZlcnNpb25cbiAgICAgICAgICBpZiAodHlwZSA9PT0gJ3BkZicgfHwgdHlwZSA9PSAnc3ZnJykge1xuICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlLnNlbmQoXG4gICAgICAgICAgICAgIEJ1ZmZlci5mcm9tKGluZm8ucmVzdWx0LCAndXRmOCcpLnRvU3RyaW5nKCdiYXNlNjQnKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gcmVzcG9uc2Uuc2VuZChpbmZvLnJlc3VsdCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXQgY29ycmVjdCBjb250ZW50IHR5cGVcbiAgICAgICAgcmVzcG9uc2UuaGVhZGVyKCdDb250ZW50LVR5cGUnLCByZXZlcnNlZE1pbWVbdHlwZV0gfHwgJ2ltYWdlL3BuZycpO1xuXG4gICAgICAgIC8vIERlY2lkZSB3aGV0aGVyIHRvIGRvd25sb2FkIG9yIG5vdCBjaGFydCBmaWxlXG4gICAgICAgIGlmICghYm9keS5ub0Rvd25sb2FkKSB7XG4gICAgICAgICAgcmVzcG9uc2UuYXR0YWNobWVudChcbiAgICAgICAgICAgIGAke3JlcXVlc3QucGFyYW1zLmZpbGVuYW1lIHx8IHJlcXVlc3QuYm9keS5maWxlbmFtZSB8fCAnY2hhcnQnfS4ke1xuICAgICAgICAgICAgICB0eXBlIHx8ICdwbmcnXG4gICAgICAgICAgICB9YFxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBJZiBTVkcsIHJldHVybiBwbGFpbiBjb250ZW50XG4gICAgICAgIHJldHVybiB0eXBlID09PSAnc3ZnJ1xuICAgICAgICAgID8gcmVzcG9uc2Uuc2VuZChpbmZvLnJlc3VsdClcbiAgICAgICAgICA6IHJlc3BvbnNlLnNlbmQoQnVmZmVyLmZyb20oaW5mby5yZXN1bHQsICdiYXNlNjQnKSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgbmV4dChlcnJvcik7XG4gIH1cbn07XG5cbmV4cG9ydCBkZWZhdWx0IChhcHApID0+IHtcbiAgLyoqXG4gICAqIEFkZHMgdGhlIFBPU1QgLyBhIHJvdXRlIGZvciBoYW5kbGluZyBQT1NUIHJlcXVlc3RzIGF0IHRoZSByb290IGVuZHBvaW50LlxuICAgKi9cbiAgYXBwLnBvc3QoJy8nLCBleHBvcnRIYW5kbGVyKTtcblxuICAvKipcbiAgICogQWRkcyB0aGUgUE9TVCAvOmZpbGVuYW1lIGEgcm91dGUgZm9yIGhhbmRsaW5nIFBPU1QgcmVxdWVzdHMgd2l0aFxuICAgKiBhIHNwZWNpZmllZCBmaWxlbmFtZSBwYXJhbWV0ZXIuXG4gICAqL1xuICBhcHAucG9zdCgnLzpmaWxlbmFtZScsIGV4cG9ydEhhbmRsZXIpO1xufTtcbiIsIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG5cbkhpZ2hjaGFydHMgRXhwb3J0IFNlcnZlclxuXG5Db3B5cmlnaHQgKGMpIDIwMTYtMjAyNCwgSGlnaHNvZnRcblxuTGljZW5jZWQgdW5kZXIgdGhlIE1JVCBsaWNlbmNlLlxuXG5BZGRpdGlvbmFsbHkgYSB2YWxpZCBIaWdoY2hhcnRzIGxpY2Vuc2UgaXMgcmVxdWlyZWQgZm9yIHVzZS5cblxuU2VlIExJQ0VOU0UgZmlsZSBpbiByb290IGZvciBkZXRhaWxzLlxuXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG5pbXBvcnQgeyByZWFkRmlsZVN5bmMgfSBmcm9tICdmcyc7XG5pbXBvcnQgeyBqb2luIGFzIHBhdGhlciB9IGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgbG9nIH0gZnJvbSAnLi4vLi4vbG9nZ2VyLmpzJztcblxuaW1wb3J0IHsgdmVyc2lvbiB9IGZyb20gJy4uLy4uL2NhY2hlLmpzJztcbmltcG9ydCB7IGFkZEludGVydmFsIH0gZnJvbSAnLi4vLi4vaW50ZXJ2YWxzLmpzJztcbmltcG9ydCBwb29sIGZyb20gJy4uLy4uL3Bvb2wuanMnO1xuaW1wb3J0IHsgX19kaXJuYW1lIH0gZnJvbSAnLi4vLi4vdXRpbHMuanMnO1xuXG5jb25zdCBwa2dGaWxlID0gSlNPTi5wYXJzZShyZWFkRmlsZVN5bmMocGF0aGVyKF9fZGlybmFtZSwgJ3BhY2thZ2UuanNvbicpKSk7XG5cbmNvbnN0IHNlcnZlclN0YXJ0VGltZSA9IG5ldyBEYXRlKCk7XG5cbmNvbnN0IHN1Y2Nlc3NSYXRlcyA9IFtdO1xuY29uc3QgcmVjb3JkSW50ZXJ2YWwgPSA2MCAqIDEwMDA7IC8vIHJlY29yZCBldmVyeSBtaW51dGVcbmNvbnN0IHdpbmRvd1NpemUgPSAzMDsgLy8gMzAgbWludXRlc1xuXG4vKipcbiAqIENhbGN1bGF0ZXMgbW92aW5nIGF2ZXJhZ2UgaW5kaWNhdG9yIGJhc2VkIG9uIHRoZSBkYXRhIGZyb20gdGhlIHN1Y2Nlc3NSYXRlc1xuICogYXJyYXkuXG4gKlxuICogQHJldHVybnMge251bWJlcn0gLSBBIG1vdmluZyBhdmVyYWdlIGZvciBzdWNjZXNzIHJhdGlvIG9mIHRoZSBzZXJ2ZXIgZXhwb3J0cy5cbiAqL1xuZnVuY3Rpb24gY2FsY3VsYXRlTW92aW5nQXZlcmFnZSgpIHtcbiAgY29uc3Qgc3VtID0gc3VjY2Vzc1JhdGVzLnJlZHVjZSgoYSwgYikgPT4gYSArIGIsIDApO1xuICByZXR1cm4gc3VtIC8gc3VjY2Vzc1JhdGVzLmxlbmd0aDtcbn1cblxuLyoqXG4gKiBTdGFydHMgdGhlIGludGVydmFsIHJlc3BvbnNpYmxlIGZvciBjYWxjdWxhdGluZyBjdXJyZW50IHN1Y2Nlc3MgcmF0ZSByYXRpb1xuICogYW5kIGdhdGhlcnNcbiAqXG4gKiBAcmV0dXJucyB7Tm9kZUpTLlRpbWVvdXR9IGlkIC0gSWQgb2YgYW4gaW50ZXJ2YWwuXG4gKi9cbmV4cG9ydCBjb25zdCBzdGFydFN1Y2Nlc3NSYXRlID0gKCkgPT5cbiAgc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgIGNvbnN0IHN0YXRzID0gcG9vbC5nZXRTdGF0cygpO1xuICAgIGNvbnN0IHN1Y2Nlc3NSYXRpbyA9XG4gICAgICBzdGF0cy5leHBvcnRBdHRlbXB0cyA9PT0gMFxuICAgICAgICA/IDFcbiAgICAgICAgOiAoc3RhdHMucGVyZm9ybWVkRXhwb3J0cyAvIHN0YXRzLmV4cG9ydEF0dGVtcHRzKSAqIDEwMDtcblxuICAgIHN1Y2Nlc3NSYXRlcy5wdXNoKHN1Y2Nlc3NSYXRpbyk7XG4gICAgaWYgKHN1Y2Nlc3NSYXRlcy5sZW5ndGggPiB3aW5kb3dTaXplKSB7XG4gICAgICBzdWNjZXNzUmF0ZXMuc2hpZnQoKTtcbiAgICB9XG4gIH0sIHJlY29yZEludGVydmFsKTtcblxuLyoqXG4gKiBBZGRzIHRoZSAvaGVhbHRoIGFuZCAvc3VjY2Vzcy1tb3ZpbmctYXZlcmFnZSByb3V0ZXNcbiAqIHdoaWNoIG91dHB1dCBiYXNpYyBzdGF0cyBmb3IgdGhlIHNlcnZlci5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gYWRkSGVhbHRoUm91dGVzKGFwcCkge1xuICBpZiAoIWFwcCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIFN0YXJ0IHByb2Nlc3Npbmcgc3VjY2VzcyByYXRlIHJhdGlvIGludGVydmFsIGFuZCBzYXZlIGl0cyBpZCB0byB0aGUgYXJyYXlcbiAgLy8gZm9yIHRoZSBncmFjZWZ1bCBjbGVhcmluZyBvbiBzaHV0ZG93biB3aXRoIGluamVjdGVkIGFkZEludGVydmFsIGZ1bnRpb25cbiAgYWRkSW50ZXJ2YWwoc3RhcnRTdWNjZXNzUmF0ZSgpKTtcblxuICBhcHAuZ2V0KCcvaGVhbHRoJywgKF8sIHJlcykgPT4ge1xuICAgIGNvbnN0IHN0YXRzID0gcG9vbC5nZXRTdGF0cygpO1xuICAgIGNvbnN0IHBlcmlvZCA9IHN1Y2Nlc3NSYXRlcy5sZW5ndGg7XG4gICAgY29uc3QgbW92aW5nQXZlcmFnZSA9IGNhbGN1bGF0ZU1vdmluZ0F2ZXJhZ2UoKTtcblxuICAgIGxvZyg0LCAnW2hlYWx0aC5qc10gR0VUIC9oZWFsdGggWzIwMF0gLSByZXR1cm5pbmcgc2VydmVyIGhlYWx0aC4nKTtcblxuICAgIHJlcy5zZW5kKHtcbiAgICAgIHN0YXR1czogJ09LJyxcbiAgICAgIGJvb3RUaW1lOiBzZXJ2ZXJTdGFydFRpbWUsXG4gICAgICB1cHRpbWU6XG4gICAgICAgIE1hdGguZmxvb3IoXG4gICAgICAgICAgKG5ldyBEYXRlKCkuZ2V0VGltZSgpIC0gc2VydmVyU3RhcnRUaW1lLmdldFRpbWUoKSkgLyAxMDAwIC8gNjBcbiAgICAgICAgKSArICcgbWludXRlcycsXG4gICAgICB2ZXJzaW9uOiBwa2dGaWxlLnZlcnNpb24sXG4gICAgICBoaWdoY2hhcnRzVmVyc2lvbjogdmVyc2lvbigpLFxuICAgICAgYXZlcmFnZVByb2Nlc3NpbmdUaW1lOiBzdGF0cy5zcGVudEF2ZXJhZ2UsXG4gICAgICBwZXJmb3JtZWRFeHBvcnRzOiBzdGF0cy5wZXJmb3JtZWRFeHBvcnRzLFxuICAgICAgZmFpbGVkRXhwb3J0czogc3RhdHMuZHJvcHBlZEV4cG9ydHMsXG4gICAgICBleHBvcnRBdHRlbXB0czogc3RhdHMuZXhwb3J0QXR0ZW1wdHMsXG4gICAgICBzdWNlc3NSYXRpbzogKHN0YXRzLnBlcmZvcm1lZEV4cG9ydHMgLyBzdGF0cy5leHBvcnRBdHRlbXB0cykgKiAxMDAsXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLW5hbWVkLWFzLWRlZmF1bHQtbWVtYmVyXG4gICAgICBwb29sOiBwb29sLmdldFBvb2xJbmZvSlNPTigpLFxuXG4gICAgICAvLyBNb3ZpbmcgYXZlcmFnZVxuICAgICAgcGVyaW9kLFxuICAgICAgbW92aW5nQXZlcmFnZSxcbiAgICAgIG1lc3NhZ2U6XG4gICAgICAgIGlzTmFOKG1vdmluZ0F2ZXJhZ2UpIHx8ICFzdWNjZXNzUmF0ZXMubGVuZ3RoXG4gICAgICAgICAgPyAnVG9vIGVhcmx5IHRvIHJlcG9ydC4gTm8gZXhwb3J0cyBtYWRlIHlldC4gUGxlYXNlIGNoZWNrIGJhY2sgc29vbi4nXG4gICAgICAgICAgOiBgTGFzdCAke3BlcmlvZH0gbWludXRlcyBoYWQgYSBzdWNjZXNzIHJhdGUgb2YgJHttb3ZpbmdBdmVyYWdlLnRvRml4ZWQoMil9JS5gLFxuXG4gICAgICAvLyBTVkcvSlNPTiBhdHRlbXB0c1xuICAgICAgc3ZnRXhwb3J0QXR0ZW1wdHM6IHN0YXRzLmV4cG9ydEZyb21TdmdBdHRlbXB0cyxcbiAgICAgIGpzb25FeHBvcnRBdHRlbXB0czogc3RhdHMucGVyZm9ybWVkRXhwb3J0cyAtIHN0YXRzLmV4cG9ydEZyb21TdmdBdHRlbXB0c1xuICAgIH0pO1xuICB9KTtcbn1cbiIsIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG5cbkhpZ2hjaGFydHMgRXhwb3J0IFNlcnZlclxuXG5Db3B5cmlnaHQgKGMpIDIwMTYtMjAyNCwgSGlnaHNvZnRcblxuTGljZW5jZWQgdW5kZXIgdGhlIE1JVCBsaWNlbmNlLlxuXG5BZGRpdGlvbmFsbHkgYSB2YWxpZCBIaWdoY2hhcnRzIGxpY2Vuc2UgaXMgcmVxdWlyZWQgZm9yIHVzZS5cblxuU2VlIExJQ0VOU0UgZmlsZSBpbiByb290IGZvciBkZXRhaWxzLlxuXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG5pbXBvcnQgeyBwcm9taXNlcyBhcyBmc1Byb21pc2VzIH0gZnJvbSAnZnMnO1xuaW1wb3J0IHsgcG9zaXggfSBmcm9tICdwYXRoJztcblxuaW1wb3J0IGNvcnMgZnJvbSAnY29ycyc7XG5pbXBvcnQgZXhwcmVzcyBmcm9tICdleHByZXNzJztcbmltcG9ydCBodHRwIGZyb20gJ2h0dHAnO1xuaW1wb3J0IGh0dHBzIGZyb20gJ2h0dHBzJztcbmltcG9ydCBtdWx0ZXIgZnJvbSAnbXVsdGVyJztcblxuaW1wb3J0IGVycm9ySGFuZGxlciBmcm9tICcuL2Vycm9yLmpzJztcbmltcG9ydCByYXRlTGltaXQgZnJvbSAnLi9yYXRlX2xpbWl0LmpzJztcbmltcG9ydCB7IGxvZywgbG9nV2l0aFN0YWNrIH0gZnJvbSAnLi4vbG9nZ2VyLmpzJztcbmltcG9ydCB7IF9fZGlybmFtZSB9IGZyb20gJy4uL3V0aWxzLmpzJztcblxuaW1wb3J0IHZTd2l0Y2hSb3V0ZSBmcm9tICcuL3JvdXRlcy9jaGFuZ2VfaGNfdmVyc2lvbi5qcyc7XG5pbXBvcnQgZXhwb3J0Um91dGVzIGZyb20gJy4vcm91dGVzL2V4cG9ydC5qcyc7XG5pbXBvcnQgaGVhbHRoUm91dGUgZnJvbSAnLi9yb3V0ZXMvaGVhbHRoLmpzJztcbmltcG9ydCB1aVJvdXRlIGZyb20gJy4vcm91dGVzL3VpLmpzJztcblxuaW1wb3J0IEV4cG9ydEVycm9yIGZyb20gJy4uL2Vycm9ycy9FeHBvcnRFcnJvci5qcyc7XG5cbi8vIEFycmF5IG9mIGFuIGFjdGl2ZSBzZXJ2ZXJzXG5jb25zdCBhY3RpdmVTZXJ2ZXJzID0gbmV3IE1hcCgpO1xuXG4vLyBDcmVhdGUgZXhwcmVzcyBhcHBcbmNvbnN0IGFwcCA9IGV4cHJlc3MoKTtcblxuLy8gRGlzYWJsZSB0aGUgWC1Qb3dlcmVkLUJ5IGhlYWRlclxuYXBwLmRpc2FibGUoJ3gtcG93ZXJlZC1ieScpO1xuXG4vLyBFbmFibGUgQ09SUyBzdXBwb3J0XG5hcHAudXNlKGNvcnMoKSk7XG5cbi8vIEdldHRpbmcgYSBsb3Qgb2YgUmFuZ2VOb3RTYXRpc2ZpYWJsZUVycm9yIGV4Y2VwdGlvbi5cbi8vIEV2ZW4gdGhvdWdoIHRoaXMgaXMgYSBkZXByZWNhdGVkIG9wdGlvbnMsIGxldCdzIHRyeSB0byBzZXQgaXQgdG8gZmFsc2UuXG5hcHAudXNlKChfcmVxLCByZXMsIG5leHQpID0+IHtcbiAgcmVzLnNldCgnQWNjZXB0LVJhbmdlcycsICdub25lJyk7XG4gIG5leHQoKTtcbn0pO1xuXG4vKipcbiAqIEF0dGFjaCBlcnJvciBoYW5kbGVycyB0byB0aGUgc2VydmVyLlxuICpcbiAqIEBwYXJhbSB7aHR0cC5TZXJ2ZXJ9IHNlcnZlciAtIFRoZSBIVFRQL0hUVFBTIHNlcnZlciBpbnN0YW5jZS5cbiAqL1xuY29uc3QgYXR0YWNoU2VydmVyRXJyb3JIYW5kbGVycyA9IChzZXJ2ZXIpID0+IHtcbiAgc2VydmVyLm9uKCdjbGllbnRFcnJvcicsIChlcnJvciwgc29ja2V0KSA9PiB7XG4gICAgbG9nV2l0aFN0YWNrKFxuICAgICAgMSxcbiAgICAgIGVycm9yLFxuICAgICAgYFtzZXJ2ZXJdIENsaWVudCBlcnJvcjogJHtlcnJvci5tZXNzYWdlfSwgZGVzdHJveWluZyBzb2NrZXQuYFxuICAgICk7XG4gICAgc29ja2V0LmRlc3Ryb3koKTtcbiAgfSk7XG5cbiAgc2VydmVyLm9uKCdlcnJvcicsIChlcnJvcikgPT4ge1xuICAgIGxvZ1dpdGhTdGFjaygxLCBlcnJvciwgYFtzZXJ2ZXJdIFNlcnZlciBlcnJvcjogJHtlcnJvci5tZXNzYWdlfWApO1xuICB9KTtcblxuICBzZXJ2ZXIub24oJ2Nvbm5lY3Rpb24nLCAoc29ja2V0KSA9PiB7XG4gICAgc29ja2V0Lm9uKCdlcnJvcicsIChlcnJvcikgPT4ge1xuICAgICAgbG9nV2l0aFN0YWNrKDEsIGVycm9yLCBgW3NlcnZlcl0gU29ja2V0IGVycm9yOiAke2Vycm9yLm1lc3NhZ2V9YCk7XG4gICAgfSk7XG4gIH0pO1xufTtcblxuLyoqXG4gKiBTdGFydHMgYW4gSFRUUCBzZXJ2ZXIgYmFzZWQgb24gdGhlIHByb3ZpZGVkIGNvbmZpZ3VyYXRpb24uIFRoZSBgc2VydmVyQ29uZmlnYFxuICogb2JqZWN0IGNvbnRhaW5zIGFsbCBzZXJ2ZXIgcmVsYXRlZCBwcm9wZXJ0aWVzIChzZWUgdGhlIGBzZXJ2ZXJgIHNlY3Rpb25cbiAqIGluIHRoZSBgbGliL3NjaGVtYXMvY29uZmlnLmpzYCBmaWxlIGZvciBhIHJlZmVyZW5jZSkuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHNlcnZlckNvbmZpZyAtIFRoZSBzZXJ2ZXIgY29uZmlndXJhdGlvbiBvYmplY3QuXG4gKlxuICogQHRocm93cyB7RXhwb3J0RXJyb3J9IC0gVGhyb3dzIGFuIGVycm9yIGlmIHRoZSBzZXJ2ZXIgY2Fubm90IGJlIGNvbmZpZ3VyZWRcbiAqIGFuZCBzdGFydGVkLlxuICovXG5leHBvcnQgY29uc3Qgc3RhcnRTZXJ2ZXIgPSBhc3luYyAoc2VydmVyQ29uZmlnKSA9PiB7XG4gIHRyeSB7XG4gICAgLy8gVE9ETzogUmVhZCBmcm9tIGNvbmZpZy9lbnZcbiAgICAvLyBOT1RFOlxuICAgIC8vIFRvbyBiaWcgbGltaXRzIGxlYWQgdG8gdGltZW91dHMgaW4gdGhlIGV4cG9ydCBwcm9jZXNzIHdoZW4gdGhlXG4gICAgLy8gcmFzdGVyaXphdGlvbiB0aW1lb3V0IGlzIHNldCB0b28gbG93LlxuICAgIGNvbnN0IHVwbG9hZExpbWl0TWlCID0gc2VydmVyQ29uZmlnLm1heFVwbG9hZFNpemUgfHwgMztcbiAgICBjb25zdCB1cGxvYWRMaW1pdEJ5dGVzID0gdXBsb2FkTGltaXRNaUIgKiAxMDI0ICogMTAyNDtcblxuICAgIC8vIEVuYWJsZSBwYXJzaW5nIG9mIGZvcm0gZGF0YSAoZmlsZXMpIHdpdGggTXVsdGVyIHBhY2thZ2VcbiAgICBjb25zdCBzdG9yYWdlID0gbXVsdGVyLm1lbW9yeVN0b3JhZ2UoKTtcbiAgICBjb25zdCB1cGxvYWQgPSBtdWx0ZXIoe1xuICAgICAgc3RvcmFnZSxcbiAgICAgIGxpbWl0czoge1xuICAgICAgICBmaWVsZFNpemU6IHVwbG9hZExpbWl0Qnl0ZXNcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIEVuYWJsZSBib2R5IHBhcnNlclxuICAgIGFwcC51c2UoZXhwcmVzcy5qc29uKHsgbGltaXQ6IHVwbG9hZExpbWl0Qnl0ZXMgfSkpO1xuICAgIGFwcC51c2UoZXhwcmVzcy51cmxlbmNvZGVkKHsgZXh0ZW5kZWQ6IHRydWUsIGxpbWl0OiB1cGxvYWRMaW1pdEJ5dGVzIH0pKTtcblxuICAgIC8vIFVzZSBvbmx5IG5vbi1maWxlIG11bHRpcGFydCBmb3JtIGZpZWxkc1xuICAgIGFwcC51c2UodXBsb2FkLm5vbmUoKSk7XG5cbiAgICAvLyBTdG9wIGlmIG5vdCBlbmFibGVkXG4gICAgaWYgKCFzZXJ2ZXJDb25maWcuZW5hYmxlKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gTGlzdGVuIEhUVFAgc2VydmVyXG4gICAgaWYgKCFzZXJ2ZXJDb25maWcuc3NsLmZvcmNlKSB7XG4gICAgICAvLyBNYWluIHNlcnZlciBpbnN0YW5jZSAoSFRUUClcbiAgICAgIGNvbnN0IGh0dHBTZXJ2ZXIgPSBodHRwLmNyZWF0ZVNlcnZlcihhcHApO1xuXG4gICAgICAvLyBBdHRhY2ggZXJyb3IgaGFuZGxlcnMgYW5kIGxpc3RlbiB0byB0aGUgc2VydmVyXG4gICAgICBhdHRhY2hTZXJ2ZXJFcnJvckhhbmRsZXJzKGh0dHBTZXJ2ZXIpO1xuXG4gICAgICAvLyBMaXN0ZW5cbiAgICAgIGh0dHBTZXJ2ZXIubGlzdGVuKHNlcnZlckNvbmZpZy5wb3J0LCBzZXJ2ZXJDb25maWcuaG9zdCk7XG5cbiAgICAgIC8vIFNhdmUgdGhlIHJlZmVyZW5jZSB0byBIVFRQIHNlcnZlclxuICAgICAgYWN0aXZlU2VydmVycy5zZXQoc2VydmVyQ29uZmlnLnBvcnQsIGh0dHBTZXJ2ZXIpO1xuXG4gICAgICBsb2coXG4gICAgICAgIDMsXG4gICAgICAgIGBbc2VydmVyXSBTdGFydGVkIEhUVFAgc2VydmVyIG9uICR7c2VydmVyQ29uZmlnLmhvc3R9OiR7c2VydmVyQ29uZmlnLnBvcnR9LmBcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gTGlzdGVuIEhUVFBTIHNlcnZlclxuICAgIGlmIChzZXJ2ZXJDb25maWcuc3NsLmVuYWJsZSkge1xuICAgICAgLy8gU2V0IHVwIGFuIFNTTCBzZXJ2ZXIgYWxzb1xuICAgICAgbGV0IGtleSwgY2VydDtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gR2V0IHRoZSBTU0wga2V5XG4gICAgICAgIGtleSA9IGF3YWl0IGZzUHJvbWlzZXMucmVhZEZpbGUoXG4gICAgICAgICAgcG9zaXguam9pbihzZXJ2ZXJDb25maWcuc3NsLmNlcnRQYXRoLCAnc2VydmVyLmtleScpLFxuICAgICAgICAgICd1dGY4J1xuICAgICAgICApO1xuXG4gICAgICAgIC8vIEdldCB0aGUgU1NMIGNlcnRpZmljYXRlXG4gICAgICAgIGNlcnQgPSBhd2FpdCBmc1Byb21pc2VzLnJlYWRGaWxlKFxuICAgICAgICAgIHBvc2l4LmpvaW4oc2VydmVyQ29uZmlnLnNzbC5jZXJ0UGF0aCwgJ3NlcnZlci5jcnQnKSxcbiAgICAgICAgICAndXRmOCdcbiAgICAgICAgKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGxvZyhcbiAgICAgICAgICAyLFxuICAgICAgICAgIGBbc2VydmVyXSBVbmFibGUgdG8gbG9hZCBrZXkvY2VydGlmaWNhdGUgZnJvbSB0aGUgJyR7c2VydmVyQ29uZmlnLnNzbC5jZXJ0UGF0aH0nIHBhdGguIENvdWxkIG5vdCBydW4gc2VjdXJlZCBsYXllciBzZXJ2ZXIuYFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBpZiAoa2V5ICYmIGNlcnQpIHtcbiAgICAgICAgLy8gTWFpbiBzZXJ2ZXIgaW5zdGFuY2UgKEhUVFBTKVxuICAgICAgICBjb25zdCBodHRwc1NlcnZlciA9IGh0dHBzLmNyZWF0ZVNlcnZlcih7IGtleSwgY2VydCB9LCBhcHApO1xuXG4gICAgICAgIC8vIEF0dGFjaCBlcnJvciBoYW5kbGVycyBhbmQgbGlzdGVuIHRvIHRoZSBzZXJ2ZXJcbiAgICAgICAgYXR0YWNoU2VydmVyRXJyb3JIYW5kbGVycyhodHRwc1NlcnZlcik7XG5cbiAgICAgICAgLy8gTGlzdGVuXG4gICAgICAgIGh0dHBzU2VydmVyLmxpc3RlbihzZXJ2ZXJDb25maWcuc3NsLnBvcnQsIHNlcnZlckNvbmZpZy5ob3N0KTtcblxuICAgICAgICAvLyBTYXZlIHRoZSByZWZlcmVuY2UgdG8gSFRUUFMgc2VydmVyXG4gICAgICAgIGFjdGl2ZVNlcnZlcnMuc2V0KHNlcnZlckNvbmZpZy5zc2wucG9ydCwgaHR0cHNTZXJ2ZXIpO1xuXG4gICAgICAgIGxvZyhcbiAgICAgICAgICAzLFxuICAgICAgICAgIGBbc2VydmVyXSBTdGFydGVkIEhUVFBTIHNlcnZlciBvbiAke3NlcnZlckNvbmZpZy5ob3N0fToke3NlcnZlckNvbmZpZy5zc2wucG9ydH0uYFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEVuYWJsZSB0aGUgcmF0ZSBsaW1pdGVyIGlmIGNvbmZpZyBzYXlzIHNvXG4gICAgaWYgKFxuICAgICAgc2VydmVyQ29uZmlnLnJhdGVMaW1pdGluZyAmJlxuICAgICAgc2VydmVyQ29uZmlnLnJhdGVMaW1pdGluZy5lbmFibGUgJiZcbiAgICAgICFbMCwgTmFOXS5pbmNsdWRlcyhzZXJ2ZXJDb25maWcucmF0ZUxpbWl0aW5nLm1heFJlcXVlc3RzKVxuICAgICkge1xuICAgICAgcmF0ZUxpbWl0KGFwcCwgc2VydmVyQ29uZmlnLnJhdGVMaW1pdGluZyk7XG4gICAgfVxuXG4gICAgLy8gU2V0IHVwIHN0YXRpYyBmb2xkZXIncyByb3V0ZVxuICAgIGFwcC51c2UoZXhwcmVzcy5zdGF0aWMocG9zaXguam9pbihfX2Rpcm5hbWUsICdwdWJsaWMnKSkpO1xuXG4gICAgLy8gU2V0IHVwIHJvdXRlc1xuICAgIGhlYWx0aFJvdXRlKGFwcCk7XG4gICAgZXhwb3J0Um91dGVzKGFwcCk7XG4gICAgdWlSb3V0ZShhcHApO1xuICAgIHZTd2l0Y2hSb3V0ZShhcHApO1xuXG4gICAgLy8gU2V0IHVwIGNlbnRyYWxpemVkIGVycm9yIGhhbmRsZXJcbiAgICBlcnJvckhhbmRsZXIoYXBwKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICB0aHJvdyBuZXcgRXhwb3J0RXJyb3IoXG4gICAgICAnW3NlcnZlcl0gQ291bGQgbm90IGNvbmZpZ3VyZSBhbmQgc3RhcnQgdGhlIHNlcnZlci4nXG4gICAgKS5zZXRFcnJvcihlcnJvcik7XG4gIH1cbn07XG5cbi8qKlxuICogQ2xvc2VzIGFsbCBzZXJ2ZXJzIGFzc29jaWF0ZWQgd2l0aCBFeHByZXNzIGFwcCBpbnN0YW5jZS5cbiAqL1xuZXhwb3J0IGNvbnN0IGNsb3NlU2VydmVycyA9ICgpID0+IHtcbiAgbG9nKDQsIGBbc2VydmVyXSBDbG9zaW5nIGFsbCBzZXJ2ZXJzLmApO1xuICBmb3IgKGNvbnN0IFtwb3J0LCBzZXJ2ZXJdIG9mIGFjdGl2ZVNlcnZlcnMpIHtcbiAgICBzZXJ2ZXIuY2xvc2UoKCkgPT4ge1xuICAgICAgYWN0aXZlU2VydmVycy5kZWxldGUocG9ydCk7XG4gICAgICBsb2coNCwgYFtzZXJ2ZXJdIENsb3NlZCBzZXJ2ZXIgb24gcG9ydDogJHtwb3J0fS5gKTtcbiAgICB9KTtcbiAgfVxufTtcblxuLyoqXG4gKiBHZXQgYWxsIHNlcnZlcnMgYXNzb2NpYXRlZCB3aXRoIEV4cHJlc3MgYXBwIGluc3RhbmNlLlxuICpcbiAqIEByZXR1cm5zIHtBcnJheX0gLSBTZXJ2ZXJzIGFzc29jaWF0ZWQgd2l0aCBFeHByZXNzIGFwcCBpbnN0YW5jZS5cbiAqL1xuZXhwb3J0IGNvbnN0IGdldFNlcnZlcnMgPSAoKSA9PiBhY3RpdmVTZXJ2ZXJzO1xuXG4vKipcbiAqIEVuYWJsZSByYXRlIGxpbWl0aW5nIGZvciB0aGUgc2VydmVyLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBsaW1pdENvbmZpZyAtIENvbmZpZ3VyYXRpb24gb2JqZWN0IGZvciByYXRlIGxpbWl0aW5nLlxuICovXG5leHBvcnQgY29uc3QgZW5hYmxlUmF0ZUxpbWl0aW5nID0gKGxpbWl0Q29uZmlnKSA9PiByYXRlTGltaXQoYXBwLCBsaW1pdENvbmZpZyk7XG5cbi8qKlxuICogR2V0IHRoZSBFeHByZXNzIGluc3RhbmNlLlxuICpcbiAqIEByZXR1cm5zIHtPYmplY3R9IC0gVGhlIEV4cHJlc3MgaW5zdGFuY2UuXG4gKi9cbmV4cG9ydCBjb25zdCBnZXRFeHByZXNzID0gKCkgPT4gZXhwcmVzcztcblxuLyoqXG4gKiBHZXQgdGhlIEV4cHJlc3MgYXBwIGluc3RhbmNlLlxuICpcbiAqIEByZXR1cm5zIHtPYmplY3R9IC0gVGhlIEV4cHJlc3MgYXBwIGluc3RhbmNlLlxuICovXG5leHBvcnQgY29uc3QgZ2V0QXBwID0gKCkgPT4gYXBwO1xuXG4vKipcbiAqIEFwcGx5IG1pZGRsZXdhcmUocykgdG8gYSBzcGVjaWZpYyBwYXRoLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoIC0gVGhlIHBhdGggdG8gd2hpY2ggdGhlIG1pZGRsZXdhcmUocykgc2hvdWxkIGJlIGFwcGxpZWQuXG4gKiBAcGFyYW0gey4uLkZ1bmN0aW9ufSBtaWRkbGV3YXJlcyAtIFRoZSBtaWRkbGV3YXJlIGZ1bmN0aW9ucyB0byBiZSBhcHBsaWVkLlxuICovXG5leHBvcnQgY29uc3QgdXNlID0gKHBhdGgsIC4uLm1pZGRsZXdhcmVzKSA9PiB7XG4gIGFwcC51c2UocGF0aCwgLi4ubWlkZGxld2FyZXMpO1xufTtcblxuLyoqXG4gKiBTZXQgdXAgYSByb3V0ZSB3aXRoIEdFVCBtZXRob2QgYW5kIGFwcGx5IG1pZGRsZXdhcmUocykuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHBhdGggLSBUaGUgcm91dGUgcGF0aC5cbiAqIEBwYXJhbSB7Li4uRnVuY3Rpb259IG1pZGRsZXdhcmVzIC0gVGhlIG1pZGRsZXdhcmUgZnVuY3Rpb25zIHRvIGJlIGFwcGxpZWQuXG4gKi9cbmV4cG9ydCBjb25zdCBnZXQgPSAocGF0aCwgLi4ubWlkZGxld2FyZXMpID0+IHtcbiAgYXBwLmdldChwYXRoLCAuLi5taWRkbGV3YXJlcyk7XG59O1xuXG4vKipcbiAqIFNldCB1cCBhIHJvdXRlIHdpdGggUE9TVCBtZXRob2QgYW5kIGFwcGx5IG1pZGRsZXdhcmUocykuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHBhdGggLSBUaGUgcm91dGUgcGF0aC5cbiAqIEBwYXJhbSB7Li4uRnVuY3Rpb259IG1pZGRsZXdhcmVzIC0gVGhlIG1pZGRsZXdhcmUgZnVuY3Rpb25zIHRvIGJlIGFwcGxpZWQuXG4gKi9cbmV4cG9ydCBjb25zdCBwb3N0ID0gKHBhdGgsIC4uLm1pZGRsZXdhcmVzKSA9PiB7XG4gIGFwcC5wb3N0KHBhdGgsIC4uLm1pZGRsZXdhcmVzKTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgc3RhcnRTZXJ2ZXIsXG4gIGNsb3NlU2VydmVycyxcbiAgZ2V0U2VydmVycyxcbiAgZW5hYmxlUmF0ZUxpbWl0aW5nLFxuICBnZXRFeHByZXNzLFxuICBnZXRBcHAsXG4gIHVzZSxcbiAgZ2V0LFxuICBwb3N0XG59O1xuIiwiLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcblxuSGlnaGNoYXJ0cyBFeHBvcnQgU2VydmVyXG5cbkNvcHlyaWdodCAoYykgMjAxNi0yMDI0LCBIaWdoc29mdFxuXG5MaWNlbmNlZCB1bmRlciB0aGUgTUlUIGxpY2VuY2UuXG5cbkFkZGl0aW9uYWxseSBhIHZhbGlkIEhpZ2hjaGFydHMgbGljZW5zZSBpcyByZXF1aXJlZCBmb3IgdXNlLlxuXG5TZWUgTElDRU5TRSBmaWxlIGluIHJvb3QgZm9yIGRldGFpbHMuXG5cbioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG5cbmltcG9ydCB7IGpvaW4gfSBmcm9tICdwYXRoJztcblxuaW1wb3J0IHsgX19kaXJuYW1lIH0gZnJvbSAnLi4vLi4vdXRpbHMuanMnO1xuXG4vKipcbiAqIEFkZHMgdGhlIEdFVCAvIHJvdXRlIGZvciBhIFVJIHdoZW4gZW5hYmxlZCBvbiB0aGUgZXhwb3J0IHNlcnZlci5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgKGFwcCkgPT5cbiAgIWFwcFxuICAgID8gZmFsc2VcbiAgICA6IGFwcC5nZXQoJy8nLCAoX3JlcXVlc3QsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgIHJlc3BvbnNlLnNlbmRGaWxlKGpvaW4oX19kaXJuYW1lLCAncHVibGljJywgJ2luZGV4Lmh0bWwnKSwge1xuICAgICAgICAgIGFjY2VwdFJhbmdlczogZmFsc2VcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiIsIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG5cbkhpZ2hjaGFydHMgRXhwb3J0IFNlcnZlclxuXG5Db3B5cmlnaHQgKGMpIDIwMTYtMjAyNCwgSGlnaHNvZnRcblxuTGljZW5jZWQgdW5kZXIgdGhlIE1JVCBsaWNlbmNlLlxuXG5BZGRpdGlvbmFsbHkgYSB2YWxpZCBIaWdoY2hhcnRzIGxpY2Vuc2UgaXMgcmVxdWlyZWQgZm9yIHVzZS5cblxuU2VlIExJQ0VOU0UgZmlsZSBpbiByb290IGZvciBkZXRhaWxzLlxuXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG5pbXBvcnQgeyBjbGVhckFsbEludGVydmFscyB9IGZyb20gJy4vaW50ZXJ2YWxzLmpzJztcbmltcG9ydCB7IGtpbGxQb29sIH0gZnJvbSAnLi9wb29sLmpzJztcbmltcG9ydCB7IGNsb3NlU2VydmVycyB9IGZyb20gJy4vc2VydmVyL3NlcnZlci5qcyc7XG5cbi8qKlxuICogQ2xlYW4gdXAgZnVuY3Rpb24gdG8gdHJpZ2dlciBiZWZvcmUgZW5kaW5nIHByb2Nlc3MgZm9yIHRoZSBncmFjZWZ1bCBzaHV0ZG93bi5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gZXhpdENvZGUgLSBBbiBleGl0IGNvZGUgZm9yIHRoZSBwcm9jZXNzLmV4aXQoKSBmdW5jdGlvbi5cbiAqL1xuZXhwb3J0IGNvbnN0IHNodXRkb3duQ2xlYW5VcCA9IGFzeW5jIChleGl0Q29kZSkgPT4ge1xuICAvLyBBd2FpdCBmcmVlaW5nIGFsbCByZXNvdXJjZXNcbiAgYXdhaXQgUHJvbWlzZS5hbGxTZXR0bGVkKFtcbiAgICAvLyBDbGVhciBhbGwgb25nb2luZyBpbnRlcnZhbHNcbiAgICBjbGVhckFsbEludGVydmFscygpLFxuXG4gICAgLy8gR2V0IGF2YWlsYWJsZSBzZXJ2ZXIgaW5zdGFuY2VzIChIVFRQL0hUVFBTKSBhbmQgY2xvc2UgdGhlbVxuICAgIGNsb3NlU2VydmVycygpLFxuXG4gICAgLy8gQ2xvc2UgcG9vbCBhbG9uZyB3aXRoIGl0cyB3b3JrZXJzIGFuZCB0aGUgYnJvd3NlciBpbnN0YW5jZSwgaWYgZXhpc3RzXG4gICAga2lsbFBvb2woKVxuICBdKTtcblxuICAvLyBFeGl0IHByb2Nlc3Mgd2l0aCBhIGNvcnJlY3QgY29kZVxuICBwcm9jZXNzLmV4aXQoZXhpdENvZGUpO1xufTtcblxuZXhwb3J0IGRlZmF1bHQge1xuICBzaHV0ZG93bkNsZWFuVXBcbn07XG4iLCIvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuXG5IaWdoY2hhcnRzIEV4cG9ydCBTZXJ2ZXJcblxuQ29weXJpZ2h0IChjKSAyMDE2LTIwMjQsIEhpZ2hzb2Z0XG5cbkxpY2VuY2VkIHVuZGVyIHRoZSBNSVQgbGljZW5jZS5cblxuQWRkaXRpb25hbGx5IGEgdmFsaWQgSGlnaGNoYXJ0cyBsaWNlbnNlIGlzIHJlcXVpcmVkIGZvciB1c2UuXG5cblNlZSBMSUNFTlNFIGZpbGUgaW4gcm9vdCBmb3IgZGV0YWlscy5cblxuKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuaW1wb3J0ICdjb2xvcnMnO1xuXG5pbXBvcnQgeyBjaGVja0FuZFVwZGF0ZUNhY2hlIH0gZnJvbSAnLi9jYWNoZS5qcyc7XG5pbXBvcnQge1xuICBiYXRjaEV4cG9ydCxcbiAgc2V0QWxsb3dDb2RlRXhlY3V0aW9uLFxuICBzaW5nbGVFeHBvcnQsXG4gIHN0YXJ0RXhwb3J0XG59IGZyb20gJy4vY2hhcnQuanMnO1xuaW1wb3J0IHsgbWFwVG9OZXdDb25maWcsIG1hbnVhbENvbmZpZywgc2V0T3B0aW9ucyB9IGZyb20gJy4vY29uZmlnLmpzJztcbmltcG9ydCB7XG4gIGluaXRMb2dnaW5nLFxuICBsb2csXG4gIGxvZ1dpdGhTdGFjayxcbiAgc2V0TG9nTGV2ZWwsXG4gIGVuYWJsZUZpbGVMb2dnaW5nXG59IGZyb20gJy4vbG9nZ2VyLmpzJztcbmltcG9ydCB7IGluaXRQb29sLCBraWxsUG9vbCB9IGZyb20gJy4vcG9vbC5qcyc7XG5pbXBvcnQgeyBzaHV0ZG93bkNsZWFuVXAgfSBmcm9tICcuL3Jlc291cmNlX3JlbGVhc2UuanMnO1xuaW1wb3J0IHNlcnZlciwgeyBzdGFydFNlcnZlciB9IGZyb20gJy4vc2VydmVyL3NlcnZlci5qcyc7XG5pbXBvcnQgeyBwcmludExvZ28sIHByaW50VXNhZ2UgfSBmcm9tICcuL3V0aWxzLmpzJztcblxuLyoqXG4gKiBBdHRhY2hlcyBleGl0IGxpc3RlbmVycyB0byB0aGUgcHJvY2VzcywgZW5zdXJpbmcgcHJvcGVyIGNsZWFudXAgb2YgcmVzb3VyY2VzXG4gKiBhbmQgdGVybWluYXRpb24gb24gZXhpdCBzaWduYWxzLiBIYW5kbGVzICdleGl0JywgJ1NJR0lOVCcsICdTSUdURVJNJywgYW5kXG4gKiAndW5jYXVnaHRFeGNlcHRpb24nIGV2ZW50cy5cbiAqL1xuY29uc3QgYXR0YWNoUHJvY2Vzc0V4aXRMaXN0ZW5lcnMgPSAoKSA9PiB7XG4gIGxvZygzLCAnW3Byb2Nlc3NdIEF0dGFjaGluZyBleGl0IGxpc3RlbmVycyB0byB0aGUgcHJvY2Vzcy4nKTtcblxuICAvLyBIYW5kbGVyIGZvciB0aGUgJ2V4aXQnXG4gIHByb2Nlc3Mub24oJ2V4aXQnLCAoY29kZSkgPT4ge1xuICAgIGxvZyg0LCBgUHJvY2VzcyBleGl0ZWQgd2l0aCBjb2RlICR7Y29kZX0uYCk7XG4gIH0pO1xuXG4gIC8vIEhhbmRsZXIgZm9yIHRoZSAnU0lHSU5UJ1xuICBwcm9jZXNzLm9uKCdTSUdJTlQnLCBhc3luYyAobmFtZSwgY29kZSkgPT4ge1xuICAgIGxvZyg0LCBgVGhlICR7bmFtZX0gZXZlbnQgd2l0aCBjb2RlOiAke2NvZGV9LmApO1xuICAgIGF3YWl0IHNodXRkb3duQ2xlYW5VcCgwKTtcbiAgfSk7XG5cbiAgLy8gSGFuZGxlciBmb3IgdGhlICdTSUdURVJNJ1xuICBwcm9jZXNzLm9uKCdTSUdURVJNJywgYXN5bmMgKG5hbWUsIGNvZGUpID0+IHtcbiAgICBsb2coNCwgYFRoZSAke25hbWV9IGV2ZW50IHdpdGggY29kZTogJHtjb2RlfS5gKTtcbiAgICBhd2FpdCBzaHV0ZG93bkNsZWFuVXAoMCk7XG4gIH0pO1xuXG4gIC8vIEhhbmRsZXIgZm9yIHRoZSAnU0lHSFVQJ1xuICBwcm9jZXNzLm9uKCdTSUdIVVAnLCBhc3luYyAobmFtZSwgY29kZSkgPT4ge1xuICAgIGxvZyg0LCBgVGhlICR7bmFtZX0gZXZlbnQgd2l0aCBjb2RlOiAke2NvZGV9LmApO1xuICAgIGF3YWl0IHNodXRkb3duQ2xlYW5VcCgwKTtcbiAgfSk7XG5cbiAgLy8gSGFuZGxlciBmb3IgdGhlICd1bmNhdWdodEV4Y2VwdGlvbidcbiAgcHJvY2Vzcy5vbigndW5jYXVnaHRFeGNlcHRpb24nLCBhc3luYyAoZXJyb3IsIG5hbWUpID0+IHtcbiAgICBsb2dXaXRoU3RhY2soMSwgZXJyb3IsIGBUaGUgJHtuYW1lfSBlcnJvci5gKTtcbiAgICBhd2FpdCBzaHV0ZG93bkNsZWFuVXAoMSk7XG4gIH0pO1xufTtcblxuLyoqXG4gKiBJbml0aWFsaXplcyB0aGUgZXhwb3J0IHByb2Nlc3MuIFRhc2tzIHN1Y2ggYXMgY29uZmlndXJpbmcgbG9nZ2luZywgY2hlY2tpbmdcbiAqIGNhY2hlIGFuZCBzb3VyY2VzLCBhbmQgaW5pdGlhbGl6aW5nIHRoZSBwb29sIG9mIHJlc291cmNlcyBoYXBwZW4gZHVyaW5nXG4gKiB0aGlzIHN0YWdlLiBGdW5jdGlvbiB0aGF0IGlzIHJlcXVpcmVkIHRvIGJlIGNhbGxlZCBiZWZvcmUgdHJ5aW5nIHRvIGV4cG9ydCBjaGFydHMgb3Igc2V0dGluZyBhIHNlcnZlci4gVGhlIGBvcHRpb25zYCBpcyBhbiBvYmplY3QgdGhhdCBjb250YWlucyBhbGwgb3B0aW9ucy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIEFsbCBleHBvcnQgb3B0aW9ucy5cbiAqXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxPYmplY3Q+fSBQcm9taXNlIHJlc29sdmluZyB0byB0aGUgdXBkYXRlZCBleHBvcnQgb3B0aW9ucy5cbiAqL1xuY29uc3QgaW5pdEV4cG9ydCA9IGFzeW5jIChvcHRpb25zKSA9PiB7XG4gIC8vIFNldCB0aGUgYWxsb3dDb2RlRXhlY3V0aW9uIHBlciBleHBvcnQgbW9kdWxlIHNjb3BlXG4gIHNldEFsbG93Q29kZUV4ZWN1dGlvbihcbiAgICBvcHRpb25zLmN1c3RvbUxvZ2ljICYmIG9wdGlvbnMuY3VzdG9tTG9naWMuYWxsb3dDb2RlRXhlY3V0aW9uXG4gICk7XG5cbiAgLy8gSW5pdCB0aGUgbG9nZ2luZ1xuICBpbml0TG9nZ2luZyhvcHRpb25zLmxvZ2dpbmcpO1xuXG4gIC8vIEF0dGFjaCBwcm9jZXNzJyBleGl0IGxpc3RlbmVyc1xuICBpZiAob3B0aW9ucy5vdGhlci5saXN0ZW5Ub1Byb2Nlc3NFeGl0cykge1xuICAgIGF0dGFjaFByb2Nlc3NFeGl0TGlzdGVuZXJzKCk7XG4gIH1cblxuICAvLyBDaGVjayBpZiBjYWNoZSBuZWVkcyB0byBiZSB1cGRhdGVkXG4gIGF3YWl0IGNoZWNrQW5kVXBkYXRlQ2FjaGUob3B0aW9ucyk7XG5cbiAgLy8gSW5pdCB0aGUgcG9vbFxuICBhd2FpdCBpbml0UG9vbCh7XG4gICAgcG9vbDogb3B0aW9ucy5wb29sIHx8IHtcbiAgICAgIG1pbldvcmtlcnM6IDEsXG4gICAgICBtYXhXb3JrZXJzOiAxXG4gICAgfSxcbiAgICBwdXBwZXRlZXJBcmdzOiBvcHRpb25zLnB1cHBldGVlci5hcmdzIHx8IFtdXG4gIH0pO1xuXG4gIC8vIFJldHVybiB1cGRhdGVkIG9wdGlvbnNcbiAgcmV0dXJuIG9wdGlvbnM7XG59O1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIC8vIFNlcnZlclxuICBzZXJ2ZXIsXG4gIHN0YXJ0U2VydmVyLFxuXG4gIC8vIEV4cG9ydGluZ1xuICBpbml0RXhwb3J0LFxuICBzaW5nbGVFeHBvcnQsXG4gIGJhdGNoRXhwb3J0LFxuICBzdGFydEV4cG9ydCxcblxuICAvLyBQb29sXG4gIGluaXRQb29sLFxuICBraWxsUG9vbCxcblxuICAvLyBPdGhlclxuICBzZXRPcHRpb25zLFxuICBzaHV0ZG93bkNsZWFuVXAsXG5cbiAgLy8gTG9nc1xuICBsb2csXG4gIGxvZ1dpdGhTdGFjayxcbiAgc2V0TG9nTGV2ZWwsXG4gIGVuYWJsZUZpbGVMb2dnaW5nLFxuXG4gIC8vIFV0aWxzXG4gIG1hcFRvTmV3Q29uZmlnLFxuICBtYW51YWxDb25maWcsXG4gIHByaW50TG9nbyxcbiAgcHJpbnRVc2FnZVxufTtcbiJdLCJuYW1lcyI6WyJzY3JpcHRzTmFtZXMiLCJjb3JlIiwibW9kdWxlcyIsImluZGljYXRvcnMiLCJjdXN0b20iLCJkZWZhdWx0Q29uZmlnIiwicHVwcGV0ZWVyIiwiYXJncyIsInZhbHVlIiwidHlwZSIsImRlc2NyaXB0aW9uIiwidGVtcERpciIsImVudkxpbmsiLCJoaWdoY2hhcnRzIiwidmVyc2lvbiIsImNkblVSTCIsImNvcmVTY3JpcHRzIiwibW9kdWxlU2NyaXB0cyIsImluZGljYXRvclNjcmlwdHMiLCJjdXN0b21TY3JpcHRzIiwiZm9yY2VGZXRjaCIsImNhY2hlUGF0aCIsImV4cG9ydCIsImluZmlsZSIsImluc3RyIiwib3B0aW9ucyIsIm91dGZpbGUiLCJjb25zdHIiLCJkZWZhdWx0SGVpZ2h0IiwiZGVmYXVsdFdpZHRoIiwiZGVmYXVsdFNjYWxlIiwiaGVpZ2h0Iiwid2lkdGgiLCJzY2FsZSIsImdsb2JhbE9wdGlvbnMiLCJ0aGVtZU9wdGlvbnMiLCJiYXRjaCIsInJhc3Rlcml6YXRpb25UaW1lb3V0IiwiY3VzdG9tTG9naWMiLCJhbGxvd0NvZGVFeGVjdXRpb24iLCJhbGxvd0ZpbGVSZXNvdXJjZXMiLCJjdXN0b21Db2RlIiwiY2FsbGJhY2siLCJyZXNvdXJjZXMiLCJsb2FkQ29uZmlnIiwibGVnYWN5TmFtZSIsImNyZWF0ZUNvbmZpZyIsInNlcnZlciIsIm1heFVwbG9hZFNpemUiLCJlbmFibGUiLCJjbGlOYW1lIiwiaG9zdCIsInBvcnQiLCJiZW5jaG1hcmtpbmciLCJwcm94eSIsInVzZXJuYW1lIiwicGFzc3dvcmQiLCJ0aW1lb3V0IiwicmF0ZUxpbWl0aW5nIiwibWF4UmVxdWVzdHMiLCJ3aW5kb3ciLCJkZWxheSIsInRydXN0UHJveHkiLCJza2lwS2V5Iiwic2tpcFRva2VuIiwic3NsIiwiZm9yY2UiLCJjZXJ0UGF0aCIsInBvb2wiLCJtaW5Xb3JrZXJzIiwibWF4V29ya2VycyIsIndvcmtMaW1pdCIsImFjcXVpcmVUaW1lb3V0IiwiY3JlYXRlVGltZW91dCIsImRlc3Ryb3lUaW1lb3V0IiwiaWRsZVRpbWVvdXQiLCJjcmVhdGVSZXRyeUludGVydmFsIiwicmVhcGVySW50ZXJ2YWwiLCJsb2dnaW5nIiwibGV2ZWwiLCJmaWxlIiwiZGVzdCIsInRvQ29uc29sZSIsInRvRmlsZSIsInVpIiwicm91dGUiLCJvdGhlciIsIm5vZGVFbnYiLCJsaXN0ZW5Ub1Byb2Nlc3NFeGl0cyIsIm5vTG9nbyIsImhhcmRSZXNldFBhZ2UiLCJicm93c2VyU2hlbGxNb2RlIiwiZGVidWciLCJoZWFkbGVzcyIsImRldnRvb2xzIiwibGlzdGVuVG9Db25zb2xlIiwiZHVtcGlvIiwic2xvd01vIiwiZGVidWdnaW5nUG9ydCIsInByb21wdHNDb25maWciLCJuYW1lIiwibWVzc2FnZSIsImluaXRpYWwiLCJqb2luIiwic2VwYXJhdG9yIiwiaW5zdHJ1Y3Rpb25zIiwiY2hvaWNlcyIsImhpbnQiLCJtaW4iLCJtYXgiLCJyb3VuZCIsImFic29sdXRlUHJvcHMiLCJuZXN0ZWRBcmdzIiwiY3JlYXRlTmVzdGVkQXJncyIsIm9iaiIsInByb3BDaGFpbiIsIk9iamVjdCIsImtleXMiLCJmb3JFYWNoIiwiayIsImluY2x1ZGVzIiwiZW50cnkiLCJzdWJzdHJpbmciLCJ1bmRlZmluZWQiLCJkb3RlbnYiLCJjb25maWciLCJ2IiwiZmlsdGVyQXJyYXkiLCJ6Iiwic3RyaW5nIiwidHJhbnNmb3JtIiwic3BsaXQiLCJtYXAiLCJ0cmltIiwiZmlsdGVyIiwibGVuZ3RoIiwiZW51bSIsInZhbHVlcyIsInJlZmluZSIsInRlc3QiLCJpc05hTiIsInBhcnNlRmxvYXQiLCJlbnZzIiwib2JqZWN0IiwiUFVQUEVURUVSX1RFTVBfRElSIiwiSElHSENIQVJUU19WRVJTSU9OIiwiSElHSENIQVJUU19DRE5fVVJMIiwic3RhcnRzV2l0aCIsIkhJR0hDSEFSVFNfQ09SRV9TQ1JJUFRTIiwiSElHSENIQVJUU19NT0RVTEVfU0NSSVBUUyIsIkhJR0hDSEFSVFNfSU5ESUNBVE9SX1NDUklQVFMiLCJISUdIQ0hBUlRTX0ZPUkNFX0ZFVENIIiwiSElHSENIQVJUU19DQUNIRV9QQVRIIiwiSElHSENIQVJUU19BRE1JTl9UT0tFTiIsIkVYUE9SVF9UWVBFIiwiRVhQT1JUX0NPTlNUUiIsIkVYUE9SVF9ERUZBVUxUX0hFSUdIVCIsIkVYUE9SVF9ERUZBVUxUX1dJRFRIIiwiRVhQT1JUX0RFRkFVTFRfU0NBTEUiLCJFWFBPUlRfUkFTVEVSSVpBVElPTl9USU1FT1VUIiwiQ1VTVE9NX0xPR0lDX0FMTE9XX0NPREVfRVhFQ1VUSU9OIiwiQ1VTVE9NX0xPR0lDX0FMTE9XX0ZJTEVfUkVTT1VSQ0VTIiwiU0VSVkVSX0VOQUJMRSIsIlNFUlZFUl9IT1NUIiwiU0VSVkVSX1BPUlQiLCJTRVJWRVJfTUFYX1VQTE9BRF9TSVpFIiwiU0VSVkVSX0JFTkNITUFSS0lORyIsIlNFUlZFUl9QUk9YWV9IT1NUIiwiU0VSVkVSX1BST1hZX1BPUlQiLCJTRVJWRVJfUFJPWFlfVVNFUk5BTUUiLCJTRVJWRVJfUFJPWFlfUEFTU1dPUkQiLCJTRVJWRVJfUFJPWFlfVElNRU9VVCIsIlNFUlZFUl9SQVRFX0xJTUlUSU5HX0VOQUJMRSIsIlNFUlZFUl9SQVRFX0xJTUlUSU5HX01BWF9SRVFVRVNUUyIsIlNFUlZFUl9SQVRFX0xJTUlUSU5HX1dJTkRPVyIsIlNFUlZFUl9SQVRFX0xJTUlUSU5HX0RFTEFZIiwiU0VSVkVSX1JBVEVfTElNSVRJTkdfVFJVU1RfUFJPWFkiLCJTRVJWRVJfUkFURV9MSU1JVElOR19TS0lQX0tFWSIsIlNFUlZFUl9SQVRFX0xJTUlUSU5HX1NLSVBfVE9LRU4iLCJTRVJWRVJfU1NMX0VOQUJMRSIsIlNFUlZFUl9TU0xfRk9SQ0UiLCJTRVJWRVJfU1NMX1BPUlQiLCJTRVJWRVJfU1NMX0NFUlRfUEFUSCIsIlBPT0xfTUlOX1dPUktFUlMiLCJQT09MX01BWF9XT1JLRVJTIiwiUE9PTF9XT1JLX0xJTUlUIiwiUE9PTF9BQ1FVSVJFX1RJTUVPVVQiLCJQT09MX0NSRUFURV9USU1FT1VUIiwiUE9PTF9ERVNUUk9ZX1RJTUVPVVQiLCJQT09MX0lETEVfVElNRU9VVCIsIlBPT0xfQ1JFQVRFX1JFVFJZX0lOVEVSVkFMIiwiUE9PTF9SRUFQRVJfSU5URVJWQUwiLCJQT09MX0JFTkNITUFSS0lORyIsIkxPR0dJTkdfTEVWRUwiLCJMT0dHSU5HX0ZJTEUiLCJMT0dHSU5HX0RFU1QiLCJMT0dHSU5HX1RPX0NPTlNPTEUiLCJMT0dHSU5HX1RPX0ZJTEUiLCJVSV9FTkFCTEUiLCJVSV9ST1VURSIsIk9USEVSX05PREVfRU5WIiwiT1RIRVJfTElTVEVOX1RPX1BST0NFU1NfRVhJVFMiLCJPVEhFUl9OT19MT0dPIiwiT1RIRVJfSEFSRF9SRVNFVF9QQUdFIiwiT1RIRVJfQlJPV1NFUl9TSEVMTF9NT0RFIiwiT1RIRVJfQUxMT1dfWExJTksiLCJERUJVR19FTkFCTEUiLCJERUJVR19IRUFETEVTUyIsIkRFQlVHX0RFVlRPT0xTIiwiREVCVUdfTElTVEVOX1RPX0NPTlNPTEUiLCJERUJVR19EVU1QSU8iLCJERUJVR19TTE9XX01PIiwiREVCVUdfREVCVUdHSU5HX1BPUlQiLCJwYXJ0aWFsIiwicGFyc2UiLCJwcm9jZXNzIiwiZW52IiwiY29sb3JzIiwicGF0aENyZWF0ZWQiLCJsZXZlbHNEZXNjIiwidGl0bGUiLCJjb2xvciIsImxpc3RlbmVycyIsImxvZ1RvRmlsZSIsInRleHRzIiwicHJlZml4IiwiZXhpc3RzU3luYyIsIm1rZGlyU3luYyIsImFwcGVuZEZpbGUiLCJjb25jYXQiLCJlcnJvciIsImNvbnNvbGUiLCJsb2ciLCJuZXdMZXZlbCIsIkRhdGUiLCJ0b1N0cmluZyIsImZuIiwiYXBwbHkiLCJsb2dXaXRoU3RhY2siLCJjdXN0b21NZXNzYWdlIiwibWFpbk1lc3NhZ2UiLCJzdGFja01lc3NhZ2UiLCJzdGFjayIsInNsaWNlIiwic2V0TG9nTGV2ZWwiLCJlbmFibGVGaWxlTG9nZ2luZyIsImxvZ0Rlc3QiLCJsb2dGaWxlIiwiZW5kc1dpdGgiLCJfX2Rpcm5hbWUiLCJmaWxlVVJMVG9QYXRoIiwiVVJMIiwiZG9jdW1lbnQiLCJyZXF1aXJlIiwicGF0aFRvRmlsZVVSTCIsIl9fZmlsZW5hbWUiLCJocmVmIiwiX2RvY3VtZW50Q3VycmVudFNjcmlwdCIsInRhZ05hbWUiLCJ0b1VwcGVyQ2FzZSIsInNyYyIsImJhc2VVUkkiLCJmaXhUeXBlIiwiZm9ybWF0cyIsIm91dFR5cGUiLCJwb3AiLCJmaW5kIiwidCIsImhhbmRsZVJlc291cmNlcyIsImFsbG93ZWRQcm9wcyIsImhhbmRsZWRSZXNvdXJjZXMiLCJjb3JyZWN0UmVzb3VyY2VzIiwiaXNDb3JyZWN0SlNPTiIsInJlYWRGaWxlU3luYyIsImZpbGVzIiwicHJvcE5hbWUiLCJpdGVtIiwiZGF0YSIsInBhcnNlZERhdGEiLCJKU09OIiwic3RyaW5naWZ5IiwiZGVlcENvcHkiLCJjb3B5IiwiQXJyYXkiLCJpc0FycmF5Iiwia2V5IiwicHJvdG90eXBlIiwiaGFzT3duUHJvcGVydHkiLCJjYWxsIiwib3B0aW9uc1N0cmluZ2lmeSIsImFsbG93RnVuY3Rpb25zIiwicmVwbGFjZUFsbCIsInByaW50VXNhZ2UiLCJib2xkIiwieWVsbG93IiwiY3ljbGVDYXRlZ29yaWVzIiwib3B0aW9uIiwiZW50cmllcyIsImRlc2NOYW1lIiwiZ3JlZW4iLCJpIiwiYmx1ZSIsImNhdGVnb3J5IiwicmVkIiwidG9Cb29sZWFuIiwid3JhcEFyb3VuZCIsInJlcGxhY2UiLCJtZWFzdXJlVGltZSIsInN0YXJ0IiwiaHJ0aW1lIiwiYmlnaW50IiwiTnVtYmVyIiwiZ2VuZXJhbE9wdGlvbnMiLCJnZXRPcHRpb25zIiwibWVyZ2VDb25maWdPcHRpb25zIiwibmV3T3B0aW9ucyIsIm1lcmdlZE9wdGlvbnMiLCJ1cGRhdGVEZWZhdWx0Q29uZmlnIiwiY29uZmlnT2JqIiwiY3VzdG9tT2JqIiwiY3VzdG9tVmFsdWUiLCJpbml0T3B0aW9ucyIsIml0ZW1zIiwicmVjdXJzaXZlUHJvcHMiLCJvYmplY3RUb1VwZGF0ZSIsIm5lc3RlZE5hbWVzIiwic2hpZnQiLCJhc3NpZ24iLCJhc3luYyIsImZldGNoIiwidXJsIiwicmVxdWVzdE9wdGlvbnMiLCJQcm9taXNlIiwicmVzb2x2ZSIsInJlamVjdCIsInByb3RvY29sIiwiaHR0cHMiLCJodHRwIiwiZ2V0UHJvdG9jb2wiLCJnZXQiLCJoZWFkZXJzIiwiUmVmZXJlciIsInJlcyIsIm9uIiwiY2h1bmsiLCJ0ZXh0IiwiRXhwb3J0RXJyb3IiLCJFcnJvciIsImNvbnN0cnVjdG9yIiwic3VwZXIiLCJ0aGlzIiwic2V0RXJyb3IiLCJzdGF0dXNDb2RlIiwiY2FjaGUiLCJhY3RpdmVNYW5pZmVzdCIsInNvdXJjZXMiLCJoY1ZlcnNpb24iLCJleHRyYWN0VmVyc2lvbiIsImluZGV4T2YiLCJmZXRjaEFuZFByb2Nlc3NTY3JpcHQiLCJzY3JpcHQiLCJmZXRjaGVkTW9kdWxlcyIsInNob3VsZFRocm93RXJyb3IiLCJyZXNwb25zZSIsInVwZGF0ZUNhY2hlIiwiaGlnaGNoYXJ0c09wdGlvbnMiLCJwcm94eU9wdGlvbnMiLCJzb3VyY2VQYXRoIiwicHJveHlBZ2VudCIsIkh0dHBzUHJveHlBZ2VudCIsImFnZW50IiwiYWxsRmV0Y2hQcm9taXNlcyIsImFsbCIsImZldGNoU2NyaXB0cyIsImMiLCJtIiwid3JpdGVGaWxlU3luYyIsImNoZWNrQW5kVXBkYXRlQ2FjaGUiLCJtYW5pZmVzdFBhdGgiLCJyZXF1ZXN0VXBkYXRlIiwibWFuaWZlc3QiLCJtb2R1bGVNYXAiLCJudW1iZXJPZk1vZHVsZXMiLCJzb21lIiwibW9kdWxlTmFtZSIsIm5ld01hbmlmZXN0Iiwic2F2ZUNvbmZpZ1RvTWFuaWZlc3QiLCJnZXRDYWNoZVBhdGgiLCJzZXR1cEhpZ2hjaGFydHMiLCJIaWdoY2hhcnRzIiwiYW5pbU9iamVjdCIsImR1cmF0aW9uIiwidHJpZ2dlckV4cG9ydCIsImNoYXJ0T3B0aW9ucyIsImRpc3BsYXlFcnJvcnMiLCJfZGlzcGxheUVycm9ycyIsIm1lcmdlIiwic2V0T3B0aW9ucyIsIndyYXAiLCJzZXRPcHRpb25zT2JqIiwiY2hhcnQiLCJhbmltYXRpb24iLCJzdHJJbmoiLCJpc1JlbmRlckNvbXBsZXRlIiwiQ2hhcnQiLCJwcm9jZWVkIiwidXNlck9wdGlvbnMiLCJjYiIsImV4cG9ydGluZyIsImVuYWJsZWQiLCJwbG90T3B0aW9ucyIsInNlcmllcyIsImxhYmVsIiwidG9vbHRpcCIsIm9uSGlnaGNoYXJ0c1JlbmRlciIsImFkZEV2ZW50IiwiU2VyaWVzIiwiRnVuY3Rpb24iLCJmaW5hbE9wdGlvbnMiLCJmaW5hbENhbGxiYWNrIiwiZGVmYXVsdE9wdGlvbnMiLCJwcm9wIiwidGVtcGxhdGUiLCJicm93c2VyIiwibmV3UGFnZSIsInBhZ2UiLCJzZXRDYWNoZUVuYWJsZWQiLCJzZXRQYWdlQ29udGVudCIsImlzQ2xvc2VkIiwiJGV2YWwiLCJlbGVtZW50IiwiZXJyb3JNZXNzYWdlIiwiaW5uZXJIVE1MIiwic2V0UGFnZUV2ZW50cyIsImNsZWFyUGFnZVJlc291cmNlcyIsImluamVjdGVkUmVzb3VyY2VzIiwicmVzb3VyY2UiLCJkaXNwb3NlIiwiZXZhbHVhdGUiLCJvbGRDaGFydHMiLCJjaGFydHMiLCJvbGRDaGFydCIsImRlc3Ryb3kiLCJzY3JpcHRzVG9SZW1vdmUiLCJnZXRFbGVtZW50c0J5VGFnTmFtZSIsInN0eWxlc1RvUmVtb3ZlIiwibGlua3NUb1JlbW92ZSIsInJlbW92ZSIsInNldENvbnRlbnQiLCJ3YWl0VW50aWwiLCJhZGRTY3JpcHRUYWciLCJwYXRoIiwic2V0QXNDb25maWciLCJ0b3RhbFNpemUiLCJCdWZmZXIiLCJieXRlTGVuZ3RoIiwidG9GaXhlZCIsInB1cHBldGVlckV4cG9ydCIsImV4cG9ydE9wdGlvbnMiLCJkZWJ1Z2dlciIsImlzU1ZHIiwic3ZnVGVtcGxhdGUiLCJpbmplY3RlZEpzIiwianMiLCJwdXNoIiwiY29udGVudCIsImlzTG9jYWwiLCJqc1Jlc291cmNlIiwiaW5qZWN0ZWRDc3MiLCJjc3MiLCJjc3NJbXBvcnRzIiwibWF0Y2giLCJjc3NJbXBvcnRQYXRoIiwiY3NzUmVzb3VyY2UiLCJhZGRTdHlsZVRhZyIsImFkZFBhZ2VSZXNvdXJjZXMiLCJzaXplIiwic3ZnRWxlbWVudCIsInF1ZXJ5U2VsZWN0b3IiLCJjaGFydEhlaWdodCIsImJhc2VWYWwiLCJjaGFydFdpZHRoIiwiYm9keSIsInN0eWxlIiwiem9vbSIsIm1hcmdpbiIsInZpZXdwb3J0SGVpZ2h0IiwiTWF0aCIsImFicyIsImNlaWwiLCJ2aWV3cG9ydFdpZHRoIiwieCIsInkiLCJnZXRCb3VuZGluZ0NsaWVudFJlY3QiLCJ0cnVuYyIsImdldENsaXBSZWdpb24iLCJzZXRWaWV3cG9ydCIsImRldmljZVNjYWxlRmFjdG9yIiwib3V0ZXJIVE1MIiwiY3JlYXRlU1ZHIiwiZW5jb2RpbmciLCJjbGlwIiwicmFjZSIsInNjcmVlbnNob3QiLCJjYXB0dXJlQmV5b25kVmlld3BvcnQiLCJmdWxsUGFnZSIsIm9wdGltaXplRm9yU3BlZWQiLCJxdWFsaXR5Iiwib21pdEJhY2tncm91bmQiLCJfcmVzb2x2ZSIsInNldFRpbWVvdXQiLCJjcmVhdGVJbWFnZSIsImVtdWxhdGVNZWRpYVR5cGUiLCJwZGYiLCJjcmVhdGVQREYiLCJzdGF0cyIsInBlcmZvcm1lZEV4cG9ydHMiLCJleHBvcnRBdHRlbXB0cyIsImV4cG9ydEZyb21TdmdBdHRlbXB0cyIsInRpbWVTcGVudCIsImRyb3BwZWRFeHBvcnRzIiwic3BlbnRBdmVyYWdlIiwicG9vbENvbmZpZyIsImZhY3RvcnkiLCJjcmVhdGUiLCJpZCIsInV1aWQiLCJzdGFydERhdGUiLCJnZXRUaW1lIiwid29ya0NvdW50IiwicmFuZG9tIiwidmFsaWRhdGUiLCJ3b3JrZXJIYW5kbGUiLCJjbG9zZSIsImluaXRQb29sIiwicHVwcGV0ZWVyQXJncyIsInB1cHBldGVlck9wdGlvbnMiLCJlbmFibGVkRGVidWciLCJkZWJ1Z09wdGlvbnMiLCJsYXVuY2hPcHRpb25zIiwidXNlckRhdGFEaXIiLCJoYW5kbGVTSUdJTlQiLCJoYW5kbGVTSUdURVJNIiwiaGFuZGxlU0lHSFVQIiwid2FpdEZvckluaXRpYWxQYWdlIiwiZGVmYXVsdFZpZXdwb3J0IiwibWF4VHJpZXMiLCJ0cnlDb3VudCIsIm9wZW4iLCJsYXVuY2giLCJjcmVhdGVCcm93c2VyIiwicGFyc2VJbnQiLCJQb29sIiwiYWNxdWlyZVRpbWVvdXRNaWxsaXMiLCJjcmVhdGVUaW1lb3V0TWlsbGlzIiwiZGVzdHJveVRpbWVvdXRNaWxsaXMiLCJpZGxlVGltZW91dE1pbGxpcyIsImNyZWF0ZVJldHJ5SW50ZXJ2YWxNaWxsaXMiLCJyZWFwSW50ZXJ2YWxNaWxsaXMiLCJwcm9wYWdhdGVDcmVhdGVFcnJvciIsInIiLCJoYXJkUmVzZXQiLCJnb3RvIiwiY2xlYXJQYWdlIiwiZXZlbnRJZCIsImluaXRpYWxSZXNvdXJjZXMiLCJhY3F1aXJlIiwicHJvbWlzZSIsInJlbGVhc2UiLCJraWxsUG9vbCIsIndvcmtlciIsInVzZWQiLCJkZXN0cm95ZWQiLCJjb25uZWN0ZWQiLCJjbG9zZUJyb3dzZXIiLCJwb3N0V29yayIsImdldFBvb2xJbmZvIiwiYWNxdWlyZUNvdW50ZXIiLCJwYXlsb2FkIiwicmVxdWVzdElkIiwid29ya1N0YXJ0IiwiZXhwb3J0Q291bnRlciIsInJlc3VsdCIsImV4cG9ydFRpbWUiLCJnZXRQb29sSW5mb0pTT04iLCJudW1GcmVlIiwibnVtVXNlZCIsImF2YWlsYWJsZSIsInBlbmRpbmciLCJudW1QZW5kaW5nQWNxdWlyZXMiLCJwb29sJDEiLCJzdGFydEV4cG9ydCIsInNldHRpbmdzIiwiZW5kQ2FsbGJhY2siLCJzdmciLCJpbml0RXhwb3J0U2V0dGluZ3MiLCJleHBvcnRBc1N0cmluZyIsImlucHV0IiwiZm9yYmlkZGVuIiwiSlNET00iLCJET01QdXJpZnkiLCJzYW5pdGl6ZSIsIkFERF9UQUdTIiwiRk9SQklEX0FUVFIiLCJkb1N0cmFpZ2h0SW5qZWN0IiwiZG9FeHBvcnQiLCJmaW5kQ2hhcnRTaXplIiwicHJlY2lzaW9uIiwibXVsdGlwbGllciIsInBvdyIsInJvdW5kTnVtYmVyIiwic291cmNlSGVpZ2h0Iiwic291cmNlV2lkdGgiLCJwYXJhbSIsImNoYXJ0SnNvbiIsImN1c3RvbUxvZ2ljT3B0aW9ucyIsImFsbG93Q29kZUV4ZWN1dGlvblNjb3BlZCIsIm9wdGlvbnNOYW1lIiwic3RyaW5nVG9FeHBvcnQiLCJjaGFydEpTT04iLCJpbnRlcnZhbElkcyIsImNsZWFyQWxsSW50ZXJ2YWxzIiwiY2xlYXJJbnRlcnZhbCIsImxvZ0Vycm9yTWlkZGxld2FyZSIsInJlcSIsIm5leHQiLCJyZXR1cm5FcnJvck1pZGRsZXdhcmUiLCJzdENvZGUiLCJzdGF0dXMiLCJqc29uIiwicmF0ZUxpbWl0IiwiYXBwIiwibGltaXRDb25maWciLCJtc2ciLCJyYXRlT3B0aW9ucyIsImxpbWl0ZXIiLCJ3aW5kb3dNcyIsImRlbGF5TXMiLCJoYW5kbGVyIiwicmVxdWVzdCIsImZvcm1hdCIsInNlbmQiLCJkZWZhdWx0Iiwic2tpcCIsInF1ZXJ5IiwiYWNjZXNzX3Rva2VuIiwidXNlIiwiSHR0cEVycm9yIiwic2V0U3RhdHVzIiwidlN3aXRjaFJvdXRlIiwicG9zdCIsImFkbWluVG9rZW4iLCJ0b2tlbiIsIm5ld1ZlcnNpb24iLCJwYXJhbXMiLCJ1cGRhdGVWZXJzaW9uIiwicmV2ZXJzZWRNaW1lIiwicG5nIiwianBlZyIsImdpZiIsInJlcXVlc3RzQ291bnRlciIsImJlZm9yZVJlcXVlc3QiLCJhZnRlclJlcXVlc3QiLCJkb0NhbGxiYWNrcyIsImNhbGxiYWNrcyIsInVuaXF1ZUlkIiwiY2FsbFJlc3BvbnNlIiwiZXhwb3J0SGFuZGxlciIsInN0b3BDb3VudGVyIiwidjQiLCJjb25uZWN0aW9uIiwicmVtb3RlQWRkcmVzcyIsImI2NCIsIm5vRG93bmxvYWQiLCJjb25uZWN0aW9uQWJvcnRlZCIsInNvY2tldCIsImhhZEVycm9ycyIsInRvTG93ZXJDYXNlIiwic3Vic3RyIiwicGF0dGVybiIsImlzUHJpdmF0ZVJhbmdlVXJsRm91bmQiLCJpbmZvIiwicmVtb3ZlQWxsTGlzdGVuZXJzIiwiZnJvbSIsImhlYWRlciIsImF0dGFjaG1lbnQiLCJmaWxlbmFtZSIsInBrZ0ZpbGUiLCJwYXRoZXIiLCJzZXJ2ZXJTdGFydFRpbWUiLCJzdWNjZXNzUmF0ZXMiLCJhZGRIZWFsdGhSb3V0ZXMiLCJzZXRJbnRlcnZhbCIsInN1Y2Nlc3NSYXRpbyIsIl8iLCJwZXJpb2QiLCJtb3ZpbmdBdmVyYWdlIiwicmVkdWNlIiwiYSIsImIiLCJib290VGltZSIsInVwdGltZSIsImZsb29yIiwiaGlnaGNoYXJ0c1ZlcnNpb24iLCJhdmVyYWdlUHJvY2Vzc2luZ1RpbWUiLCJmYWlsZWRFeHBvcnRzIiwic3VjZXNzUmF0aW8iLCJzdmdFeHBvcnRBdHRlbXB0cyIsImpzb25FeHBvcnRBdHRlbXB0cyIsImFjdGl2ZVNlcnZlcnMiLCJNYXAiLCJleHByZXNzIiwiZGlzYWJsZSIsImNvcnMiLCJfcmVxIiwic2V0IiwiYXR0YWNoU2VydmVyRXJyb3JIYW5kbGVycyIsInN0YXJ0U2VydmVyIiwic2VydmVyQ29uZmlnIiwidXBsb2FkTGltaXRCeXRlcyIsInN0b3JhZ2UiLCJtdWx0ZXIiLCJtZW1vcnlTdG9yYWdlIiwidXBsb2FkIiwibGltaXRzIiwiZmllbGRTaXplIiwibGltaXQiLCJ1cmxlbmNvZGVkIiwiZXh0ZW5kZWQiLCJub25lIiwiaHR0cFNlcnZlciIsImNyZWF0ZVNlcnZlciIsImxpc3RlbiIsImNlcnQiLCJmc1Byb21pc2VzIiwicmVhZEZpbGUiLCJwb3NpeCIsImh0dHBzU2VydmVyIiwiTmFOIiwic3RhdGljIiwiaGVhbHRoUm91dGUiLCJleHBvcnRSb3V0ZXMiLCJfcmVxdWVzdCIsInNlbmRGaWxlIiwiYWNjZXB0UmFuZ2VzIiwidWlSb3V0ZSIsImVycm9ySGFuZGxlciIsImNsb3NlU2VydmVycyIsImRlbGV0ZSIsImdldFNlcnZlcnMiLCJlbmFibGVSYXRlTGltaXRpbmciLCJnZXRFeHByZXNzIiwiZ2V0QXBwIiwibWlkZGxld2FyZXMiLCJzaHV0ZG93bkNsZWFuVXAiLCJleGl0Q29kZSIsImFsbFNldHRsZWQiLCJleGl0IiwiaW5kZXgiLCJpbml0RXhwb3J0IiwibG9nZ2luZ09wdGlvbnMiLCJpbml0TG9nZ2luZyIsImNvZGUiLCJzaW5nbGVFeHBvcnQiLCJiYXRjaEV4cG9ydCIsImJhdGNoRnVuY3Rpb25zIiwicGFpciIsImNvbmZpZ0luZGV4IiwiZmluZEluZGV4IiwiYXJnIiwiZmlsZU5hbWUiLCJsb2FkQ29uZmlnRmlsZSIsInNob3dVc2FnZSIsInByb3BlcnRpZXNDaGFpbiIsImFyZ3VtZW50VHlwZSIsInBhaXJBcmd1bWVudFZhbHVlIiwibWFwVG9OZXdDb25maWciLCJvbGRPcHRpb25zIiwibWFudWFsQ29uZmlnIiwiY29uZmlnRmlsZU5hbWUiLCJjb25maWdGaWxlIiwiY2hvaWNlIiwicHJvbXB0cyIsIm9uU3VibWl0IiwicCIsImNhdGVnb3JpZXMiLCJxdWVzdGlvbnNDb3VudGVyIiwiYWxsUXVlc3Rpb25zIiwic2VjdGlvbiIsInByb21wdCIsImFuc3dlciIsIm1vZHVsZSIsInByb21pc2VzIiwid3JpdGVGaWxlIiwicHJpbnRMb2dvIiwicGFja2FnZVZlcnNpb24iXSwibWFwcGluZ3MiOiIrY0FlTyxNQUFNQSxFQUFlLENBQzFCQyxLQUFNLENBQUMsYUFBYyxrQkFBbUIsaUJBQ3hDQyxRQUFTLENBQ1AsUUFDQSxNQUNBLFFBQ0EsWUFDQSx1QkFDQSxnQkFFQSxlQUNBLFFBQ0EsT0FDQSxhQUNBLG1CQUNBLGVBQ0EsY0FDQSxVQUNBLFVBQ0EsY0FDQSxXQUNBLFVBQ0EsWUFDQSxjQUNBLFlBQ0Esc0JBQ0EsU0FDQSxTQUNBLFdBQ0EsYUFDQSxZQUNBLGVBQ0EseUJBQ0EsU0FDQSxlQUNBLFlBQ0Esa0JBQ0EsU0FDQSxjQUNBLG1CQUNBLGVBQ0Esa0JBQ0EsY0FDQSxlQUVBLGNBQ0EsV0FDQSxlQUNBLFdBQ0EsU0FDQSxPQUNBLFdBQ0EsWUFDQSxTQUNBLHFCQUNBLGFBQ0EsV0FDQSxXQUNBLFdBQ0EsV0FDQSxlQUNBLFVBQ0Esa0JBQ0Esb0JBQ0EsYUFDQSxVQUNBLGNBQ0EsWUFDQSxZQUVGQyxXQUFZLENBQUMsa0JBQ2JDLE9BQVEsQ0FDTix3RUFDQSxtR0FNU0MsRUFBZ0IsQ0FDM0JDLFVBQVcsQ0FDVEMsS0FBTSxDQUNKQyxNQUFPLENBQ0wsbUNBQ0Es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 +"use strict";require("colors");var e=require("fs"),t=require("path"),r=require("https-proxy-agent"),o=require("prompts"),i=require("dotenv"),s=require("zod"),n=require("url"),a=require("http"),l=require("https"),c=require("tarn"),p=require("uuid"),h=require("puppeteer"),u=require("jsdom"),d=require("dompurify"),g=require("cors"),m=require("express"),f=require("multer"),v=require("express-rate-limit"),y="undefined"!=typeof document?document.currentScript:null;const b={core:["highcharts","highcharts-more","highcharts-3d"],modules:["stock","map","gantt","exporting","parallel-coordinates","accessibility","boost-canvas","boost","data","data-tools","draggable-points","static-scale","broken-axis","heatmap","tilemap","tiledwebmap","timeline","treemap","treegraph","item-series","drilldown","histogram-bellcurve","bullet","funnel","funnel3d","geoheatmap","pyramid3d","networkgraph","overlapping-datalabels","pareto","pattern-fill","pictorial","price-indicator","sankey","arc-diagram","dependency-wheel","series-label","series-on-point","solid-gauge","sonification","streamgraph","sunburst","variable-pie","variwide","vector","venn","windbarb","wordcloud","xrange","no-data-to-display","drag-panes","debugger","dumbbell","lollipop","cylinder","organization","dotplot","marker-clusters","hollowcandlestick","heikinashi","flowmap","export-data","navigator","textpath"],indicators:["indicators-all"],custom:["https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.30.1/moment.min.js","https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.45/moment-timezone-with-data.min.js"]},w={puppeteer:{args:{value:["--allow-running-insecure-content","--ash-no-nudges","--autoplay-policy=user-gesture-required","--block-new-web-contents","--disable-accelerated-2d-canvas","--disable-background-networking","--disable-background-timer-throttling","--disable-backgrounding-occluded-windows","--disable-breakpad","--disable-checker-imaging","--disable-client-side-phishing-detection","--disable-component-extensions-with-background-pages","--disable-component-update","--disable-default-apps","--disable-dev-shm-usage","--disable-domain-reliability","--disable-extensions","--disable-features=CalculateNativeWinOcclusion,InterestFeedContentSuggestions,WebOTP","--disable-hang-monitor","--disable-ipc-flooding-protection","--disable-logging","--disable-notifications","--disable-offer-store-unmasked-wallet-cards","--disable-popup-blocking","--disable-print-preview","--disable-prompt-on-repost","--disable-renderer-backgrounding","--disable-search-engine-choice-screen","--disable-session-crashed-bubble","--disable-setuid-sandbox","--disable-site-isolation-trials","--disable-speech-api","--disable-sync","--enable-unsafe-webgpu","--hide-crash-restore-bubble","--hide-scrollbars","--metrics-recording-only","--mute-audio","--no-default-browser-check","--no-first-run","--no-pings","--pipe","--no-startup-window","--password-store=basic","--process-per-tab","--use-mock-keychain"],type:"string[]",description:"Arguments array to send to Puppeteer."},tempDir:{value:"./tmp/",type:"string",envLink:"PUPPETEER_TEMP_DIR",description:"The directory for Puppeteer to store temporary files."}},highcharts:{version:{value:"latest",type:"string",envLink:"HIGHCHARTS_VERSION",description:"The Highcharts version to be used."},cdnURL:{value:"https://code.highcharts.com/",type:"string",envLink:"HIGHCHARTS_CDN_URL",description:"The CDN URL for Highcharts scripts to be used."},coreScripts:{value:b.core,type:"string[]",envLink:"HIGHCHARTS_CORE_SCRIPTS",description:"The core Highcharts scripts to fetch."},moduleScripts:{value:b.modules,type:"string[]",envLink:"HIGHCHARTS_MODULE_SCRIPTS",description:"The modules of Highcharts to fetch."},indicatorScripts:{value:b.indicators,type:"string[]",envLink:"HIGHCHARTS_INDICATOR_SCRIPTS",description:"The indicators of Highcharts to fetch."},customScripts:{value:b.custom,type:"string[]",description:"Additional custom scripts or dependencies to fetch."},forceFetch:{value:!1,type:"boolean",envLink:"HIGHCHARTS_FORCE_FETCH",description:"The flag to determine whether to refetch all scripts after each server rerun."},cachePath:{value:".cache",type:"string",envLink:"HIGHCHARTS_CACHE_PATH",description:"The path to the cache directory. It is used to store the Highcharts scripts and custom scripts."}},export:{infile:{value:!1,type:"string",description:"The input file should include a name and a type (json or svg). It must be correctly formatted as a JSON or SVG file."},instr:{value:!1,type:"string",description:"Input, provided in the form of a stringified JSON or SVG file, will override the --infile option."},options:{value:!1,type:"string",description:"An alias for the --instr option."},outfile:{value:!1,type:"string",description:"The output filename along with a type (jpeg, png, pdf, or svg). This will ignore the --type flag."},type:{value:"png",type:"string",envLink:"EXPORT_TYPE",description:"The file export format. It can be jpeg, png, pdf, or svg."},constr:{value:"chart",type:"string",envLink:"EXPORT_CONSTR",description:"The constructor to use. Can be chart, stockChart, mapChart, or ganttChart."},defaultHeight:{value:400,type:"number",envLink:"EXPORT_DEFAULT_HEIGHT",description:"the default height of the exported chart. Used when no value is set."},defaultWidth:{value:600,type:"number",envLink:"EXPORT_DEFAULT_WIDTH",description:"The default width of the exported chart. Used when no value is set."},defaultScale:{value:1,type:"number",envLink:"EXPORT_DEFAULT_SCALE",description:"The default scale of the exported chart. Used when no value is set."},height:{value:!1,type:"number",description:"The height of the exported chart, overriding the option in the chart settings."},width:{value:!1,type:"number",description:"The width of the exported chart, overriding the option in the chart settings."},scale:{value:!1,type:"number",description:"The scale of the exported chart, overriding the option in the chart settings. Ranges between 0.1 and 5.0."},globalOptions:{value:!1,type:"string",description:"Either a stringified JSON or a filename containing options to be passed into the Highcharts.setOptions."},themeOptions:{value:!1,type:"string",description:"Either a stringified JSON or a filename containing theme options to be passed into the Highcharts.setOptions."},batch:{value:!1,type:"string",description:'Initiates a batch job with a string containing input/output pairs: "in=out;in=out;...".'},rasterizationTimeout:{value:1500,type:"number",envLink:"EXPORT_RASTERIZATION_TIMEOUT",description:"The duration in milliseconds to wait for rendering a webpage."}},customLogic:{allowCodeExecution:{value:!1,type:"boolean",envLink:"CUSTOM_LOGIC_ALLOW_CODE_EXECUTION",description:"Controls whether the execution of arbitrary code is allowed during the exporting process."},allowFileResources:{value:!1,type:"boolean",envLink:"CUSTOM_LOGIC_ALLOW_FILE_RESOURCES",description:"Controls the ability to inject resources from the filesystem. This setting has no effect when running as a server."},customCode:{value:!1,type:"string",description:"Custom code to execute before chart initialization. It can be a function, code wrapped within a function, or a filename with the .js extension."},callback:{value:!1,type:"string",description:"JavaScript code to run during construction. It can be a function or a filename with the .js extension."},resources:{value:!1,type:"string",description:"Additional resource in the form of a stringified JSON, which may contain files, js, and css sections."},loadConfig:{value:!1,type:"string",legacyName:"fromFile",description:"A file containing a pre-defined configuration to use."},createConfig:{value:!1,type:"string",description:"Enables setting options through a prompt and saving them in a provided config file."}},server:{maxUploadSize:{value:3,type:"number",envLink:"SERVER_MAX_UPLOAD_SIZE",description:"The maximum upload size, in MB, for the server."},enable:{value:!1,type:"boolean",envLink:"SERVER_ENABLE",cliName:"enableServer",description:"When set to true, the server starts on the local IP address 0.0.0.0."},host:{value:"0.0.0.0",type:"string",envLink:"SERVER_HOST",description:"The hostname of the server. Additionally, it starts a server on the provided hostname."},port:{value:7801,type:"number",envLink:"SERVER_PORT",description:"The server port when enabled."},benchmarking:{value:!1,type:"boolean",envLink:"SERVER_BENCHMARKING",cliName:"serverBenchmarking",description:"Indicates whether to display the duration, in milliseconds, of specific actions that occur on the server while serving a request."},proxy:{host:{value:!1,type:"string",envLink:"SERVER_PROXY_HOST",cliName:"proxyHost",description:"The host of the proxy server to use, if it exists."},port:{value:8080,type:"number",envLink:"SERVER_PROXY_PORT",cliName:"proxyPort",description:"The port of the proxy server to use, if it exists."},username:{value:!1,type:"string",envLink:"SERVER_PROXY_USERNAME",cliName:"proxyUsername",description:"The username for the proxy server, if it exists."},password:{value:!1,type:"string",envLink:"SERVER_PROXY_PASSWORD",cliName:"proxyPassword",description:"The password for the proxy server, if it exists."},timeout:{value:5e3,type:"number",envLink:"SERVER_PROXY_TIMEOUT",cliName:"proxyTimeout",description:"The timeout for the proxy server to use, if it exists."}},rateLimiting:{enable:{value:!1,type:"boolean",envLink:"SERVER_RATE_LIMITING_ENABLE",cliName:"enableRateLimiting",description:"Enables rate limiting for the server."},maxRequests:{value:10,type:"number",envLink:"SERVER_RATE_LIMITING_MAX_REQUESTS",legacyName:"rateLimit",description:"The maximum number of requests allowed in one minute."},window:{value:1,type:"number",envLink:"SERVER_RATE_LIMITING_WINDOW",description:"The time window, in minutes, for the rate limiting."},delay:{value:0,type:"number",envLink:"SERVER_RATE_LIMITING_DELAY",description:"The delay duration for each successive request before reaching the maximum limit."},trustProxy:{value:!1,type:"boolean",envLink:"SERVER_RATE_LIMITING_TRUST_PROXY",description:"Set this to true if the server is behind a load balancer."},skipKey:{value:!1,type:"string",envLink:"SERVER_RATE_LIMITING_SKIP_KEY",description:"Allows bypassing the rate limiter and should be provided with the skipToken argument."},skipToken:{value:!1,type:"string",envLink:"SERVER_RATE_LIMITING_SKIP_TOKEN",description:"Allows bypassing the rate limiter and should be provided with the skipKey argument."}},ssl:{enable:{value:!1,type:"boolean",envLink:"SERVER_SSL_ENABLE",cliName:"enableSsl",description:"Enables or disables the SSL protocol."},force:{value:!1,type:"boolean",envLink:"SERVER_SSL_FORCE",cliName:"sslForce",legacyName:"sslOnly",description:"When set to true, the server is forced to serve only over HTTPS."},port:{value:443,type:"number",envLink:"SERVER_SSL_PORT",cliName:"sslPort",description:"The port on which to run the SSL server."},certPath:{value:!1,type:"string",envLink:"SERVER_SSL_CERT_PATH",legacyName:"sslPath",description:"The path to the SSL certificate/key file."}}},pool:{minWorkers:{value:4,type:"number",envLink:"POOL_MIN_WORKERS",description:"The number of minimum and initial pool workers to spawn."},maxWorkers:{value:8,type:"number",envLink:"POOL_MAX_WORKERS",legacyName:"workers",description:"The number of maximum pool workers to spawn."},workLimit:{value:40,type:"number",envLink:"POOL_WORK_LIMIT",description:"The number of work pieces that can be performed before restarting the worker process."},acquireTimeout:{value:5e3,type:"number",envLink:"POOL_ACQUIRE_TIMEOUT",description:"The duration, in milliseconds, to wait for acquiring a resource."},createTimeout:{value:5e3,type:"number",envLink:"POOL_CREATE_TIMEOUT",description:"The duration, in milliseconds, to wait for creating a resource."},destroyTimeout:{value:5e3,type:"number",envLink:"POOL_DESTROY_TIMEOUT",description:"The duration, in milliseconds, to wait for destroying a resource."},idleTimeout:{value:3e4,type:"number",envLink:"POOL_IDLE_TIMEOUT",description:"The duration, in milliseconds, after which an idle resource is destroyed."},createRetryInterval:{value:200,type:"number",envLink:"POOL_CREATE_RETRY_INTERVAL",description:"The duration, in milliseconds, to wait before retrying the create process in case of a failure."},reaperInterval:{value:1e3,type:"number",envLink:"POOL_REAPER_INTERVAL",description:"The duration, in milliseconds, after which the check for idle resources to destroy is triggered."},benchmarking:{value:!1,type:"boolean",envLink:"POOL_BENCHMARKING",cliName:"poolBenchmarking",description:"Indicate whether to show statistics for the pool of resources or not."}},logging:{level:{value:4,type:"number",envLink:"LOGGING_LEVEL",cliName:"logLevel",description:"The logging level to be used."},file:{value:"highcharts-export-server.log",type:"string",envLink:"LOGGING_FILE",cliName:"logFile",description:"The name of a log file. The `logToFile` and `logDest` options also need to be set to enable file logging."},dest:{value:"log/",type:"string",envLink:"LOGGING_DEST",cliName:"logDest",description:"The path to store log files. The `logToFile` option also needs to be set to enable file logging."},toConsole:{value:!0,type:"boolean",envLink:"LOGGING_TO_CONSOLE",cliName:"logToConsole",description:"Enables or disables showing logs in the console."},toFile:{value:!0,type:"boolean",envLink:"LOGGING_TO_FILE",cliName:"logToFile",description:"Enables or disables creation of the log directory and saving the log into a .log file."}},ui:{enable:{value:!1,type:"boolean",envLink:"UI_ENABLE",cliName:"enableUi",description:"Enables or disables the user interface (UI) for the export server."},route:{value:"/",type:"string",envLink:"UI_ROUTE",cliName:"uiRoute",description:"The endpoint route to which the user interface (UI) should be attached."}},other:{nodeEnv:{value:"production",type:"string",envLink:"OTHER_NODE_ENV",description:"The type of Node.js environment."},listenToProcessExits:{value:!0,type:"boolean",envLink:"OTHER_LISTEN_TO_PROCESS_EXITS",description:"Decides whether or not to attach process.exit handlers."},noLogo:{value:!1,type:"boolean",envLink:"OTHER_NO_LOGO",description:"Skip printing the logo on a startup. Will be replaced by a simple text."},hardResetPage:{value:!1,type:"boolean",envLink:"OTHER_HARD_RESET_PAGE",description:"Decides if the page content should be reset entirely."},browserShellMode:{value:!0,type:"boolean",envLink:"OTHER_BROWSER_SHELL_MODE",description:"Decides if the browser runs in the shell mode."}},debug:{enable:{value:!1,type:"boolean",envLink:"DEBUG_ENABLE",cliName:"enableDebug",description:"Enables or disables debug mode for the underlying browser."},headless:{value:!0,type:"boolean",envLink:"DEBUG_HEADLESS",description:"Controls the mode in which the browser is launched when in the debug mode."},devtools:{value:!1,type:"boolean",envLink:"DEBUG_DEVTOOLS",description:"Decides whether to enable DevTools when the browser is in a headful state."},listenToConsole:{value:!1,type:"boolean",envLink:"DEBUG_LISTEN_TO_CONSOLE",description:"Decides whether to enable a listener for console messages sent from the browser."},dumpio:{value:!1,type:"boolean",envLink:"DEBUG_DUMPIO",description:"Redirects browser process stdout and stderr to process.stdout and process.stderr."},slowMo:{value:0,type:"number",envLink:"DEBUG_SLOW_MO",description:"Slows down Puppeteer operations by the specified number of milliseconds."},debuggingPort:{value:9222,type:"number",envLink:"DEBUG_DEBUGGING_PORT",description:"Specifies the debugging port."}}},E={puppeteer:[{type:"list",name:"args",message:"Puppeteer arguments",initial:w.puppeteer.args.value.join(","),separator:","}],highcharts:[{type:"text",name:"version",message:"Highcharts version",initial:w.highcharts.version.value},{type:"text",name:"cdnURL",message:"The URL of CDN",initial:w.highcharts.cdnURL.value},{type:"multiselect",name:"coreScripts",message:"Available core scripts",instructions:"Space: Select specific, A: Select all, Enter: Confirm.",choices:w.highcharts.coreScripts.value},{type:"multiselect",name:"moduleScripts",message:"Available module scripts",instructions:"Space: Select specific, A: Select all, Enter: Confirm.",choices:w.highcharts.moduleScripts.value},{type:"multiselect",name:"indicatorScripts",message:"Available indicator scripts",instructions:"Space: Select specific, A: Select all, Enter: Confirm.",choices:w.highcharts.indicatorScripts.value},{type:"list",name:"customScripts",message:"Custom scripts",initial:w.highcharts.customScripts.value.join(","),separator:","},{type:"toggle",name:"forceFetch",message:"Force re-fetch the scripts",initial:w.highcharts.forceFetch.value},{type:"text",name:"cachePath",message:"The path to the cache directory",initial:w.highcharts.cachePath.value}],export:[{type:"select",name:"type",message:"The default export file type",hint:`Default: ${w.export.type.value}`,initial:0,choices:["png","jpeg","pdf","svg"]},{type:"select",name:"constr",message:"The default constructor for Highcharts",hint:`Default: ${w.export.constr.value}`,initial:0,choices:["chart","stockChart","mapChart","ganttChart"]},{type:"number",name:"defaultHeight",message:"The default fallback height of the exported chart",initial:w.export.defaultHeight.value},{type:"number",name:"defaultWidth",message:"The default fallback width of the exported chart",initial:w.export.defaultWidth.value},{type:"number",name:"defaultScale",message:"The default fallback scale of the exported chart",initial:w.export.defaultScale.value,min:.1,max:5},{type:"number",name:"rasterizationTimeout",message:"The rendering webpage timeout in milliseconds",initial:w.export.rasterizationTimeout.value}],customLogic:[{type:"toggle",name:"allowCodeExecution",message:"Enable execution of custom code",initial:w.customLogic.allowCodeExecution.value},{type:"toggle",name:"allowFileResources",message:"Enable file resources",initial:w.customLogic.allowFileResources.value}],server:[{type:"toggle",name:"enable",message:"Starts the server on 0.0.0.0",initial:w.server.enable.value},{type:"text",name:"host",message:"Server hostname",initial:w.server.host.value},{type:"number",name:"port",message:"Server port",initial:w.server.port.value},{type:"toggle",name:"benchmarking",message:"Enable server benchmarking",initial:w.server.benchmarking.value},{type:"text",name:"proxy.host",message:"The host of the proxy server to use",initial:w.server.proxy.host.value},{type:"number",name:"proxy.port",message:"The port of the proxy server to use",initial:w.server.proxy.port.value},{type:"number",name:"proxy.timeout",message:"The timeout for the proxy server to use",initial:w.server.proxy.timeout.value},{type:"toggle",name:"rateLimiting.enable",message:"Enable rate limiting",initial:w.server.rateLimiting.enable.value},{type:"number",name:"rateLimiting.maxRequests",message:"The maximum requests allowed per minute",initial:w.server.rateLimiting.maxRequests.value},{type:"number",name:"rateLimiting.window",message:"The rate-limiting time window in minutes",initial:w.server.rateLimiting.window.value},{type:"number",name:"rateLimiting.delay",message:"The delay for each successive request before reaching the maximum",initial:w.server.rateLimiting.delay.value},{type:"toggle",name:"rateLimiting.trustProxy",message:"Set to true if behind a load balancer",initial:w.server.rateLimiting.trustProxy.value},{type:"text",name:"rateLimiting.skipKey",message:"Allows bypassing the rate limiter when provided with the skipToken argument",initial:w.server.rateLimiting.skipKey.value},{type:"text",name:"rateLimiting.skipToken",message:"Allows bypassing the rate limiter when provided with the skipKey argument",initial:w.server.rateLimiting.skipToken.value},{type:"toggle",name:"ssl.enable",message:"Enable SSL protocol",initial:w.server.ssl.enable.value},{type:"toggle",name:"ssl.force",message:"Force serving only over HTTPS",initial:w.server.ssl.force.value},{type:"number",name:"ssl.port",message:"SSL server port",initial:w.server.ssl.port.value},{type:"text",name:"ssl.certPath",message:"The path to find the SSL certificate/key",initial:w.server.ssl.certPath.value}],pool:[{type:"number",name:"minWorkers",message:"The initial number of workers to spawn",initial:w.pool.minWorkers.value},{type:"number",name:"maxWorkers",message:"The maximum number of workers to spawn",initial:w.pool.maxWorkers.value},{type:"number",name:"workLimit",message:"The pieces of work that can be performed before restarting a Puppeteer process",initial:w.pool.workLimit.value},{type:"number",name:"acquireTimeout",message:"The number of milliseconds to wait for acquiring a resource",initial:w.pool.acquireTimeout.value},{type:"number",name:"createTimeout",message:"The number of milliseconds to wait for creating a resource",initial:w.pool.createTimeout.value},{type:"number",name:"destroyTimeout",message:"The number of milliseconds to wait for destroying a resource",initial:w.pool.destroyTimeout.value},{type:"number",name:"idleTimeout",message:"The number of milliseconds after an idle resource is destroyed",initial:w.pool.idleTimeout.value},{type:"number",name:"createRetryInterval",message:"The retry interval in milliseconds after a create process fails",initial:w.pool.createRetryInterval.value},{type:"number",name:"reaperInterval",message:"The reaper interval in milliseconds after triggering the check for idle resources to destroy",initial:w.pool.reaperInterval.value},{type:"toggle",name:"benchmarking",message:"Enable benchmarking for a resource pool",initial:w.pool.benchmarking.value}],logging:[{type:"number",name:"level",message:"The log level (0: silent, 1: error, 2: warning, 3: notice, 4: verbose, 5: benchmark)",initial:w.logging.level.value,round:0,min:0,max:5},{type:"text",name:"file",message:"A log file name. Set with --toFile and --logDest to enable file logging",initial:w.logging.file.value},{type:"text",name:"dest",message:"The path to a log file when the file logging is enabled",initial:w.logging.dest.value},{type:"toggle",name:"toConsole",message:"Enable logging to the console",initial:w.logging.toConsole.value},{type:"toggle",name:"toFile",message:"Enables logging to a file",initial:w.logging.toFile.value}],ui:[{type:"toggle",name:"enable",message:"Enable UI for the export server",initial:w.ui.enable.value},{type:"text",name:"route",message:"A route to attach the UI",initial:w.ui.route.value}],other:[{type:"text",name:"nodeEnv",message:"The type of Node.js environment",initial:w.other.nodeEnv.value},{type:"toggle",name:"listenToProcessExits",message:"Set to false to skip attaching process.exit handlers",initial:w.other.listenToProcessExits.value},{type:"toggle",name:"noLogo",message:"Skip printing the logo on startup. Replaced by simple text",initial:w.other.noLogo.value},{type:"toggle",name:"hardResetPage",message:"Decides if the page content should be reset entirely",initial:w.other.hardResetPage.value},{type:"toggle",name:"browserShellMode",message:"Decides if the browser runs in the shell mode",initial:w.other.browserShellMode.value}],debug:[{type:"toggle",name:"enable",message:"Enables debug mode for the browser instance",initial:w.debug.enable.value},{type:"toggle",name:"headless",message:"The mode setting for the browser",initial:w.debug.headless.value},{type:"toggle",name:"devtools",message:"The DevTools for the headful browser",initial:w.debug.devtools.value},{type:"toggle",name:"listenToConsole",message:"The event listener for console messages from the browser",initial:w.debug.listenToConsole.value},{type:"toggle",name:"dumpio",message:"Redirects the browser stdout and stderr to NodeJS process",initial:w.debug.dumpio.value},{type:"number",name:"slowMo",message:"Puppeteer operations slow down in milliseconds",initial:w.debug.slowMo.value},{type:"number",name:"debuggingPort",message:"The port number for debugging",initial:w.debug.debuggingPort.value}]},T=["options","globalOptions","themeOptions","resources","payload"],S={},x=(e,t="")=>{Object.keys(e).forEach(r=>{if(!["puppeteer","highcharts"].includes(r)){const o=e[r];void 0===o.value?x(o,`${t}.${r}`):(S[o.cliName||r]=`${t}.${r}`.substring(1),void 0!==o.legacyName&&(S[o.legacyName]=`${t}.${r}`.substring(1)))}})};x(w),i.config();const R=e=>s.z.string().transform(t=>t.split(",").map(e=>e.trim()).filter(t=>e.includes(t))).transform(e=>e.length?e:void 0),_=()=>s.z.enum(["true","false",""]).transform(e=>""!==e?"true"===e:void 0),O=e=>s.z.enum([...e,""]).transform(e=>""!==e?e:void 0),L=()=>s.z.string().trim().refine(e=>!["false","undefined","null","NaN"].includes(e)||""===e,e=>({message:`The string contains forbidden values, received '${e}'`})).transform(e=>""!==e?e:void 0),k=()=>s.z.string().trim().refine(e=>/^(\.\/|\.\.\/|\/|[a-zA-Z]:\\|[a-zA-Z]:\/)?((?:[\w-]+)[\\/]?)+$/.test(e),{},{message:"The string is an invalid path directory string."}),I=()=>s.z.string().trim().refine(e=>""===e||!isNaN(parseFloat(e))&&parseFloat(e)>0,e=>({message:`The value must be numeric and positive, received '${e}'`})).transform(e=>""!==e?parseFloat(e):void 0),C=()=>s.z.string().trim().refine(e=>""===e||!isNaN(parseFloat(e))&&parseFloat(e)>=0,e=>({message:`The value must be numeric and non-negative, received '${e}'`})).transform(e=>""!==e?parseFloat(e):void 0),N=s.z.object({PUPPETEER_TEMP_DIR:k(),HIGHCHARTS_VERSION:s.z.string().trim().refine(e=>/^(latest|\d+(\.\d+){0,2})$/.test(e)||""===e,e=>({message:`HIGHCHARTS_VERSION must be 'latest', a major version, or in the form XX.YY.ZZ, received '${e}'`})).transform(e=>""!==e?e:void 0),HIGHCHARTS_CDN_URL:s.z.string().trim().refine(e=>e.startsWith("https://")||e.startsWith("http://")||""===e,e=>({message:`Invalid value for HIGHCHARTS_CDN_URL. It should start with http:// or https://, received '${e}'`})).transform(e=>""!==e?e:void 0),HIGHCHARTS_CORE_SCRIPTS:R(b.core),HIGHCHARTS_MODULE_SCRIPTS:R(b.modules),HIGHCHARTS_INDICATOR_SCRIPTS:R(b.indicators),HIGHCHARTS_FORCE_FETCH:_(),HIGHCHARTS_CACHE_PATH:L(),HIGHCHARTS_ADMIN_TOKEN:L(),EXPORT_TYPE:O(["jpeg","png","pdf","svg"]),EXPORT_CONSTR:O(["chart","stockChart","mapChart","ganttChart"]),EXPORT_DEFAULT_HEIGHT:I(),EXPORT_DEFAULT_WIDTH:I(),EXPORT_DEFAULT_SCALE:I(),EXPORT_RASTERIZATION_TIMEOUT:C(),CUSTOM_LOGIC_ALLOW_CODE_EXECUTION:_(),CUSTOM_LOGIC_ALLOW_FILE_RESOURCES:_(),SERVER_ENABLE:_(),SERVER_HOST:L(),SERVER_PORT:I(),SERVER_MAX_UPLOAD_SIZE:I(),SERVER_BENCHMARKING:_(),SERVER_PROXY_HOST:L(),SERVER_PROXY_PORT:I(),SERVER_PROXY_USERNAME:L(),SERVER_PROXY_PASSWORD:L(),SERVER_PROXY_TIMEOUT:C(),SERVER_RATE_LIMITING_ENABLE:_(),SERVER_RATE_LIMITING_MAX_REQUESTS:C(),SERVER_RATE_LIMITING_WINDOW:C(),SERVER_RATE_LIMITING_DELAY:C(),SERVER_RATE_LIMITING_TRUST_PROXY:_(),SERVER_RATE_LIMITING_SKIP_KEY:L(),SERVER_RATE_LIMITING_SKIP_TOKEN:L(),SERVER_SSL_ENABLE:_(),SERVER_SSL_FORCE:_(),SERVER_SSL_PORT:I(),SERVER_SSL_CERT_PATH:L(),POOL_MIN_WORKERS:C(),POOL_MAX_WORKERS:C(),POOL_WORK_LIMIT:I(),POOL_ACQUIRE_TIMEOUT:C(),POOL_CREATE_TIMEOUT:C(),POOL_DESTROY_TIMEOUT:C(),POOL_IDLE_TIMEOUT:C(),POOL_CREATE_RETRY_INTERVAL:C(),POOL_REAPER_INTERVAL:C(),POOL_BENCHMARKING:_(),LOGGING_LEVEL:s.z.string().trim().refine(e=>""===e||!isNaN(parseFloat(e))&&parseFloat(e)>=0&&parseFloat(e)<=5,e=>({message:`Invalid value for LOGGING_LEVEL. We only accept values from 0 to 5 as logging levels, received '${e}'`})).transform(e=>""!==e?parseFloat(e):void 0),LOGGING_FILE:L(),LOGGING_DEST:L(),LOGGING_TO_CONSOLE:_(),LOGGING_TO_FILE:_(),UI_ENABLE:_(),UI_ROUTE:L(),OTHER_NODE_ENV:O(["development","production","test"]),OTHER_LISTEN_TO_PROCESS_EXITS:_(),OTHER_NO_LOGO:_(),OTHER_HARD_RESET_PAGE:_(),OTHER_BROWSER_SHELL_MODE:_(),OTHER_ALLOW_XLINK:_(),DEBUG_ENABLE:_(),DEBUG_HEADLESS:_(),DEBUG_DEVTOOLS:_(),DEBUG_LISTEN_TO_CONSOLE:_(),DEBUG_DUMPIO:_(),DEBUG_SLOW_MO:C(),DEBUG_DEBUGGING_PORT:I()}).partial().parse(process.env),A=["red","yellow","blue","gray","green"];let P={toConsole:!0,toFile:!1,pathCreated:!1,levelsDesc:[{title:"error",color:A[0]},{title:"warning",color:A[1]},{title:"notice",color:A[2]},{title:"verbose",color:A[3]},{title:"benchmark",color:A[4]}],listeners:[]};const H=(t,r)=>{P.pathCreated||(!e.existsSync(P.dest)&&e.mkdirSync(P.dest),P.pathCreated=!0),e.appendFile(`${P.dest}${P.file}`,[r].concat(t).join(" ")+"\n",e=>{e&&(console.log(`[logger] Unable to write to log file: ${e}`),P.toFile=!1)})},$=(...e)=>{const[t,...r]=e,{levelsDesc:o,level:i}=P;if(5!==t&&(0===t||t>i||i>o.length))return;const s=`${(new Date).toString().split("(")[0].trim()} [${o[t-1].title}] -`;P.listeners.forEach(e=>{e(s,r.join(" "))}),P.toConsole&&console.log.apply(void 0,[s.toString()[P.levelsDesc[t-1].color]].concat(r)),P.toFile&&H(r,s)},D=(e,t,r)=>{const o=r||t.message,{level:i,levelsDesc:s}=P;if(0===e||e>i||i>s.length)return;const n=`${(new Date).toString().split("(")[0].trim()} [${s[e-1].title}] -`,a=t.message!==t.stackMessage||void 0===t.stackMessage?t.stack:t.stack.split("\n").slice(1).join("\n"),l=[o,"\n",a];P.toConsole&&console.log.apply(void 0,[n.toString()[P.levelsDesc[e-1].color]].concat([o[A[e-1]],"\n",a])),P.listeners.forEach(e=>{e(n,l.join(" "))}),P.toFile&&H(l,n)},U=e=>{e>=0&&e<=P.levelsDesc.length&&(P.level=e)},G=(e,t)=>{if(P={...P,dest:e||P.dest,file:t||P.file,toFile:!0},0===P.dest.length)return $(1,"[logger] File logging initialization: no path supplied.");P.dest.endsWith("/")||(P.dest+="/")},F=n.fileURLToPath(new URL("../.","undefined"==typeof document?require("url").pathToFileURL(__filename).href:y&&"SCRIPT"===y.tagName.toUpperCase()&&y.src||new URL("index.cjs",document.baseURI).href)),j=(e,t)=>{const r=["png","jpeg","pdf","svg"];if(t){const o=t.split(".").pop();"jpg"===o?e="jpeg":r.includes(o)&&e!==o&&(e=o)}return{"image/png":"png","image/jpeg":"jpeg","application/pdf":"pdf","image/svg+xml":"svg"}[e]||r.find(t=>t===e)||"png"},M=(t=!1,r)=>{const o=["js","css","files"];let i=t,s=!1;if(r&&t.endsWith(".json"))try{i=V(e.readFileSync(t,"utf8"))}catch(e){return D(2,e,"[cli] No resources found.")}else i=V(t),i&&!r&&delete i.files;for(const e in i)o.includes(e)?s||(s=!0):delete i[e];return s?(i.files&&(i.files=i.files.map(e=>e.trim()),(!i.files||i.files.length<=0)&&delete i.files),i):$(3,"[cli] No resources found.")};function V(e,t){try{const r=JSON.parse("string"!=typeof e?JSON.stringify(e):e);return"string"!=typeof r&&t?JSON.stringify(r):r}catch{return!1}}const W=e=>"object"==typeof e&&!Array.isArray(e)&&null!==e,q=e=>{if(null===e||"object"!=typeof e)return e;const t=Array.isArray(e)?[]:{};for(const r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=q(e[r]));return t},B=(e,t)=>JSON.stringify(e,(e,r)=>("string"==typeof r&&((r=r.trim()).startsWith("function(")||r.startsWith("function ("))&&r.endsWith("}")&&(r=t?`EXP_FUN${(r+"").replaceAll(/\n|\t|\r/g," ")}EXP_FUN`:void 0),"function"==typeof r?`EXP_FUN${(r+"").replaceAll(/\n|\t|\r/g," ")}EXP_FUN`:r)).replaceAll(/"EXP_FUN|EXP_FUN"/g,"");function X(){console.log("\nUsage of CLI arguments:".bold,"\n------",`\nFor more detailed information, visit the readme at: ${"https://github.com/highcharts/node-export-server#readme".bold.yellow}.`);const e=t=>{for(const[r,o]of Object.entries(t))if(Object.prototype.hasOwnProperty.call(o,"value")){let e=` --${o.cliName||r} ${("<"+o.type+">").green} `;if(e.length<48)for(let t=e.length;t<48;t++)e+=".";console.log(e,o.description,`[Default: ${o.value.toString().bold}]`.blue)}else e(o)};Object.keys(w).forEach(t=>{["puppeteer","highcharts"].includes(t)||(console.log(`\n${t.toUpperCase()}`.red),e(w[t]))}),console.log("\n")}const z=e=>!["false","undefined","null","NaN","0",""].includes(e)&&!!e,K=(t,r)=>{if(t&&"string"==typeof t)return(t=t.trim()).endsWith(".js")?!!r&&K(e.readFileSync(t,"utf8")):t.startsWith("function()")||t.startsWith("function ()")||t.startsWith("()=>")||t.startsWith("() =>")?`(${t})()`:t.replace(/;$/,"")},J=()=>{const e=process.hrtime.bigint();return()=>Number(process.hrtime.bigint()-e)/1e6};let Y={};const Z=()=>Y,Q=(e,t,r=[])=>{const o=q(e);for(const[e,i]of Object.entries(t))o[e]=W(i)&&!r.includes(e)&&void 0!==o[e]?Q(o[e],i,r):void 0!==i?i:o[e];return o};function ee(e,t={},r=""){Object.keys(e).forEach(o=>{const i=e[o],s=t&&t[o];void 0===i.value?ee(i,s,`${r}.${o}`):(void 0!==s&&(i.value=s),i.envLink in N&&void 0!==N[i.envLink]&&(i.value=N[i.envLink]))})}function te(e){let t={};for(const[r,o]of Object.entries(e))t[r]=Object.prototype.hasOwnProperty.call(o,"value")?o.value:te(o);return t}function re(e,t,r){for(;t.length>1;){const o=t.shift();return Object.prototype.hasOwnProperty.call(e,o)||(e[o]={}),e[o]=re(Object.assign({},e[o]),t,r),e}return e[t[0]]=r,e}async function oe(e,t={}){return new Promise((r,o)=>{const i=(e=>e.startsWith("https")?l:a)(e);i.get(e,Object.assign({headers:{"User-Agent":"highcharts/export",Referer:"highcharts.export"}},t||{}),e=>{let t="";e.on("data",e=>{t+=e}),e.on("end",()=>{t||o("Nothing was fetched from the URL."),e.text=t,r(e)})}).on("error",e=>{o(e)})})}class ie extends Error{constructor(e){super(),this.message=e,this.stackMessage=e}setError(e){return this.error=e,e.name&&(this.name=e.name),e.statusCode&&(this.statusCode=e.statusCode),e.stack&&(this.stackMessage=e.message,this.stack=e.stack),this}}const se={cdnURL:"https://code.highcharts.com/",activeManifest:{},sources:"",hcVersion:""},ne=e=>e.sources.substring(0,e.sources.indexOf("*/")).replace("/*","").replace("*/","").replace(/\n/g,"").trim(),ae=async(e,t,r,o=!1)=>{e.endsWith(".js")&&(e=e.substring(0,e.length-3)),$(4,`[cache] Fetching script - ${e}.js`);const i=await oe(`${e}.js`,t);if(200===i.statusCode&&"string"==typeof i.text){if(r){r[e.replace(/(.*)\/|(.*)modules\/|stock\/(.*)indicators\/|maps\/(.*)modules\//gi,"")]=1}return i.text}if(o)throw new ie(`Could not fetch the ${e}.js. The script might not exist in the requested version (status code: ${i.statusCode}).`).setError(i);return $(2,`[cache] Could not fetch the ${e}.js. The script might not exist in the requested version.`),""},le=async(t,o,i)=>{const s=t.version,n="latest"!==s&&s?`${s}/`:"",a=t.cdnURL||se.cdnURL;$(3,`[cache] Updating cache version to Highcharts: ${n||"latest"}.`);const l={};try{return se.sources=await(async(e,t,o,i,s)=>{let n;const{host:a,port:l,username:c,password:p}=i;if(a&&l)try{n=new r.HttpsProxyAgent({host:a,port:l,...c&&p?{username:c,password:p}:{}})}catch(e){throw new ie("[cache] Could not create a Proxy Agent.").setError(e)}const h=n?{agent:n,timeout:N.SERVER_PROXY_TIMEOUT}:{},u=[...e.map(e=>ae(`${e}`,h,s,!0)),...t.map(e=>ae(`${e}`,h,s)),...o.map(e=>ae(`${e}`,h))];return(await Promise.all(u)).join(";\n")})([...t.coreScripts.map(e=>`${a}${n}${e}`)],[...t.moduleScripts.map(e=>"map"===e?`${a}maps/${n}modules/${e}`:`${a}${n}modules/${e}`),...t.indicatorScripts.map(e=>`${a}stock/${n}indicators/${e}`)],t.customScripts,o,l),se.hcVersion=ne(se),e.writeFileSync(i,se.sources),l}catch(e){throw new ie("[cache] Unable to update the local Highcharts cache.").setError(e)}},ce=async r=>{const{highcharts:o,server:i}=r,s=t.join(F,o.cachePath);let n;const a=t.join(s,"manifest.json"),l=t.join(s,"sources.js");if(!e.existsSync(s)&&e.mkdirSync(s),!e.existsSync(a)||o.forceFetch)$(3,"[cache] Fetching and caching Highcharts dependencies."),n=await le(o,i.proxy,l);else{let t=!1;const r=JSON.parse(e.readFileSync(a));if(r.modules&&Array.isArray(r.modules)){const e={};r.modules.forEach(t=>e[t]=1),r.modules=e}const{coreScripts:s,moduleScripts:c,indicatorScripts:p}=o,h=s.length+c.length+p.length;r.version!==o.version?($(2,"[cache] A Highcharts version mismatch in the cache, need to re-fetch."),t=!0):Object.keys(r.modules||{}).length!==h?($(2,"[cache] The cache and the requested modules do not match, need to re-fetch."),t=!0):t=(c||[]).some(e=>{if(!r.modules[e])return $(2,`[cache] The ${e} is missing in the cache, need to re-fetch.`),!0}),t?n=await le(o,i.proxy,l):($(3,"[cache] Dependency cache is up to date, proceeding."),se.sources=e.readFileSync(l,"utf8"),n=r.modules,se.hcVersion=ne(se))}await(async(r,o)=>{const i={version:r.version,modules:o||{}};se.activeManifest=i,$(3,"[cache] Writing a new manifest.");try{e.writeFileSync(t.join(F,r.cachePath,"manifest.json"),JSON.stringify(i),"utf8")}catch(e){throw new ie("[cache] Error writing the cache manifest.").setError(e)}})(o,n)},pe=()=>se.hcVersion;function he(){Highcharts.animObject=function(){return{duration:0}}}async function ue(e,t,r){window._displayErrors=r;const{getOptions:o,merge:i,setOptions:s,wrap:n}=Highcharts;Highcharts.setOptionsObj=i(!1,{},o());const a={animation:!1};t.export.strInj&&(a.height=e.chart.height,a.width=e.chart.width),window.isRenderComplete=!1,n(Highcharts.Chart.prototype,"init",function(e,t,r){((t=i(t,{exporting:{enabled:!1},plotOptions:{series:{label:{enabled:!1}}},tooltip:{}})).series||[]).forEach(function(e){e.animation=!1}),window.onHighchartsRender||(window.onHighchartsRender=Highcharts.addEvent(this,"render",()=>{window.isRenderComplete=!0})),e.apply(this,[t,r])}),n(Highcharts.Series.prototype,"init",function(e,t,r){e.apply(this,[t,r])});const l=t.export.strInj?new Function(`return ${t.export.strInj}`)():e;t.customLogic.customCode&&new Function("options",t.customLogic.customCode)(l);const c=i(!1,JSON.parse(t.export.themeOptions),l,{chart:a}),p=t.customLogic.callback?new Function(`return ${t.customLogic.callback}`)():void 0,h=JSON.parse(t.export.globalOptions);h&&s(h);let u=t.export.constr||"chart";u=void 0!==Highcharts[u]?u:"chart",Highcharts[u]("container",c,p);const d=o();for(const e in d)"function"!=typeof d[e]&&delete d[e];s(Highcharts.setOptionsObj),Highcharts.setOptionsObj={}}const de=e.readFileSync(F+"/templates/template.html","utf8");let ge;async function me(){if(!ge)return!1;const e=await ge.newPage();return await e.setCacheEnabled(!1),await ve(e),function(e){const{debug:t}=Z();t.enable&&t.listenToConsole&&e.on("console",e=>{console.log(`[debug] ${e.text()}`)});e.on("pageerror",async t=>{e.isClosed()||await e.$eval("#container",(e,t)=>{window._displayErrors&&(e.innerHTML=t)},`

Chart input data error:

${t.toString()}`)})}(e),e}async function fe(e,t){try{for(const e of t)await e.dispose();await e.evaluate(()=>{if("undefined"!=typeof Highcharts){const e=Highcharts.charts;if(Array.isArray(e)&&e.length)for(const t of e)t&&t.destroy(),Highcharts.charts.shift()}const[...e]=document.getElementsByTagName("script"),[,...t]=document.getElementsByTagName("style"),[...r]=document.getElementsByTagName("link");for(const o of[...e,...t,...r])o.remove()})}catch(e){D(2,e,"[browser] Could not clear page's resources.")}}async function ve(e){await e.setContent(de,{waitUntil:"domcontentloaded"}),await e.addScriptTag({path:`${t.join(F,Z().highcharts.cachePath)}/sources.js`}),await e.evaluate(he)}const ye=async(e,t,r,o)=>{r.export.instr=null,r.export.infile=null;const i=Buffer.byteLength(r.export?.strInj?r.export?.strInj:JSON.stringify(t),"utf-8");if($(4,`[export] The current total size of data passed to a page is around ${(i/1048576).toFixed(2)} MB`),i>=104857600)throw new ie("[export] The data passed to a page exceeded 100MB.");return e.evaluate(ue,t,r,o)};var be=async(r,o,i)=>{let s=[];try{$(4,"[export] Determining export path.");const n=i.export,a=n?.options?.chart?.displayErrors&&se.activeManifest.modules.debugger;let l;if(o.indexOf&&(o.indexOf("=0||o.indexOf("=0)){if($(4,"[export] Treating as SVG."),"svg"===n.type)return o;l=!0,await r.setContent((e=>`\n\n\n \n \n Highcharts Export\n \n \n \n
\n ${e}\n
\n \n\n\n`)(o),{waitUntil:"domcontentloaded"})}else $(4,"[export] Treating as config."),n.strInj?await ye(r,{chart:{height:n.height,width:n.width}},i,a):(o.chart.height=n.height,o.chart.width=n.width,await ye(r,o,i,a));s=await async function(r,o){const i=[],s=o.customLogic.resources;if(s){const n=[];if(s.js&&n.push({content:s.js}),s.files)for(const t of s.files){const r=!t.startsWith("http");n.push(r?{content:e.readFileSync(t,"utf8")}:{url:t})}for(const e of n)try{i.push(await r.addScriptTag(e))}catch(e){D(2,e,"[export] The JS resource cannot be loaded.")}n.length=0;const a=[];if(s.css){let e=s.css.match(/@import\s*([^;]*);/g);if(e)for(let r of e)r&&(r=r.replace("url(","").replace("@import","").replace(/"/g,"").replace(/'/g,"").replace(/;/,"").replace(/\)/g,"").trim(),r.startsWith("http")?a.push({url:r}):o.customLogic.allowFileResources&&a.push({path:t.join(F,r)}));a.push({content:s.css.replace(/@import\s*([^;]*);/g,"")||" "});for(const e of a)try{i.push(await r.addStyleTag(e))}catch(e){D(2,e,"[export] The CSS resource cannot be loaded.")}a.length=0}}return i}(r,i);const c=l?await r.evaluate(e=>{const t=document.querySelector("#chart-container svg:first-of-type"),r=t.height.baseVal.value*e,o=t.width.baseVal.value*e;return document.body.style.zoom=e,document.body.style.margin="0px",{chartHeight:r,chartWidth:o}},parseFloat(n.scale)):await r.evaluate(()=>{const{chartHeight:e,chartWidth:t}=window.Highcharts.charts[0];return document.body.style.zoom=1,{chartHeight:e,chartWidth:t}}),p=Math.abs(Math.ceil(c.chartHeight||n.height)),h=Math.abs(Math.ceil(c.chartWidth||n.width)),{x:u,y:d}=await(e=>e.$eval("#chart-container",e=>{const{x:t,y:r,width:o,height:i}=e.getBoundingClientRect();return{x:t,y:r,width:o,height:Math.trunc(i>1?i:500)}}))(r);let g;if(await r.setViewport({height:p,width:h,deviceScaleFactor:l?1:parseFloat(n.scale)}),"svg"===n.type)g=await(e=>e.$eval("#container svg:first-of-type",e=>e.outerHTML))(r);else if(["png","jpeg"].includes(n.type))g=await((e,t,r,o,i)=>Promise.race([e.screenshot({type:t,encoding:r,clip:o,captureBeyondViewport:!0,fullPage:!1,optimizeForSpeed:!0,..."png"!==t?{quality:80}:{},omitBackground:"png"==t}),new Promise((e,t)=>setTimeout(()=>t(new ie("Rasterization timeout")),i||1500))]))(r,n.type,"base64",{width:h,height:p,x:u,y:d},n.rasterizationTimeout);else{if("pdf"!==n.type)throw new ie(`[export] Unsupported output format ${n.type}.`);g=await(async(e,t,r,o,i)=>(await e.emulateMediaType("screen"),e.pdf({height:t+1,width:r,encoding:o,timeout:i||1500})))(r,p,h,"base64",n.rasterizationTimeout)}return await fe(r,s),g}catch(e){return await fe(r,s),e}};let we=!1;const Ee={performedExports:0,exportAttempts:0,exportFromSvgAttempts:0,timeSpent:0,droppedExports:0,spentAverage:0};let Te={};const Se={create:async()=>{let e=!1;const t=p.v4(),r=(new Date).getTime();try{if(e=await me(),!e||e.isClosed())throw new ie("The page is invalid or closed.");$(3,`[pool] Successfully created a worker ${t} - took ${(new Date).getTime()-r} ms.`)}catch(e){throw new ie("Error encountered when creating a new page.").setError(e)}return{id:t,page:e,workCount:Math.round(Math.random()*(Te.workLimit/2))}},validate:async e=>!(!e.page||e.page?.isClosed())&&(!(Te.workLimit&&++e.workCount>Te.workLimit)||($(3,`[pool] Worker failed validation: exceeded work limit (limit is ${Te.workLimit}).`),!1)),destroy:async e=>{$(3,`[pool] Destroying pool entry ${e.id}.`),e.page&&!e.page.isClosed()&&await e.page.close()}},xe=async e=>{if(Te=e&&e.pool?{...e.pool}:{},await async function(e){const{puppeteer:t,debug:r,other:o}=Z(),{enable:i,...s}=r,n={headless:!o.browserShellMode||"shell",userDataDir:t.tempDir||"./tmp/",args:e,handleSIGINT:!1,handleSIGTERM:!1,handleSIGHUP:!1,waitForInitialPage:!1,defaultViewport:null,...i&&s};if(!ge){const e=25;let t=0;const r=async()=>{try{$(3,`[browser] Attempting to get a browser instance (try ${++t}).`),ge=await h.launch(n)}catch(o){if(D(2,o,`[browser] Failed to launch a browser instance - retrying (attempt ${t}/${e}).`),!(t<25))throw o;$(3,`[browser] Retry to open a browser (attempt ${t}/${e}).`),await new Promise(e=>setTimeout(e,4e3)),await r()}};try{await r(),"shell"===n.headless&&$(3,"[browser] Launched browser in shell mode."),i&&$(3,"[browser] Launched browser in debug mode.")}catch(e){throw new ie("[browser] Maximum retries to open a browser instance reached.").setError(e)}if(!ge)throw new ie("[browser] Cannot find a browser to open.")}return ge}(e.puppeteerArgs),$(3,`[pool] Initializing pool with workers: min ${Te.minWorkers}, max ${Te.maxWorkers}.`),we)return $(4,"[pool] Already initialized, please kill it before creating a new one.");parseInt(Te.minWorkers)>parseInt(Te.maxWorkers)&&(Te.minWorkers=Te.maxWorkers);try{we=new c.Pool({...Se,min:parseInt(Te.minWorkers),max:parseInt(Te.maxWorkers),acquireTimeoutMillis:Te.acquireTimeout,createTimeoutMillis:Te.createTimeout,destroyTimeoutMillis:Te.destroyTimeout,idleTimeoutMillis:Te.idleTimeout,createRetryIntervalMillis:Te.createRetryInterval,reapIntervalMillis:Te.reaperInterval,propagateCreateError:!1}),we.on("release",async e=>{const t=await async function(e,t=!1){try{if(e&&!e.isClosed())return t?(await e.goto("about:blank",{waitUntil:"domcontentloaded"}),await ve(e)):await e.evaluate(()=>{document.body.innerHTML='
'}),!0}catch(e){D(2,e,"[browser] Could not clear the content of the page.")}return!1}(e.page,!1);$(4,`[pool] Releasing a worker with ID ${e.id}. Clear page status: ${t}.`)}),we.on("destroySuccess",(e,t)=>{$(4,`[pool] Destroyed a worker with ID ${t.id}.`),t.page=null});const e=[];for(let t=0;t{we.release(e)}),$(3,"[pool] The pool is ready"+(e.length?` with ${e.length} initial resources waiting.`:"."))}catch(e){throw new ie("[pool] Could not create the pool of workers.").setError(e)}};async function Re(){if($(3,"[pool] Killing pool with all workers and closing browser."),we){for(const e of we.used)we.release(e.resource);we.destroyed||(await we.destroy(),$(4,"[browser] Destroyed the pool of resources."))}await async function(){ge?.connected&&await ge.close(),$(4,"[browser] Closed the browser.")}()}const _e=async(e,t)=>{let r;try{if($(4,"[pool] Work received, starting to process."),++Ee.exportAttempts,Te.benchmarking&&Le(),!we)throw new ie("Work received, but pool has not been started.");const o=J();try{$(4,"[pool] Acquiring a worker handle."),r=await we.acquire().promise,t.server.benchmarking&&$(5,t.payload?.requestId?`[benchmark] Request with ID ${t.payload?.requestId} -`:"[benchmark]",`Acquired a worker handle: ${o()}ms.`)}catch(e){throw new ie((t.payload?.requestId?`For request with ID ${t.payload?.requestId} - `:"")+`Error encountered when acquiring an available entry: ${o()}ms.`).setError(e)}if($(4,"[pool] Acquired a worker handle."),!r.page)throw new ie("Resolved worker page is invalid: the pool setup is wonky.");let i=(new Date).getTime();$(4,`[pool] Starting work on pool entry with ID ${r.id}.`);const s=J(),n=await be(r.page,e,t);if(n instanceof Error)throw"Rasterization timeout"===n.message&&(r.workCount=Te.workLimit+1,r.page=null),"TimeoutError"===n.name||"Rasterization timeout"===n.message?new ie("Rasterization timeout: your chart may be too complex or large, and failed to render within the allotted time.").setError(n):new ie((t.payload?.requestId?`For request with ID ${t.payload?.requestId} - `:"")+`Error encountered during export: ${s()}ms.`).setError(n);t.server.benchmarking&&$(5,t.payload?.requestId?`[benchmark] Request with ID ${t.payload?.requestId} -`:"[benchmark]",`Exported a chart sucessfully: ${s()}ms.`),we.release(r);const a=(new Date).getTime()-i;return Ee.timeSpent+=a,Ee.spentAverage=Ee.timeSpent/++Ee.performedExports,$(4,`[pool] Work completed in ${a} ms.`),{result:n,options:t}}catch(e){throw++Ee.droppedExports,r&&we.release(r),new ie(`[pool] In pool.postWork: ${e.message}`).setError(e)}},Oe=()=>({min:we.min,max:we.max,all:we.numFree()+we.numUsed(),available:we.numFree(),used:we.numUsed(),pending:we.numPendingAcquires()});function Le(){const{min:e,max:t,all:r,available:o,used:i,pending:s}=Oe();$(5,`[pool] The minimum number of resources allowed by pool: ${e}.`),$(5,`[pool] The maximum number of resources allowed by pool: ${t}.`),$(5,`[pool] The number of all created resources: ${r}.`),$(5,`[pool] The number of available resources: ${o}.`),$(5,`[pool] The number of acquired resources: ${i}.`),$(5,`[pool] The number of resources waiting to be acquired: ${s}.`)}var ke=Oe,Ie=()=>Ee;let Ce=!1;const Ne=async(t,r)=>{$(4,"[chart] Starting the exporting process.");const o=((e,t={})=>{let r={};return e.svg?(r=q(t),r.export.type=e.type||e.export.type,r.export.scale=e.scale||e.export.scale,r.export.outfile=e.outfile||e.export.outfile,r.payload={svg:e.svg}):r=Q(t,e,T),r.export.outfile=r.export?.outfile||`chart.${r.export?.type||"png"}`,r})(t,Z()),i=o.export;if(o.payload?.svg&&""!==o.payload.svg)try{$(4,"[chart] Attempting to export from a SVG input.");const e=$e(function(e){const t=[];N.OTHER_ALLOW_XLINK||t.push("xlink:href");const r=new u.JSDOM("").window;return d(r).sanitize(e,{ADD_TAGS:["foreignObject"],FORBID_ATTR:t})}(o.payload.svg),o,r);return++Ee.exportFromSvgAttempts,e}catch(e){return r(new ie("[chart] Error loading SVG input.").setError(e))}if(i.infile&&i.infile.length)try{return $(4,"[chart] Attempting to export from an input file."),o.export.instr=e.readFileSync(i.infile,"utf8"),$e(o.export.instr.trim(),o,r)}catch(e){return r(new ie("[chart] Error loading input file.").setError(e))}if(i.instr&&""!==i.instr||i.options&&""!==i.options)try{return $(4,"[chart] Attempting to export from a raw input."),i.instr=i.instr||i.options,z(o.customLogic?.allowCodeExecution)?He(o,r):"string"==typeof i.instr?$e(i.instr.trim(),o,r):Pe(o,i.instr||i.options,r)}catch(e){return r(new ie("[chart] Error loading raw input.").setError(e))}return r(new ie("[chart] No valid input specified. Check if at least one of the following parameters is correctly set: 'infile', 'instr', 'options', or 'svg'."))},Ae=e=>{const{chart:t,exporting:r}=e.export?.options||V(e.export?.instr),o=V(e.export?.globalOptions);let i=e.export?.scale||r?.scale||o?.exporting?.scale||e.export?.defaultScale||1;i=Math.max(.1,Math.min(i,5)),i=((e,t=1)=>{const r=Math.pow(10,t||0);return Math.round(+e*r)/r})(i,2);const s={height:e.export?.height||r?.sourceHeight||t?.height||o?.exporting?.sourceHeight||o?.chart?.height||e.export?.defaultHeight||400,width:e.export?.width||r?.sourceWidth||t?.width||o?.exporting?.sourceWidth||o?.chart?.width||e.export?.defaultWidth||600,scale:i};for(let[e,t]of Object.entries(s))s[e]="string"==typeof t?+t.replace(/px|%/gi,""):t;return s},Pe=async(t,r,o,i)=>{let{export:s,customLogic:n}=t;const a="boolean"==typeof n.allowCodeExecution?n.allowCodeExecution:Ce;if(n){if(a)if("string"==typeof t.customLogic.resources)t.customLogic.resources=M(t.customLogic.resources,z(t.customLogic.allowFileResources));else if(!t.customLogic.resources)try{const r=e.readFileSync("resources.json","utf8");t.customLogic.resources=M(r,z(t.customLogic.allowFileResources))}catch(e){$(2,"[chart] Unable to load the default resources.json file.")}}else n=t.customLogic={};if(!a&&n){if(n.callback||n.resources||n.customCode)return o(new ie("[chart] The 'callback', 'resources' and 'customCode' options have been disabled for this server."));n.callback=!1,n.resources=!1,n.customCode=!1}if(r&&(r.chart=r.chart||{},r.exporting=r.exporting||{},r.exporting.enabled=!1),s.constr=s.constr||"chart",s.type=j(s.type,s.outfile),"svg"===s.type&&(s.width=!1),["globalOptions","themeOptions"].forEach(t=>{try{s&&s[t]&&("string"==typeof s[t]&&s[t].endsWith(".json")?s[t]=V(e.readFileSync(s[t],"utf8"),!0):s[t]=V(s[t],!0))}catch(e){s[t]={},D(2,e,`[chart] The '${t}' cannot be loaded.`)}}),n.allowCodeExecution)try{n.customCode=K(n.customCode,n.allowFileResources)}catch(e){D(2,e,"[chart] The 'customCode' cannot be loaded.")}if(n&&n.callback&&n.callback?.indexOf("{")<0)if(n.allowFileResources)try{n.callback=e.readFileSync(n.callback,"utf8")}catch(e){n.callback=!1,D(2,e,"[chart] The 'callback' cannot be loaded.")}else n.callback=!1;t.export={...t.export,...Ae(t)};try{return o(!1,await _e(s.strInj||r||i,t))}catch(e){return o(e)}},He=(e,t)=>{try{let r,o=e.export.instr||e.export.options;return"string"!=typeof o&&(r=o=B(o,e.customLogic?.allowCodeExecution)),r=o.replaceAll(/\t|\n|\r/g,"").trim(),";"===r[r.length-1]&&(r=r.substring(0,r.length-1)),e.export.strInj=r,Pe(e,!1,t)}catch(r){return t(new ie(`[chart] Malformed input detected for ${e.export?.requestId||"?"}. Please make sure that your JSON/JavaScript options are sent using the "options" attribute, and that if you're using SVG, it is unescaped.`).setError(r))}},$e=(e,t,r)=>{const{allowCodeExecution:o}=t.customLogic;if(e.indexOf("=0||e.indexOf("=0)return $(4,"[chart] Parsing input as SVG."),Pe(t,!1,r,e);try{const o=JSON.parse(e.replaceAll(/\t|\n|\r/g," "));return Pe(t,o,r)}catch(e){return z(o)?He(t,r):r(new ie("[chart] Only JSON configurations and SVG are allowed for this server. If this is your server, JavaScript custom code can be enabled by starting the server with the --allowCodeExecution flag.").setError(e))}},De=[],Ue=()=>{$(4,"[server] Clearing all registered intervals.");for(const e of De)clearInterval(e)},Ge=(e,t,r,o)=>{D(1,e),"development"!==N.OTHER_NODE_ENV&&delete e.stack,o(e)},Fe=(e,t,r,o)=>{const{statusCode:i,status:s,message:n,stack:a}=e,l=i||s||400;r.status(l).json({statusCode:l,message:n,stack:a})};var je=(e,t)=>{const r="Too many requests, you have been rate limited. Please try again later.",o={max:t.maxRequests||30,window:t.window||1,delay:t.delay||0,trustProxy:t.trustProxy||!1,skipKey:t.skipKey||!1,skipToken:t.skipToken||!1};o.trustProxy&&e.enable("trust proxy");const i=v({windowMs:60*o.window*1e3,max:o.max,delayMs:o.delay,handler:(e,t)=>{t.format({json:()=>{t.status(429).send({message:r})},default:()=>{t.status(429).send(r)}})},skip:e=>!1!==o.skipKey&&!1!==o.skipToken&&e.query.key===o.skipKey&&e.query.access_token===o.skipToken&&($(4,"[rate limiting] Skipping rate limiter."),!0)});e.use(i),$(3,`[rate limiting] Enabled rate limiting with ${o.max} requests per ${o.window} minute for each IP, trusting proxy: ${o.trustProxy}.`)};class Me extends ie{constructor(e,t){super(e),this.status=this.statusCode=t}setStatus(e){return this.status=e,this}}var Ve=e=>!!e&&e.post("/version/change/:newVersion",async(e,t,r)=>{try{const r=N.HIGHCHARTS_ADMIN_TOKEN;if(!r||!r.length)throw new Me("The server is not configured to perform run-time version changes: HIGHCHARTS_ADMIN_TOKEN is not set.",401);const o=e.get("hc-auth");if(!o||o!==r)throw new Me("Invalid or missing token: Set the token in the hc-auth header.",401);const i=e.params.newVersion;if(!i)throw new Me("No new version supplied.",400);try{await(async e=>{const t=Z();t?.highcharts&&(t.highcharts.version=e),await ce(t)})(i)}catch(e){throw new Me(`Version change: ${e.message}`,e.statusCode).setError(e)}t.status(200).send({statusCode:200,version:pe(),message:`Successfully updated Highcharts to version: ${i}.`})}catch(e){r(e)}});const We={png:"image/png",jpeg:"image/jpeg",gif:"image/gif",pdf:"application/pdf",svg:"image/svg+xml"};let qe=0;const Be=[],Xe=[],ze=(e,t,r,o)=>{let i=!0;const{id:s,uniqueId:n,type:a,body:l}=o;return e.some(e=>{if(e){let o=e(t,r,s,n,a,l);return void 0!==o&&!0!==o&&(i=o),!0}}),i},Ke=async(e,t,r)=>{try{const r=J(),i=p.v4().replace(/-/g,""),s=Z(),n=e.body,a=++qe;let l=j(n.type);if(!n||"object"==typeof(o=n)&&!Array.isArray(o)&&null!==o&&0===Object.keys(o).length)throw new Me("The request body is required. Please ensure that your Content-Type header is correct (accepted types are application/json and multipart/form-data).",400);let c=V(n.infile||n.options||n.data);if(!c&&!n.svg)throw $(2,`The request with ID ${i} from ${e.headers["x-forwarded-for"]||e.connection.remoteAddress} was incorrect:\n Content-Type: ${e.headers["content-type"]}. \n Chart constructor: ${n.constr}.\n Dimensions: ${n.width}x${n.height} @ ${n.scale} scale.\n Type: ${l}.\n Is SVG set? ${void 0!==n.svg}.\n B64? ${void 0!==n.b64}.\n No download? ${void 0!==n.noDownload}.\n\n Payload received: ${JSON.stringify(n.infile||n.options||n.data||n.svg)}\n\n `),new Me("No correct chart data found. Ensure that you are using either application/json or multipart/form-data headers. If sending JSON, make sure the chart data is in the 'infile', 'options', or 'data' attribute. If sending SVG, ensure it is in the 'svg' attribute.",400);let h=!1;if(h=ze(Be,e,t,{id:a,uniqueId:i,type:l,body:n}),!0!==h)return t.send(h);let u=!1;e.socket.on("close",e=>{e&&(u=!0)}),$(4,`[export] Got an incoming HTTP request with ID ${i}.`),n.constr="string"==typeof n.constr&&n.constr||"chart";const d={export:{instr:c,type:l,constr:n.constr[0].toLowerCase()+n.constr.substr(1),height:n.height,width:n.width,scale:n.scale||s.export.scale,globalOptions:V(n.globalOptions,!0),themeOptions:V(n.themeOptions,!0)},customLogic:{allowCodeExecution:Ce,allowFileResources:!1,resources:V(n.resources,!0),callback:n.callback,customCode:n.customCode}};c&&(d.export.instr=B(c,d.customLogic.allowCodeExecution));const g=Q(s,d);if(g.export.options=c,g.payload={svg:n.svg||!1,b64:n.b64||!1,noDownload:n.noDownload||!1,requestId:i},n.svg&&(e=>[/xlink:href="(?:http:\/\/|https:\/\/)?localhost\b/,/xlink:href="(?:http:\/\/|https:\/\/)?10\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/,/xlink:href="(?:http:\/\/|https:\/\/)?127\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/,/xlink:href="(?:http:\/\/|https:\/\/)?172\.(1[6-9]|2[0-9]|3[0-1])\.\d{1,3}\.\d{1,3}\b/,/xlink:href="(?:http:\/\/|https:\/\/)?192\.168\.\d{1,3}\.\d{1,3}\b/].some(t=>t.test(e)))(g.payload.svg))throw new Me("SVG potentially contain at least one forbidden URL in xlink:href element. Please review the SVG content and ensure that all referenced URLs comply with security policies.",400);await Ne(g,(o,c)=>{if(e.socket.removeAllListeners("close"),s.server.benchmarking&&$(5,`[benchmark] Request with ID ${i} - After the whole exporting process: ${r()}ms.`),u)return $(3,"[export] The client closed the connection before the chart finished processing.");if(o)throw o;if(!c||!c.result)throw new Me(`Unexpected return from chart generation. Please check your request data. For the request with ID ${i}, the result is ${c.result}.`,400);return l=c.options.export.type,ze(Xe,e,t,{id:a,body:c.result}),c.result?n.b64?"pdf"===l||"svg"==l?t.send(Buffer.from(c.result,"utf8").toString("base64")):t.send(c.result):(t.header("Content-Type",We[l]||"image/png"),n.noDownload||t.attachment(`${e.params.filename||e.body.filename||"chart"}.${l||"png"}`),"svg"===l?t.send(c.result):t.send(Buffer.from(c.result,"base64"))):void 0})}catch(e){r(e)}var o};const Je=JSON.parse(e.readFileSync(t.join(F,"package.json"))),Ye=new Date,Ze=[];function Qe(e){if(!e)return!1;var t;t=setInterval(()=>{const e=Ie(),t=0===e.exportAttempts?1:e.performedExports/e.exportAttempts*100;Ze.push(t),Ze.length>30&&Ze.shift()},6e4),De.push(t),e.get("/health",(e,t)=>{const r=Ie(),o=Ze.length,i=Ze.reduce((e,t)=>e+t,0)/Ze.length;$(4,"[health.js] GET /health [200] - returning server health."),t.send({status:"OK",bootTime:Ye,uptime:Math.floor(((new Date).getTime()-Ye.getTime())/1e3/60)+" minutes",version:Je.version,highchartsVersion:pe(),averageProcessingTime:r.spentAverage,performedExports:r.performedExports,failedExports:r.droppedExports,exportAttempts:r.exportAttempts,sucessRatio:r.performedExports/r.exportAttempts*100,pool:ke(),period:o,movingAverage:i,message:isNaN(i)||!Ze.length?"Too early to report. No exports made yet. Please check back soon.":`Last ${o} minutes had a success rate of ${i.toFixed(2)}%.`,svgExportAttempts:r.exportFromSvgAttempts,jsonExportAttempts:r.performedExports-r.exportFromSvgAttempts})})}const et=new Map,tt=m();tt.disable("x-powered-by"),tt.use(g()),tt.use((e,t,r)=>{t.set("Accept-Ranges","none"),r()});const rt=e=>{e.on("clientError",(e,t)=>{D(1,e,`[server] Client error: ${e.message}, destroying socket.`),t.destroy()}),e.on("error",e=>{D(1,e,`[server] Server error: ${e.message}`)}),e.on("connection",e=>{e.on("error",e=>{D(1,e,`[server] Socket error: ${e.message}`)})})},ot=async r=>{try{const o=1024*(r.maxUploadSize||3)*1024,i=f.memoryStorage(),s=f({storage:i,limits:{fieldSize:o}});if(tt.use(m.json({limit:o})),tt.use(m.urlencoded({extended:!0,limit:o})),tt.use(s.none()),!r.enable)return!1;if(!r.ssl.force){const e=a.createServer(tt);rt(e),e.listen(r.port,r.host),et.set(r.port,e),$(3,`[server] Started HTTP server on ${r.host}:${r.port}.`)}if(r.ssl.enable){let o,i;try{o=await e.promises.readFile(t.posix.join(r.ssl.certPath,"server.key"),"utf8"),i=await e.promises.readFile(t.posix.join(r.ssl.certPath,"server.crt"),"utf8")}catch(e){$(2,`[server] Unable to load key/certificate from the '${r.ssl.certPath}' path. Could not run secured layer server.`)}if(o&&i){const e=l.createServer({key:o,cert:i},tt);rt(e),e.listen(r.ssl.port,r.host),et.set(r.ssl.port,e),$(3,`[server] Started HTTPS server on ${r.host}:${r.ssl.port}.`)}}r.rateLimiting&&r.rateLimiting.enable&&![0,NaN].includes(r.rateLimiting.maxRequests)&&je(tt,r.rateLimiting),tt.use(m.static(t.posix.join(F,"public"))),Qe(tt),(e=>{e.post("/",Ke),e.post("/:filename",Ke)})(tt),(e=>{!!e&&e.get("/",(e,r)=>{r.sendFile(t.join(F,"public","index.html"),{acceptRanges:!1})})})(tt),Ve(tt),(e=>{e.use(Ge),e.use(Fe)})(tt)}catch(e){throw new ie("[server] Could not configure and start the server.").setError(e)}},it=()=>{$(4,"[server] Closing all servers.");for(const[e,t]of et)t.close(()=>{et.delete(e),$(4,`[server] Closed server on port: ${e}.`)})};var st={startServer:ot,closeServers:it,getServers:()=>et,enableRateLimiting:e=>je(tt,e),getExpress:()=>m,getApp:()=>tt,use:(e,...t)=>{tt.use(e,...t)},get:(e,...t)=>{tt.get(e,...t)},post:(e,...t)=>{tt.post(e,...t)}};const nt=async e=>{await Promise.allSettled([Ue(),it(),Re()]),process.exit(e)};var at={server:st,startServer:ot,initExport:async e=>{var t;return t=e.customLogic&&e.customLogic.allowCodeExecution,Ce=z(t),(e=>{for(const[t,r]of Object.entries(e))P[t]=r;U(e&&parseInt(e.level)),e&&e.dest&&e.toFile&&G(e.dest,e.file||"highcharts-export-server.log")})(e.logging),e.other.listenToProcessExits&&($(3,"[process] Attaching exit listeners to the process."),process.on("exit",e=>{$(4,`Process exited with code ${e}.`)}),process.on("SIGINT",async(e,t)=>{$(4,`The ${e} event with code: ${t}.`),await nt(0)}),process.on("SIGTERM",async(e,t)=>{$(4,`The ${e} event with code: ${t}.`),await nt(0)}),process.on("SIGHUP",async(e,t)=>{$(4,`The ${e} event with code: ${t}.`),await nt(0)}),process.on("uncaughtException",async(e,t)=>{D(1,e,`The ${t} error.`),await nt(1)})),await ce(e),await xe({pool:e.pool||{minWorkers:1,maxWorkers:1},puppeteerArgs:e.puppeteer.args||[]}),e},singleExport:async t=>{t.export.instr=t.export.instr||t.export.options,await Ne(t,async(t,r)=>{if(t)throw t;const{outfile:o,type:i}=r.options.export;e.writeFileSync(o||`chart.${i}`,"svg"!==i?Buffer.from(r.result,"base64"):r.result),await Re()})},batchExport:async t=>{const r=[];for(let o of t.export.batch.split(";"))o=o.split("="),2===o.length&&r.push(Ne({...t,export:{...t.export,infile:o[0],outfile:o[1]}},(t,r)=>{if(t)throw t;e.writeFileSync(r.options.export.outfile,"svg"!==r.options.export.type?Buffer.from(r.result,"base64"):r.result)}));try{await Promise.all(r),await Re()}catch(e){throw new ie("[chart] Error encountered during batch export.").setError(e)}},startExport:Ne,initPool:xe,killPool:Re,setOptions:(t,r)=>(r?.length&&(Y=function(t){const r=t.findIndex(e=>"loadConfig"===e.replace(/-/g,""));if(r>-1&&t[r+1]){const o=t[r+1];try{if(o&&o.endsWith(".json"))return JSON.parse(e.readFileSync(o))}catch(e){D(2,e,`[config] Unable to load the configuration from the ${o} file.`)}}return{}}(r)),ee(w,Y),Y=te(w),t&&(Y=Q(Y,t,T)),r?.length&&(Y=function(e,t,r){let o=!1;for(let i=0;i(n.length-1===r&&(a=e[t].type),e[t]),r),n.reduce((e,r,l)=>(n.length-1===l&&void 0!==e[r]&&(t[++i]?"boolean"===a?e[r]=z(t[i]):"number"===a?e[r]=+t[i]:a.indexOf("]")>=0?e[r]=t[i].split(","):e[r]=t[i]:($(2,`[config] Missing value for the '${s}' argument. Using the default value.`),o=!0)),e[r]),e)}o&&X();return e}(Y,r,w)),Y),shutdownCleanUp:nt,log:$,logWithStack:D,setLogLevel:U,enableFileLogging:G,mapToNewConfig:e=>{const t={};for(const[r,o]of Object.entries(e)){const e=S[r]?S[r].split("."):[];e.reduce((t,r,i)=>t[r]=e.length-1===i?o:t[r]||{},t)}return t},manualConfig:async t=>{let r={};e.existsSync(t)&&(r=JSON.parse(e.readFileSync(t,"utf8")));const i=Object.keys(E).map(e=>({title:`${e} options`,value:e}));return o({type:"multiselect",name:"category",message:"Which category do you want to configure?",hint:"Space: Select specific, A: Select all, Enter: Confirm.",instructions:"",choices:i},{onSubmit:async(i,s)=>{let n=0,a=[];for(const e of s)E[e]=E[e].map(t=>({...t,section:e})),a=[...a,...E[e]];return await o(a,{onSubmit:async(o,i)=>{if("moduleScripts"===o.name?(i=i.length?i.map(e=>o.choices[e]):o.choices,r[o.section][o.name]=i):r[o.section]=re(Object.assign({},r[o.section]||{}),o.name.split("."),o.choices?o.choices[i]:i),++n===a.length){try{await e.promises.writeFile(t,JSON.stringify(r,null,2),"utf8")}catch(e){D(1,e,`[config] An error occurred while creating the ${t} file.`)}return!0}}}),!0}})},printLogo:r=>{const o=JSON.parse(e.readFileSync(t.join(F,"package.json"))).version;r?console.log(`Starting Highcharts Export Server v${o}...`):console.log(e.readFileSync(F+"/msg/startup.msg").toString().bold.yellow,`v${o}\n`.bold)},printUsage:X};module.exports=at; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguY2pzIiwic291cmNlcyI6WyIuLi9saWIvc2NoZW1hcy9jb25maWcuanMiLCIuLi9saWIvZW52cy5qcyIsIi4uL2xpYi9sb2dnZXIuanMiLCIuLi9saWIvdXRpbHMuanMiLCIuLi9saWIvY29uZmlnLmpzIiwiLi4vbGliL2ZldGNoLmpzIiwiLi4vbGliL2Vycm9ycy9FeHBvcnRFcnJvci5qcyIsIi4uL2xpYi9jYWNoZS5qcyIsIi4uL2xpYi9oaWdoY2hhcnRzLmpzIiwiLi4vbGliL2Jyb3dzZXIuanMiLCIuLi9saWIvZXhwb3J0LmpzIiwiLi4vdGVtcGxhdGVzL3N2Z19leHBvcnQvc3ZnX2V4cG9ydC5qcyIsIi4uL2xpYi9wb29sLmpzIiwiLi4vbGliL2NoYXJ0LmpzIiwiLi4vbGliL3Nhbml0aXplLmpzIiwiLi4vbGliL2ludGVydmFscy5qcyIsIi4uL2xpYi9zZXJ2ZXIvZXJyb3IuanMiLCIuLi9saWIvc2VydmVyL3JhdGVfbGltaXQuanMiLCIuLi9saWIvZXJyb3JzL0h0dHBFcnJvci5qcyIsIi4uL2xpYi9zZXJ2ZXIvcm91dGVzL2NoYW5nZV9oY192ZXJzaW9uLmpzIiwiLi4vbGliL3NlcnZlci9yb3V0ZXMvZXhwb3J0LmpzIiwiLi4vbGliL3NlcnZlci9yb3V0ZXMvaGVhbHRoLmpzIiwiLi4vbGliL3NlcnZlci9zZXJ2ZXIuanMiLCIuLi9saWIvc2VydmVyL3JvdXRlcy91aS5qcyIsIi4uL2xpYi9yZXNvdXJjZV9yZWxlYXNlLmpzIiwiLi4vbGliL2luZGV4LmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG5cbkhpZ2hjaGFydHMgRXhwb3J0IFNlcnZlclxuXG5Db3B5cmlnaHQgKGMpIDIwMTYtMjAyNCwgSGlnaHNvZnRcblxuTGljZW5jZWQgdW5kZXIgdGhlIE1JVCBsaWNlbmNlLlxuXG5BZGRpdGlvbmFsbHkgYSB2YWxpZCBIaWdoY2hhcnRzIGxpY2Vuc2UgaXMgcmVxdWlyZWQgZm9yIHVzZS5cblxuU2VlIExJQ0VOU0UgZmlsZSBpbiByb290IGZvciBkZXRhaWxzLlxuXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG4vLyBQb3NzaWJsZSBuYW1lcyBmb3IgSGlnaGNoYXJ0cyBzY3JpcHRzXG5leHBvcnQgY29uc3Qgc2NyaXB0c05hbWVzID0ge1xuICBjb3JlOiBbJ2hpZ2hjaGFydHMnLCAnaGlnaGNoYXJ0cy1tb3JlJywgJ2hpZ2hjaGFydHMtM2QnXSxcbiAgbW9kdWxlczogW1xuICAgICdzdG9jaycsXG4gICAgJ21hcCcsXG4gICAgJ2dhbnR0JyxcbiAgICAnZXhwb3J0aW5nJyxcbiAgICAncGFyYWxsZWwtY29vcmRpbmF0ZXMnLFxuICAgICdhY2Nlc3NpYmlsaXR5JyxcbiAgICAvLyAnYW5ub3RhdGlvbnMtYWR2YW5jZWQnLFxuICAgICdib29zdC1jYW52YXMnLFxuICAgICdib29zdCcsXG4gICAgJ2RhdGEnLFxuICAgICdkYXRhLXRvb2xzJyxcbiAgICAnZHJhZ2dhYmxlLXBvaW50cycsXG4gICAgJ3N0YXRpYy1zY2FsZScsXG4gICAgJ2Jyb2tlbi1heGlzJyxcbiAgICAnaGVhdG1hcCcsXG4gICAgJ3RpbGVtYXAnLFxuICAgICd0aWxlZHdlYm1hcCcsXG4gICAgJ3RpbWVsaW5lJyxcbiAgICAndHJlZW1hcCcsXG4gICAgJ3RyZWVncmFwaCcsXG4gICAgJ2l0ZW0tc2VyaWVzJyxcbiAgICAnZHJpbGxkb3duJyxcbiAgICAnaGlzdG9ncmFtLWJlbGxjdXJ2ZScsXG4gICAgJ2J1bGxldCcsXG4gICAgJ2Z1bm5lbCcsXG4gICAgJ2Z1bm5lbDNkJyxcbiAgICAnZ2VvaGVhdG1hcCcsXG4gICAgJ3B5cmFtaWQzZCcsXG4gICAgJ25ldHdvcmtncmFwaCcsXG4gICAgJ292ZXJsYXBwaW5nLWRhdGFsYWJlbHMnLFxuICAgICdwYXJldG8nLFxuICAgICdwYXR0ZXJuLWZpbGwnLFxuICAgICdwaWN0b3JpYWwnLFxuICAgICdwcmljZS1pbmRpY2F0b3InLFxuICAgICdzYW5rZXknLFxuICAgICdhcmMtZGlhZ3JhbScsXG4gICAgJ2RlcGVuZGVuY3ktd2hlZWwnLFxuICAgICdzZXJpZXMtbGFiZWwnLFxuICAgICdzZXJpZXMtb24tcG9pbnQnLFxuICAgICdzb2xpZC1nYXVnZScsXG4gICAgJ3NvbmlmaWNhdGlvbicsXG4gICAgLy8gJ3N0b2NrLXRvb2xzJyxcbiAgICAnc3RyZWFtZ3JhcGgnLFxuICAgICdzdW5idXJzdCcsXG4gICAgJ3ZhcmlhYmxlLXBpZScsXG4gICAgJ3Zhcml3aWRlJyxcbiAgICAndmVjdG9yJyxcbiAgICAndmVubicsXG4gICAgJ3dpbmRiYXJiJyxcbiAgICAnd29yZGNsb3VkJyxcbiAgICAneHJhbmdlJyxcbiAgICAnbm8tZGF0YS10by1kaXNwbGF5JyxcbiAgICAnZHJhZy1wYW5lcycsXG4gICAgJ2RlYnVnZ2VyJyxcbiAgICAnZHVtYmJlbGwnLFxuICAgICdsb2xsaXBvcCcsXG4gICAgJ2N5bGluZGVyJyxcbiAgICAnb3JnYW5pemF0aW9uJyxcbiAgICAnZG90cGxvdCcsXG4gICAgJ21hcmtlci1jbHVzdGVycycsXG4gICAgJ2hvbGxvd2NhbmRsZXN0aWNrJyxcbiAgICAnaGVpa2luYXNoaScsXG4gICAgJ2Zsb3dtYXAnLFxuICAgICdleHBvcnQtZGF0YScsXG4gICAgJ25hdmlnYXRvcicsXG4gICAgJ3RleHRwYXRoJ1xuICBdLFxuICBpbmRpY2F0b3JzOiBbJ2luZGljYXRvcnMtYWxsJ10sXG4gIGN1c3RvbTogW1xuICAgICdodHRwczovL2NkbmpzLmNsb3VkZmxhcmUuY29tL2FqYXgvbGlicy9tb21lbnQuanMvMi4zMC4xL21vbWVudC5taW4uanMnLFxuICAgICdodHRwczovL2NkbmpzLmNsb3VkZmxhcmUuY29tL2FqYXgvbGlicy9tb21lbnQtdGltZXpvbmUvMC41LjQ1L21vbWVudC10aW1lem9uZS13aXRoLWRhdGEubWluLmpzJ1xuICBdXG59O1xuXG4vLyBUaGlzIGlzIHRoZSBjb25maWd1cmF0aW9uIG9iamVjdCB3aXRoIGFsbCBvcHRpb25zIGFuZCB0aGVpciBkZWZhdWx0IHZhbHVlcyxcbi8vIGFsc28gZnJvbSB0aGUgLmVudiBmaWxlIGlmIG9uZSBleGlzdHNcbmV4cG9ydCBjb25zdCBkZWZhdWx0Q29uZmlnID0ge1xuICBwdXBwZXRlZXI6IHtcbiAgICBhcmdzOiB7XG4gICAgICB2YWx1ZTogW1xuICAgICAgICAnLS1hbGxvdy1ydW5uaW5nLWluc2VjdXJlLWNvbnRlbnQnLFxuICAgICAgICAnLS1hc2gtbm8tbnVkZ2VzJyxcbiAgICAgICAgJy0tYXV0b3BsYXktcG9saWN5PXVzZXItZ2VzdHVyZS1yZXF1aXJlZCcsXG4gICAgICAgICctLWJsb2NrLW5ldy13ZWItY29udGVudHMnLFxuICAgICAgICAnLS1kaXNhYmxlLWFjY2VsZXJhdGVkLTJkLWNhbnZhcycsXG4gICAgICAgICctLWRpc2FibGUtYmFja2dyb3VuZC1uZXR3b3JraW5nJyxcbiAgICAgICAgJy0tZGlzYWJsZS1iYWNrZ3JvdW5kLXRpbWVyLXRocm90dGxpbmcnLFxuICAgICAgICAnLS1kaXNhYmxlLWJhY2tncm91bmRpbmctb2NjbHVkZWQtd2luZG93cycsXG4gICAgICAgICctLWRpc2FibGUtYnJlYWtwYWQnLFxuICAgICAgICAnLS1kaXNhYmxlLWNoZWNrZXItaW1hZ2luZycsXG4gICAgICAgICctLWRpc2FibGUtY2xpZW50LXNpZGUtcGhpc2hpbmctZGV0ZWN0aW9uJyxcbiAgICAgICAgJy0tZGlzYWJsZS1jb21wb25lbnQtZXh0ZW5zaW9ucy13aXRoLWJhY2tncm91bmQtcGFnZXMnLFxuICAgICAgICAnLS1kaXNhYmxlLWNvbXBvbmVudC11cGRhdGUnLFxuICAgICAgICAnLS1kaXNhYmxlLWRlZmF1bHQtYXBwcycsXG4gICAgICAgICctLWRpc2FibGUtZGV2LXNobS11c2FnZScsXG4gICAgICAgICctLWRpc2FibGUtZG9tYWluLXJlbGlhYmlsaXR5JyxcbiAgICAgICAgJy0tZGlzYWJsZS1leHRlbnNpb25zJyxcbiAgICAgICAgJy0tZGlzYWJsZS1mZWF0dXJlcz1DYWxjdWxhdGVOYXRpdmVXaW5PY2NsdXNpb24sSW50ZXJlc3RGZWVkQ29udGVudFN1Z2dlc3Rpb25zLFdlYk9UUCcsXG4gICAgICAgICctLWRpc2FibGUtaGFuZy1tb25pdG9yJyxcbiAgICAgICAgJy0tZGlzYWJsZS1pcGMtZmxvb2RpbmctcHJvdGVjdGlvbicsXG4gICAgICAgICctLWRpc2FibGUtbG9nZ2luZycsXG4gICAgICAgICctLWRpc2FibGUtbm90aWZpY2F0aW9ucycsXG4gICAgICAgICctLWRpc2FibGUtb2ZmZXItc3RvcmUtdW5tYXNrZWQtd2FsbGV0LWNhcmRzJyxcbiAgICAgICAgJy0tZGlzYWJsZS1wb3B1cC1ibG9ja2luZycsXG4gICAgICAgICctLWRpc2FibGUtcHJpbnQtcHJldmlldycsXG4gICAgICAgICctLWRpc2FibGUtcHJvbXB0LW9uLXJlcG9zdCcsXG4gICAgICAgICctLWRpc2FibGUtcmVuZGVyZXItYmFja2dyb3VuZGluZycsXG4gICAgICAgICctLWRpc2FibGUtc2VhcmNoLWVuZ2luZS1jaG9pY2Utc2NyZWVuJyxcbiAgICAgICAgJy0tZGlzYWJsZS1zZXNzaW9uLWNyYXNoZWQtYnViYmxlJyxcbiAgICAgICAgJy0tZGlzYWJsZS1zZXR1aWQtc2FuZGJveCcsXG4gICAgICAgICctLWRpc2FibGUtc2l0ZS1pc29sYXRpb24tdHJpYWxzJyxcbiAgICAgICAgJy0tZGlzYWJsZS1zcGVlY2gtYXBpJyxcbiAgICAgICAgJy0tZGlzYWJsZS1zeW5jJyxcbiAgICAgICAgJy0tZW5hYmxlLXVuc2FmZS13ZWJncHUnLFxuICAgICAgICAnLS1oaWRlLWNyYXNoLXJlc3RvcmUtYnViYmxlJyxcbiAgICAgICAgJy0taGlkZS1zY3JvbGxiYXJzJyxcbiAgICAgICAgJy0tbWV0cmljcy1yZWNvcmRpbmctb25seScsXG4gICAgICAgICctLW11dGUtYXVkaW8nLFxuICAgICAgICAnLS1uby1kZWZhdWx0LWJyb3dzZXItY2hlY2snLFxuICAgICAgICAnLS1uby1maXJzdC1ydW4nLFxuICAgICAgICAnLS1uby1waW5ncycsXG4gICAgICAgICctLXBpcGUnLFxuICAgICAgICAvLyAnLS1uby1zYW5kYm94JyxcbiAgICAgICAgJy0tbm8tc3RhcnR1cC13aW5kb3cnLFxuICAgICAgICAvLyAnLS1uby16eWdvdGUnLFxuICAgICAgICAnLS1wYXNzd29yZC1zdG9yZT1iYXNpYycsXG4gICAgICAgICctLXByb2Nlc3MtcGVyLXRhYicsXG4gICAgICAgICctLXVzZS1tb2NrLWtleWNoYWluJ1xuICAgICAgXSxcbiAgICAgIHR5cGU6ICdzdHJpbmdbXScsXG4gICAgICBkZXNjcmlwdGlvbjogJ0FyZ3VtZW50cyBhcnJheSB0byBzZW5kIHRvIFB1cHBldGVlci4nXG4gICAgfSxcbiAgICB0ZW1wRGlyOiB7XG4gICAgICB2YWx1ZTogJy4vdG1wLycsXG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIGVudkxpbms6ICdQVVBQRVRFRVJfVEVNUF9ESVInLFxuICAgICAgZGVzY3JpcHRpb246ICdUaGUgZGlyZWN0b3J5IGZvciBQdXBwZXRlZXIgdG8gc3RvcmUgdGVtcG9yYXJ5IGZpbGVzLidcbiAgICB9XG4gIH0sXG4gIGhpZ2hjaGFydHM6IHtcbiAgICB2ZXJzaW9uOiB7XG4gICAgICB2YWx1ZTogJ2xhdGVzdCcsXG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIGVudkxpbms6ICdISUdIQ0hBUlRTX1ZFUlNJT04nLFxuICAgICAgZGVzY3JpcHRpb246ICdUaGUgSGlnaGNoYXJ0cyB2ZXJzaW9uIHRvIGJlIHVzZWQuJ1xuICAgIH0sXG4gICAgY2RuVVJMOiB7XG4gICAgICB2YWx1ZTogJ2h0dHBzOi8vY29kZS5oaWdoY2hhcnRzLmNvbS8nLFxuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICBlbnZMaW5rOiAnSElHSENIQVJUU19DRE5fVVJMJyxcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhlIENETiBVUkwgZm9yIEhpZ2hjaGFydHMgc2NyaXB0cyB0byBiZSB1c2VkLidcbiAgICB9LFxuICAgIGNvcmVTY3JpcHRzOiB7XG4gICAgICB2YWx1ZTogc2NyaXB0c05hbWVzLmNvcmUsXG4gICAgICB0eXBlOiAnc3RyaW5nW10nLFxuICAgICAgZW52TGluazogJ0hJR0hDSEFSVFNfQ09SRV9TQ1JJUFRTJyxcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhlIGNvcmUgSGlnaGNoYXJ0cyBzY3JpcHRzIHRvIGZldGNoLidcbiAgICB9LFxuICAgIG1vZHVsZVNjcmlwdHM6IHtcbiAgICAgIHZhbHVlOiBzY3JpcHRzTmFtZXMubW9kdWxlcyxcbiAgICAgIHR5cGU6ICdzdHJpbmdbXScsXG4gICAgICBlbnZMaW5rOiAnSElHSENIQVJUU19NT0RVTEVfU0NSSVBUUycsXG4gICAgICBkZXNjcmlwdGlvbjogJ1RoZSBtb2R1bGVzIG9mIEhpZ2hjaGFydHMgdG8gZmV0Y2guJ1xuICAgIH0sXG4gICAgaW5kaWNhdG9yU2NyaXB0czoge1xuICAgICAgdmFsdWU6IHNjcmlwdHNOYW1lcy5pbmRpY2F0b3JzLFxuICAgICAgdHlwZTogJ3N0cmluZ1tdJyxcbiAgICAgIGVudkxpbms6ICdISUdIQ0hBUlRTX0lORElDQVRPUl9TQ1JJUFRTJyxcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhlIGluZGljYXRvcnMgb2YgSGlnaGNoYXJ0cyB0byBmZXRjaC4nXG4gICAgfSxcbiAgICBjdXN0b21TY3JpcHRzOiB7XG4gICAgICB2YWx1ZTogc2NyaXB0c05hbWVzLmN1c3RvbSxcbiAgICAgIHR5cGU6ICdzdHJpbmdbXScsXG4gICAgICBkZXNjcmlwdGlvbjogJ0FkZGl0aW9uYWwgY3VzdG9tIHNjcmlwdHMgb3IgZGVwZW5kZW5jaWVzIHRvIGZldGNoLidcbiAgICB9LFxuICAgIGZvcmNlRmV0Y2g6IHtcbiAgICAgIHZhbHVlOiBmYWxzZSxcbiAgICAgIHR5cGU6ICdib29sZWFuJyxcbiAgICAgIGVudkxpbms6ICdISUdIQ0hBUlRTX0ZPUkNFX0ZFVENIJyxcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnVGhlIGZsYWcgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgdG8gcmVmZXRjaCBhbGwgc2NyaXB0cyBhZnRlciBlYWNoIHNlcnZlciByZXJ1bi4nXG4gICAgfSxcbiAgICBjYWNoZVBhdGg6IHtcbiAgICAgIHZhbHVlOiAnLmNhY2hlJyxcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgZW52TGluazogJ0hJR0hDSEFSVFNfQ0FDSEVfUEFUSCcsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoZSBwYXRoIHRvIHRoZSBjYWNoZSBkaXJlY3RvcnkuIEl0IGlzIHVzZWQgdG8gc3RvcmUgdGhlIEhpZ2hjaGFydHMgc2NyaXB0cyBhbmQgY3VzdG9tIHNjcmlwdHMuJ1xuICAgIH1cbiAgfSxcbiAgZXhwb3J0OiB7XG4gICAgaW5maWxlOiB7XG4gICAgICB2YWx1ZTogZmFsc2UsXG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnVGhlIGlucHV0IGZpbGUgc2hvdWxkIGluY2x1ZGUgYSBuYW1lIGFuZCBhIHR5cGUgKGpzb24gb3Igc3ZnKS4gSXQgbXVzdCBiZSBjb3JyZWN0bHkgZm9ybWF0dGVkIGFzIGEgSlNPTiBvciBTVkcgZmlsZS4nXG4gICAgfSxcbiAgICBpbnN0cjoge1xuICAgICAgdmFsdWU6IGZhbHNlLFxuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ0lucHV0LCBwcm92aWRlZCBpbiB0aGUgZm9ybSBvZiBhIHN0cmluZ2lmaWVkIEpTT04gb3IgU1ZHIGZpbGUsIHdpbGwgb3ZlcnJpZGUgdGhlIC0taW5maWxlIG9wdGlvbi4nXG4gICAgfSxcbiAgICBvcHRpb25zOiB7XG4gICAgICB2YWx1ZTogZmFsc2UsXG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIGRlc2NyaXB0aW9uOiAnQW4gYWxpYXMgZm9yIHRoZSAtLWluc3RyIG9wdGlvbi4nXG4gICAgfSxcbiAgICBvdXRmaWxlOiB7XG4gICAgICB2YWx1ZTogZmFsc2UsXG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnVGhlIG91dHB1dCBmaWxlbmFtZSBhbG9uZyB3aXRoIGEgdHlwZSAoanBlZywgcG5nLCBwZGYsIG9yIHN2ZykuIFRoaXMgd2lsbCBpZ25vcmUgdGhlIC0tdHlwZSBmbGFnLidcbiAgICB9LFxuICAgIHR5cGU6IHtcbiAgICAgIHZhbHVlOiAncG5nJyxcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgZW52TGluazogJ0VYUE9SVF9UWVBFJyxcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhlIGZpbGUgZXhwb3J0IGZvcm1hdC4gSXQgY2FuIGJlIGpwZWcsIHBuZywgcGRmLCBvciBzdmcuJ1xuICAgIH0sXG4gICAgY29uc3RyOiB7XG4gICAgICB2YWx1ZTogJ2NoYXJ0JyxcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgZW52TGluazogJ0VYUE9SVF9DT05TVFInLFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdUaGUgY29uc3RydWN0b3IgdG8gdXNlLiBDYW4gYmUgY2hhcnQsIHN0b2NrQ2hhcnQsIG1hcENoYXJ0LCBvciBnYW50dENoYXJ0LidcbiAgICB9LFxuICAgIGRlZmF1bHRIZWlnaHQ6IHtcbiAgICAgIHZhbHVlOiA0MDAsXG4gICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICAgIGVudkxpbms6ICdFWFBPUlRfREVGQVVMVF9IRUlHSFQnLFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICd0aGUgZGVmYXVsdCBoZWlnaHQgb2YgdGhlIGV4cG9ydGVkIGNoYXJ0LiBVc2VkIHdoZW4gbm8gdmFsdWUgaXMgc2V0LidcbiAgICB9LFxuICAgIGRlZmF1bHRXaWR0aDoge1xuICAgICAgdmFsdWU6IDYwMCxcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgZW52TGluazogJ0VYUE9SVF9ERUZBVUxUX1dJRFRIJyxcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnVGhlIGRlZmF1bHQgd2lkdGggb2YgdGhlIGV4cG9ydGVkIGNoYXJ0LiBVc2VkIHdoZW4gbm8gdmFsdWUgaXMgc2V0LidcbiAgICB9LFxuICAgIGRlZmF1bHRTY2FsZToge1xuICAgICAgdmFsdWU6IDEsXG4gICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICAgIGVudkxpbms6ICdFWFBPUlRfREVGQVVMVF9TQ0FMRScsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoZSBkZWZhdWx0IHNjYWxlIG9mIHRoZSBleHBvcnRlZCBjaGFydC4gVXNlZCB3aGVuIG5vIHZhbHVlIGlzIHNldC4nXG4gICAgfSxcbiAgICBoZWlnaHQ6IHtcbiAgICAgIHZhbHVlOiBmYWxzZSxcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdUaGUgaGVpZ2h0IG9mIHRoZSBleHBvcnRlZCBjaGFydCwgb3ZlcnJpZGluZyB0aGUgb3B0aW9uIGluIHRoZSBjaGFydCBzZXR0aW5ncy4nXG4gICAgfSxcbiAgICB3aWR0aDoge1xuICAgICAgdmFsdWU6IGZhbHNlLFxuICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoZSB3aWR0aCBvZiB0aGUgZXhwb3J0ZWQgY2hhcnQsIG92ZXJyaWRpbmcgdGhlIG9wdGlvbiBpbiB0aGUgY2hhcnQgc2V0dGluZ3MuJ1xuICAgIH0sXG4gICAgc2NhbGU6IHtcbiAgICAgIHZhbHVlOiBmYWxzZSxcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdUaGUgc2NhbGUgb2YgdGhlIGV4cG9ydGVkIGNoYXJ0LCBvdmVycmlkaW5nIHRoZSBvcHRpb24gaW4gdGhlIGNoYXJ0IHNldHRpbmdzLiBSYW5nZXMgYmV0d2VlbiAwLjEgYW5kIDUuMC4nXG4gICAgfSxcbiAgICBnbG9iYWxPcHRpb25zOiB7XG4gICAgICB2YWx1ZTogZmFsc2UsXG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnRWl0aGVyIGEgc3RyaW5naWZpZWQgSlNPTiBvciBhIGZpbGVuYW1lIGNvbnRhaW5pbmcgb3B0aW9ucyB0byBiZSBwYXNzZWQgaW50byB0aGUgSGlnaGNoYXJ0cy5zZXRPcHRpb25zLidcbiAgICB9LFxuICAgIHRoZW1lT3B0aW9uczoge1xuICAgICAgdmFsdWU6IGZhbHNlLFxuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ0VpdGhlciBhIHN0cmluZ2lmaWVkIEpTT04gb3IgYSBmaWxlbmFtZSBjb250YWluaW5nIHRoZW1lIG9wdGlvbnMgdG8gYmUgcGFzc2VkIGludG8gdGhlIEhpZ2hjaGFydHMuc2V0T3B0aW9ucy4nXG4gICAgfSxcbiAgICBiYXRjaDoge1xuICAgICAgdmFsdWU6IGZhbHNlLFxuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ0luaXRpYXRlcyBhIGJhdGNoIGpvYiB3aXRoIGEgc3RyaW5nIGNvbnRhaW5pbmcgaW5wdXQvb3V0cHV0IHBhaXJzOiBcImluPW91dDtpbj1vdXQ7Li4uXCIuJ1xuICAgIH0sXG4gICAgcmFzdGVyaXphdGlvblRpbWVvdXQ6IHtcbiAgICAgIHZhbHVlOiAxNTAwLFxuICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICBlbnZMaW5rOiAnRVhQT1JUX1JBU1RFUklaQVRJT05fVElNRU9VVCcsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoZSBkdXJhdGlvbiBpbiBtaWxsaXNlY29uZHMgdG8gd2FpdCBmb3IgcmVuZGVyaW5nIGEgd2VicGFnZS4nXG4gICAgfVxuICB9LFxuICBjdXN0b21Mb2dpYzoge1xuICAgIGFsbG93Q29kZUV4ZWN1dGlvbjoge1xuICAgICAgdmFsdWU6IGZhbHNlLFxuICAgICAgdHlwZTogJ2Jvb2xlYW4nLFxuICAgICAgZW52TGluazogJ0NVU1RPTV9MT0dJQ19BTExPV19DT0RFX0VYRUNVVElPTicsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ0NvbnRyb2xzIHdoZXRoZXIgdGhlIGV4ZWN1dGlvbiBvZiBhcmJpdHJhcnkgY29kZSBpcyBhbGxvd2VkIGR1cmluZyB0aGUgZXhwb3J0aW5nIHByb2Nlc3MuJ1xuICAgIH0sXG4gICAgYWxsb3dGaWxlUmVzb3VyY2VzOiB7XG4gICAgICB2YWx1ZTogZmFsc2UsXG4gICAgICB0eXBlOiAnYm9vbGVhbicsXG4gICAgICBlbnZMaW5rOiAnQ1VTVE9NX0xPR0lDX0FMTE9XX0ZJTEVfUkVTT1VSQ0VTJyxcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnQ29udHJvbHMgdGhlIGFiaWxpdHkgdG8gaW5qZWN0IHJlc291cmNlcyBmcm9tIHRoZSBmaWxlc3lzdGVtLiBUaGlzIHNldHRpbmcgaGFzIG5vIGVmZmVjdCB3aGVuIHJ1bm5pbmcgYXMgYSBzZXJ2ZXIuJ1xuICAgIH0sXG4gICAgY3VzdG9tQ29kZToge1xuICAgICAgdmFsdWU6IGZhbHNlLFxuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ0N1c3RvbSBjb2RlIHRvIGV4ZWN1dGUgYmVmb3JlIGNoYXJ0IGluaXRpYWxpemF0aW9uLiBJdCBjYW4gYmUgYSBmdW5jdGlvbiwgY29kZSB3cmFwcGVkIHdpdGhpbiBhIGZ1bmN0aW9uLCBvciBhIGZpbGVuYW1lIHdpdGggdGhlIC5qcyBleHRlbnNpb24uJ1xuICAgIH0sXG4gICAgY2FsbGJhY2s6IHtcbiAgICAgIHZhbHVlOiBmYWxzZSxcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdKYXZhU2NyaXB0IGNvZGUgdG8gcnVuIGR1cmluZyBjb25zdHJ1Y3Rpb24uIEl0IGNhbiBiZSBhIGZ1bmN0aW9uIG9yIGEgZmlsZW5hbWUgd2l0aCB0aGUgLmpzIGV4dGVuc2lvbi4nXG4gICAgfSxcbiAgICByZXNvdXJjZXM6IHtcbiAgICAgIHZhbHVlOiBmYWxzZSxcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdBZGRpdGlvbmFsIHJlc291cmNlIGluIHRoZSBmb3JtIG9mIGEgc3RyaW5naWZpZWQgSlNPTiwgd2hpY2ggbWF5IGNvbnRhaW4gZmlsZXMsIGpzLCBhbmQgY3NzIHNlY3Rpb25zLidcbiAgICB9LFxuICAgIGxvYWRDb25maWc6IHtcbiAgICAgIHZhbHVlOiBmYWxzZSxcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgbGVnYWN5TmFtZTogJ2Zyb21GaWxlJyxcbiAgICAgIGRlc2NyaXB0aW9uOiAnQSBmaWxlIGNvbnRhaW5pbmcgYSBwcmUtZGVmaW5lZCBjb25maWd1cmF0aW9uIHRvIHVzZS4nXG4gICAgfSxcbiAgICBjcmVhdGVDb25maWc6IHtcbiAgICAgIHZhbHVlOiBmYWxzZSxcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdFbmFibGVzIHNldHRpbmcgb3B0aW9ucyB0aHJvdWdoIGEgcHJvbXB0IGFuZCBzYXZpbmcgdGhlbSBpbiBhIHByb3ZpZGVkIGNvbmZpZyBmaWxlLidcbiAgICB9XG4gIH0sXG4gIHNlcnZlcjoge1xuICAgIG1heFVwbG9hZFNpemU6IHtcbiAgICAgIHZhbHVlOiAzLFxuICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICBlbnZMaW5rOiAnU0VSVkVSX01BWF9VUExPQURfU0laRScsXG4gICAgICBkZXNjcmlwdGlvbjogJ1RoZSBtYXhpbXVtIHVwbG9hZCBzaXplLCBpbiBNQiwgZm9yIHRoZSBzZXJ2ZXIuJ1xuICAgIH0sXG4gICAgZW5hYmxlOiB7XG4gICAgICB2YWx1ZTogZmFsc2UsXG4gICAgICB0eXBlOiAnYm9vbGVhbicsXG4gICAgICBlbnZMaW5rOiAnU0VSVkVSX0VOQUJMRScsXG4gICAgICBjbGlOYW1lOiAnZW5hYmxlU2VydmVyJyxcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnV2hlbiBzZXQgdG8gdHJ1ZSwgdGhlIHNlcnZlciBzdGFydHMgb24gdGhlIGxvY2FsIElQIGFkZHJlc3MgMC4wLjAuMC4nXG4gICAgfSxcbiAgICBob3N0OiB7XG4gICAgICB2YWx1ZTogJzAuMC4wLjAnLFxuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICBlbnZMaW5rOiAnU0VSVkVSX0hPU1QnLFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdUaGUgaG9zdG5hbWUgb2YgdGhlIHNlcnZlci4gQWRkaXRpb25hbGx5LCBpdCBzdGFydHMgYSBzZXJ2ZXIgb24gdGhlIHByb3ZpZGVkIGhvc3RuYW1lLidcbiAgICB9LFxuICAgIHBvcnQ6IHtcbiAgICAgIHZhbHVlOiA3ODAxLFxuICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICBlbnZMaW5rOiAnU0VSVkVSX1BPUlQnLFxuICAgICAgZGVzY3JpcHRpb246ICdUaGUgc2VydmVyIHBvcnQgd2hlbiBlbmFibGVkLidcbiAgICB9LFxuICAgIGJlbmNobWFya2luZzoge1xuICAgICAgdmFsdWU6IGZhbHNlLFxuICAgICAgdHlwZTogJ2Jvb2xlYW4nLFxuICAgICAgZW52TGluazogJ1NFUlZFUl9CRU5DSE1BUktJTkcnLFxuICAgICAgY2xpTmFtZTogJ3NlcnZlckJlbmNobWFya2luZycsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ0luZGljYXRlcyB3aGV0aGVyIHRvIGRpc3BsYXkgdGhlIGR1cmF0aW9uLCBpbiBtaWxsaXNlY29uZHMsIG9mIHNwZWNpZmljIGFjdGlvbnMgdGhhdCBvY2N1ciBvbiB0aGUgc2VydmVyIHdoaWxlIHNlcnZpbmcgYSByZXF1ZXN0LidcbiAgICB9LFxuICAgIHByb3h5OiB7XG4gICAgICBob3N0OiB7XG4gICAgICAgIHZhbHVlOiBmYWxzZSxcbiAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgIGVudkxpbms6ICdTRVJWRVJfUFJPWFlfSE9TVCcsXG4gICAgICAgIGNsaU5hbWU6ICdwcm94eUhvc3QnLFxuICAgICAgICBkZXNjcmlwdGlvbjogJ1RoZSBob3N0IG9mIHRoZSBwcm94eSBzZXJ2ZXIgdG8gdXNlLCBpZiBpdCBleGlzdHMuJ1xuICAgICAgfSxcbiAgICAgIHBvcnQ6IHtcbiAgICAgICAgdmFsdWU6IDgwODAsXG4gICAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgICBlbnZMaW5rOiAnU0VSVkVSX1BST1hZX1BPUlQnLFxuICAgICAgICBjbGlOYW1lOiAncHJveHlQb3J0JyxcbiAgICAgICAgZGVzY3JpcHRpb246ICdUaGUgcG9ydCBvZiB0aGUgcHJveHkgc2VydmVyIHRvIHVzZSwgaWYgaXQgZXhpc3RzLidcbiAgICAgIH0sXG4gICAgICB1c2VybmFtZToge1xuICAgICAgICB2YWx1ZTogZmFsc2UsXG4gICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICBlbnZMaW5rOiAnU0VSVkVSX1BST1hZX1VTRVJOQU1FJyxcbiAgICAgICAgY2xpTmFtZTogJ3Byb3h5VXNlcm5hbWUnLFxuICAgICAgICBkZXNjcmlwdGlvbjogJ1RoZSB1c2VybmFtZSBmb3IgdGhlIHByb3h5IHNlcnZlciwgaWYgaXQgZXhpc3RzLidcbiAgICAgIH0sXG4gICAgICBwYXNzd29yZDoge1xuICAgICAgICB2YWx1ZTogZmFsc2UsXG4gICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICBlbnZMaW5rOiAnU0VSVkVSX1BST1hZX1BBU1NXT1JEJyxcbiAgICAgICAgY2xpTmFtZTogJ3Byb3h5UGFzc3dvcmQnLFxuICAgICAgICBkZXNjcmlwdGlvbjogJ1RoZSBwYXNzd29yZCBmb3IgdGhlIHByb3h5IHNlcnZlciwgaWYgaXQgZXhpc3RzLidcbiAgICAgIH0sXG4gICAgICB0aW1lb3V0OiB7XG4gICAgICAgIHZhbHVlOiA1MDAwLFxuICAgICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICAgICAgZW52TGluazogJ1NFUlZFUl9QUk9YWV9USU1FT1VUJyxcbiAgICAgICAgY2xpTmFtZTogJ3Byb3h5VGltZW91dCcsXG4gICAgICAgIGRlc2NyaXB0aW9uOiAnVGhlIHRpbWVvdXQgZm9yIHRoZSBwcm94eSBzZXJ2ZXIgdG8gdXNlLCBpZiBpdCBleGlzdHMuJ1xuICAgICAgfVxuICAgIH0sXG4gICAgcmF0ZUxpbWl0aW5nOiB7XG4gICAgICBlbmFibGU6IHtcbiAgICAgICAgdmFsdWU6IGZhbHNlLFxuICAgICAgICB0eXBlOiAnYm9vbGVhbicsXG4gICAgICAgIGVudkxpbms6ICdTRVJWRVJfUkFURV9MSU1JVElOR19FTkFCTEUnLFxuICAgICAgICBjbGlOYW1lOiAnZW5hYmxlUmF0ZUxpbWl0aW5nJyxcbiAgICAgICAgZGVzY3JpcHRpb246ICdFbmFibGVzIHJhdGUgbGltaXRpbmcgZm9yIHRoZSBzZXJ2ZXIuJ1xuICAgICAgfSxcbiAgICAgIG1heFJlcXVlc3RzOiB7XG4gICAgICAgIHZhbHVlOiAxMCxcbiAgICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICAgIGVudkxpbms6ICdTRVJWRVJfUkFURV9MSU1JVElOR19NQVhfUkVRVUVTVFMnLFxuICAgICAgICBsZWdhY3lOYW1lOiAncmF0ZUxpbWl0JyxcbiAgICAgICAgZGVzY3JpcHRpb246ICdUaGUgbWF4aW11bSBudW1iZXIgb2YgcmVxdWVzdHMgYWxsb3dlZCBpbiBvbmUgbWludXRlLidcbiAgICAgIH0sXG4gICAgICB3aW5kb3c6IHtcbiAgICAgICAgdmFsdWU6IDEsXG4gICAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgICBlbnZMaW5rOiAnU0VSVkVSX1JBVEVfTElNSVRJTkdfV0lORE9XJyxcbiAgICAgICAgZGVzY3JpcHRpb246ICdUaGUgdGltZSB3aW5kb3csIGluIG1pbnV0ZXMsIGZvciB0aGUgcmF0ZSBsaW1pdGluZy4nXG4gICAgICB9LFxuICAgICAgZGVsYXk6IHtcbiAgICAgICAgdmFsdWU6IDAsXG4gICAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgICBlbnZMaW5rOiAnU0VSVkVSX1JBVEVfTElNSVRJTkdfREVMQVknLFxuICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAnVGhlIGRlbGF5IGR1cmF0aW9uIGZvciBlYWNoIHN1Y2Nlc3NpdmUgcmVxdWVzdCBiZWZvcmUgcmVhY2hpbmcgdGhlIG1heGltdW0gbGltaXQuJ1xuICAgICAgfSxcbiAgICAgIHRydXN0UHJveHk6IHtcbiAgICAgICAgdmFsdWU6IGZhbHNlLFxuICAgICAgICB0eXBlOiAnYm9vbGVhbicsXG4gICAgICAgIGVudkxpbms6ICdTRVJWRVJfUkFURV9MSU1JVElOR19UUlVTVF9QUk9YWScsXG4gICAgICAgIGRlc2NyaXB0aW9uOiAnU2V0IHRoaXMgdG8gdHJ1ZSBpZiB0aGUgc2VydmVyIGlzIGJlaGluZCBhIGxvYWQgYmFsYW5jZXIuJ1xuICAgICAgfSxcbiAgICAgIHNraXBLZXk6IHtcbiAgICAgICAgdmFsdWU6IGZhbHNlLFxuICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgZW52TGluazogJ1NFUlZFUl9SQVRFX0xJTUlUSU5HX1NLSVBfS0VZJyxcbiAgICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICAgJ0FsbG93cyBieXBhc3NpbmcgdGhlIHJhdGUgbGltaXRlciBhbmQgc2hvdWxkIGJlIHByb3ZpZGVkIHdpdGggdGhlIHNraXBUb2tlbiBhcmd1bWVudC4nXG4gICAgICB9LFxuICAgICAgc2tpcFRva2VuOiB7XG4gICAgICAgIHZhbHVlOiBmYWxzZSxcbiAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgIGVudkxpbms6ICdTRVJWRVJfUkFURV9MSU1JVElOR19TS0lQX1RPS0VOJyxcbiAgICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICAgJ0FsbG93cyBieXBhc3NpbmcgdGhlIHJhdGUgbGltaXRlciBhbmQgc2hvdWxkIGJlIHByb3ZpZGVkIHdpdGggdGhlIHNraXBLZXkgYXJndW1lbnQuJ1xuICAgICAgfVxuICAgIH0sXG4gICAgc3NsOiB7XG4gICAgICBlbmFibGU6IHtcbiAgICAgICAgdmFsdWU6IGZhbHNlLFxuICAgICAgICB0eXBlOiAnYm9vbGVhbicsXG4gICAgICAgIGVudkxpbms6ICdTRVJWRVJfU1NMX0VOQUJMRScsXG4gICAgICAgIGNsaU5hbWU6ICdlbmFibGVTc2wnLFxuICAgICAgICBkZXNjcmlwdGlvbjogJ0VuYWJsZXMgb3IgZGlzYWJsZXMgdGhlIFNTTCBwcm90b2NvbC4nXG4gICAgICB9LFxuICAgICAgZm9yY2U6IHtcbiAgICAgICAgdmFsdWU6IGZhbHNlLFxuICAgICAgICB0eXBlOiAnYm9vbGVhbicsXG4gICAgICAgIGVudkxpbms6ICdTRVJWRVJfU1NMX0ZPUkNFJyxcbiAgICAgICAgY2xpTmFtZTogJ3NzbEZvcmNlJyxcbiAgICAgICAgbGVnYWN5TmFtZTogJ3NzbE9ubHknLFxuICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAnV2hlbiBzZXQgdG8gdHJ1ZSwgdGhlIHNlcnZlciBpcyBmb3JjZWQgdG8gc2VydmUgb25seSBvdmVyIEhUVFBTLidcbiAgICAgIH0sXG4gICAgICBwb3J0OiB7XG4gICAgICAgIHZhbHVlOiA0NDMsXG4gICAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgICBlbnZMaW5rOiAnU0VSVkVSX1NTTF9QT1JUJyxcbiAgICAgICAgY2xpTmFtZTogJ3NzbFBvcnQnLFxuICAgICAgICBkZXNjcmlwdGlvbjogJ1RoZSBwb3J0IG9uIHdoaWNoIHRvIHJ1biB0aGUgU1NMIHNlcnZlci4nXG4gICAgICB9LFxuICAgICAgY2VydFBhdGg6IHtcbiAgICAgICAgdmFsdWU6IGZhbHNlLFxuICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgZW52TGluazogJ1NFUlZFUl9TU0xfQ0VSVF9QQVRIJyxcbiAgICAgICAgbGVnYWN5TmFtZTogJ3NzbFBhdGgnLFxuICAgICAgICBkZXNjcmlwdGlvbjogJ1RoZSBwYXRoIHRvIHRoZSBTU0wgY2VydGlmaWNhdGUva2V5IGZpbGUuJ1xuICAgICAgfVxuICAgIH1cbiAgfSxcbiAgcG9vbDoge1xuICAgIG1pbldvcmtlcnM6IHtcbiAgICAgIHZhbHVlOiA0LFxuICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICBlbnZMaW5rOiAnUE9PTF9NSU5fV09SS0VSUycsXG4gICAgICBkZXNjcmlwdGlvbjogJ1RoZSBudW1iZXIgb2YgbWluaW11bSBhbmQgaW5pdGlhbCBwb29sIHdvcmtlcnMgdG8gc3Bhd24uJ1xuICAgIH0sXG4gICAgbWF4V29ya2Vyczoge1xuICAgICAgdmFsdWU6IDgsXG4gICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICAgIGVudkxpbms6ICdQT09MX01BWF9XT1JLRVJTJyxcbiAgICAgIGxlZ2FjeU5hbWU6ICd3b3JrZXJzJyxcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhlIG51bWJlciBvZiBtYXhpbXVtIHBvb2wgd29ya2VycyB0byBzcGF3bi4nXG4gICAgfSxcbiAgICB3b3JrTGltaXQ6IHtcbiAgICAgIHZhbHVlOiA0MCxcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgZW52TGluazogJ1BPT0xfV09SS19MSU1JVCcsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoZSBudW1iZXIgb2Ygd29yayBwaWVjZXMgdGhhdCBjYW4gYmUgcGVyZm9ybWVkIGJlZm9yZSByZXN0YXJ0aW5nIHRoZSB3b3JrZXIgcHJvY2Vzcy4nXG4gICAgfSxcbiAgICBhY3F1aXJlVGltZW91dDoge1xuICAgICAgdmFsdWU6IDUwMDAsXG4gICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICAgIGVudkxpbms6ICdQT09MX0FDUVVJUkVfVElNRU9VVCcsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoZSBkdXJhdGlvbiwgaW4gbWlsbGlzZWNvbmRzLCB0byB3YWl0IGZvciBhY3F1aXJpbmcgYSByZXNvdXJjZS4nXG4gICAgfSxcbiAgICBjcmVhdGVUaW1lb3V0OiB7XG4gICAgICB2YWx1ZTogNTAwMCxcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgZW52TGluazogJ1BPT0xfQ1JFQVRFX1RJTUVPVVQnLFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdUaGUgZHVyYXRpb24sIGluIG1pbGxpc2Vjb25kcywgdG8gd2FpdCBmb3IgY3JlYXRpbmcgYSByZXNvdXJjZS4nXG4gICAgfSxcbiAgICBkZXN0cm95VGltZW91dDoge1xuICAgICAgdmFsdWU6IDUwMDAsXG4gICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICAgIGVudkxpbms6ICdQT09MX0RFU1RST1lfVElNRU9VVCcsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoZSBkdXJhdGlvbiwgaW4gbWlsbGlzZWNvbmRzLCB0byB3YWl0IGZvciBkZXN0cm95aW5nIGEgcmVzb3VyY2UuJ1xuICAgIH0sXG4gICAgaWRsZVRpbWVvdXQ6IHtcbiAgICAgIHZhbHVlOiAzMDAwMCxcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgZW52TGluazogJ1BPT0xfSURMRV9USU1FT1VUJyxcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnVGhlIGR1cmF0aW9uLCBpbiBtaWxsaXNlY29uZHMsIGFmdGVyIHdoaWNoIGFuIGlkbGUgcmVzb3VyY2UgaXMgZGVzdHJveWVkLidcbiAgICB9LFxuICAgIGNyZWF0ZVJldHJ5SW50ZXJ2YWw6IHtcbiAgICAgIHZhbHVlOiAyMDAsXG4gICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICAgIGVudkxpbms6ICdQT09MX0NSRUFURV9SRVRSWV9JTlRFUlZBTCcsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoZSBkdXJhdGlvbiwgaW4gbWlsbGlzZWNvbmRzLCB0byB3YWl0IGJlZm9yZSByZXRyeWluZyB0aGUgY3JlYXRlIHByb2Nlc3MgaW4gY2FzZSBvZiBhIGZhaWx1cmUuJ1xuICAgIH0sXG4gICAgcmVhcGVySW50ZXJ2YWw6IHtcbiAgICAgIHZhbHVlOiAxMDAwLFxuICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICBlbnZMaW5rOiAnUE9PTF9SRUFQRVJfSU5URVJWQUwnLFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdUaGUgZHVyYXRpb24sIGluIG1pbGxpc2Vjb25kcywgYWZ0ZXIgd2hpY2ggdGhlIGNoZWNrIGZvciBpZGxlIHJlc291cmNlcyB0byBkZXN0cm95IGlzIHRyaWdnZXJlZC4nXG4gICAgfSxcbiAgICBiZW5jaG1hcmtpbmc6IHtcbiAgICAgIHZhbHVlOiBmYWxzZSxcbiAgICAgIHR5cGU6ICdib29sZWFuJyxcbiAgICAgIGVudkxpbms6ICdQT09MX0JFTkNITUFSS0lORycsXG4gICAgICBjbGlOYW1lOiAncG9vbEJlbmNobWFya2luZycsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ0luZGljYXRlIHdoZXRoZXIgdG8gc2hvdyBzdGF0aXN0aWNzIGZvciB0aGUgcG9vbCBvZiByZXNvdXJjZXMgb3Igbm90LidcbiAgICB9XG4gIH0sXG4gIGxvZ2dpbmc6IHtcbiAgICBsZXZlbDoge1xuICAgICAgdmFsdWU6IDQsXG4gICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICAgIGVudkxpbms6ICdMT0dHSU5HX0xFVkVMJyxcbiAgICAgIGNsaU5hbWU6ICdsb2dMZXZlbCcsXG4gICAgICBkZXNjcmlwdGlvbjogJ1RoZSBsb2dnaW5nIGxldmVsIHRvIGJlIHVzZWQuJ1xuICAgIH0sXG4gICAgZmlsZToge1xuICAgICAgdmFsdWU6ICdoaWdoY2hhcnRzLWV4cG9ydC1zZXJ2ZXIubG9nJyxcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgZW52TGluazogJ0xPR0dJTkdfRklMRScsXG4gICAgICBjbGlOYW1lOiAnbG9nRmlsZScsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoZSBuYW1lIG9mIGEgbG9nIGZpbGUuIFRoZSBgbG9nVG9GaWxlYCBhbmQgYGxvZ0Rlc3RgIG9wdGlvbnMgYWxzbyBuZWVkIHRvIGJlIHNldCB0byBlbmFibGUgZmlsZSBsb2dnaW5nLidcbiAgICB9LFxuICAgIGRlc3Q6IHtcbiAgICAgIHZhbHVlOiAnbG9nLycsXG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIGVudkxpbms6ICdMT0dHSU5HX0RFU1QnLFxuICAgICAgY2xpTmFtZTogJ2xvZ0Rlc3QnLFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdUaGUgcGF0aCB0byBzdG9yZSBsb2cgZmlsZXMuIFRoZSBgbG9nVG9GaWxlYCBvcHRpb24gYWxzbyBuZWVkcyB0byBiZSBzZXQgdG8gZW5hYmxlIGZpbGUgbG9nZ2luZy4nXG4gICAgfSxcbiAgICB0b0NvbnNvbGU6IHtcbiAgICAgIHZhbHVlOiB0cnVlLFxuICAgICAgdHlwZTogJ2Jvb2xlYW4nLFxuICAgICAgZW52TGluazogJ0xPR0dJTkdfVE9fQ09OU09MRScsXG4gICAgICBjbGlOYW1lOiAnbG9nVG9Db25zb2xlJyxcbiAgICAgIGRlc2NyaXB0aW9uOiAnRW5hYmxlcyBvciBkaXNhYmxlcyBzaG93aW5nIGxvZ3MgaW4gdGhlIGNvbnNvbGUuJ1xuICAgIH0sXG4gICAgdG9GaWxlOiB7XG4gICAgICB2YWx1ZTogdHJ1ZSxcbiAgICAgIHR5cGU6ICdib29sZWFuJyxcbiAgICAgIGVudkxpbms6ICdMT0dHSU5HX1RPX0ZJTEUnLFxuICAgICAgY2xpTmFtZTogJ2xvZ1RvRmlsZScsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ0VuYWJsZXMgb3IgZGlzYWJsZXMgY3JlYXRpb24gb2YgdGhlIGxvZyBkaXJlY3RvcnkgYW5kIHNhdmluZyB0aGUgbG9nIGludG8gYSAubG9nIGZpbGUuJ1xuICAgIH1cbiAgfSxcbiAgdWk6IHtcbiAgICBlbmFibGU6IHtcbiAgICAgIHZhbHVlOiBmYWxzZSxcbiAgICAgIHR5cGU6ICdib29sZWFuJyxcbiAgICAgIGVudkxpbms6ICdVSV9FTkFCTEUnLFxuICAgICAgY2xpTmFtZTogJ2VuYWJsZVVpJyxcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnRW5hYmxlcyBvciBkaXNhYmxlcyB0aGUgdXNlciBpbnRlcmZhY2UgKFVJKSBmb3IgdGhlIGV4cG9ydCBzZXJ2ZXIuJ1xuICAgIH0sXG4gICAgcm91dGU6IHtcbiAgICAgIHZhbHVlOiAnLycsXG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIGVudkxpbms6ICdVSV9ST1VURScsXG4gICAgICBjbGlOYW1lOiAndWlSb3V0ZScsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoZSBlbmRwb2ludCByb3V0ZSB0byB3aGljaCB0aGUgdXNlciBpbnRlcmZhY2UgKFVJKSBzaG91bGQgYmUgYXR0YWNoZWQuJ1xuICAgIH1cbiAgfSxcbiAgb3RoZXI6IHtcbiAgICBub2RlRW52OiB7XG4gICAgICB2YWx1ZTogJ3Byb2R1Y3Rpb24nLFxuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICBlbnZMaW5rOiAnT1RIRVJfTk9ERV9FTlYnLFxuICAgICAgZGVzY3JpcHRpb246ICdUaGUgdHlwZSBvZiBOb2RlLmpzIGVudmlyb25tZW50LidcbiAgICB9LFxuICAgIGxpc3RlblRvUHJvY2Vzc0V4aXRzOiB7XG4gICAgICB2YWx1ZTogdHJ1ZSxcbiAgICAgIHR5cGU6ICdib29sZWFuJyxcbiAgICAgIGVudkxpbms6ICdPVEhFUl9MSVNURU5fVE9fUFJPQ0VTU19FWElUUycsXG4gICAgICBkZXNjcmlwdGlvbjogJ0RlY2lkZXMgd2hldGhlciBvciBub3QgdG8gYXR0YWNoIHByb2Nlc3MuZXhpdCBoYW5kbGVycy4nXG4gICAgfSxcbiAgICBub0xvZ286IHtcbiAgICAgIHZhbHVlOiBmYWxzZSxcbiAgICAgIHR5cGU6ICdib29sZWFuJyxcbiAgICAgIGVudkxpbms6ICdPVEhFUl9OT19MT0dPJyxcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnU2tpcCBwcmludGluZyB0aGUgbG9nbyBvbiBhIHN0YXJ0dXAuIFdpbGwgYmUgcmVwbGFjZWQgYnkgYSBzaW1wbGUgdGV4dC4nXG4gICAgfSxcbiAgICBoYXJkUmVzZXRQYWdlOiB7XG4gICAgICB2YWx1ZTogZmFsc2UsXG4gICAgICB0eXBlOiAnYm9vbGVhbicsXG4gICAgICBlbnZMaW5rOiAnT1RIRVJfSEFSRF9SRVNFVF9QQUdFJyxcbiAgICAgIGRlc2NyaXB0aW9uOiAnRGVjaWRlcyBpZiB0aGUgcGFnZSBjb250ZW50IHNob3VsZCBiZSByZXNldCBlbnRpcmVseS4nXG4gICAgfSxcbiAgICBicm93c2VyU2hlbGxNb2RlOiB7XG4gICAgICB2YWx1ZTogdHJ1ZSxcbiAgICAgIHR5cGU6ICdib29sZWFuJyxcbiAgICAgIGVudkxpbms6ICdPVEhFUl9CUk9XU0VSX1NIRUxMX01PREUnLFxuICAgICAgZGVzY3JpcHRpb246ICdEZWNpZGVzIGlmIHRoZSBicm93c2VyIHJ1bnMgaW4gdGhlIHNoZWxsIG1vZGUuJ1xuICAgIH1cbiAgfSxcbiAgZGVidWc6IHtcbiAgICBlbmFibGU6IHtcbiAgICAgIHZhbHVlOiBmYWxzZSxcbiAgICAgIHR5cGU6ICdib29sZWFuJyxcbiAgICAgIGVudkxpbms6ICdERUJVR19FTkFCTEUnLFxuICAgICAgY2xpTmFtZTogJ2VuYWJsZURlYnVnJyxcbiAgICAgIGRlc2NyaXB0aW9uOiAnRW5hYmxlcyBvciBkaXNhYmxlcyBkZWJ1ZyBtb2RlIGZvciB0aGUgdW5kZXJseWluZyBicm93c2VyLidcbiAgICB9LFxuICAgIGhlYWRsZXNzOiB7XG4gICAgICB2YWx1ZTogdHJ1ZSxcbiAgICAgIHR5cGU6ICdib29sZWFuJyxcbiAgICAgIGVudkxpbms6ICdERUJVR19IRUFETEVTUycsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ0NvbnRyb2xzIHRoZSBtb2RlIGluIHdoaWNoIHRoZSBicm93c2VyIGlzIGxhdW5jaGVkIHdoZW4gaW4gdGhlIGRlYnVnIG1vZGUuJ1xuICAgIH0sXG4gICAgZGV2dG9vbHM6IHtcbiAgICAgIHZhbHVlOiBmYWxzZSxcbiAgICAgIHR5cGU6ICdib29sZWFuJyxcbiAgICAgIGVudkxpbms6ICdERUJVR19ERVZUT09MUycsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ0RlY2lkZXMgd2hldGhlciB0byBlbmFibGUgRGV2VG9vbHMgd2hlbiB0aGUgYnJvd3NlciBpcyBpbiBhIGhlYWRmdWwgc3RhdGUuJ1xuICAgIH0sXG4gICAgbGlzdGVuVG9Db25zb2xlOiB7XG4gICAgICB2YWx1ZTogZmFsc2UsXG4gICAgICB0eXBlOiAnYm9vbGVhbicsXG4gICAgICBlbnZMaW5rOiAnREVCVUdfTElTVEVOX1RPX0NPTlNPTEUnLFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdEZWNpZGVzIHdoZXRoZXIgdG8gZW5hYmxlIGEgbGlzdGVuZXIgZm9yIGNvbnNvbGUgbWVzc2FnZXMgc2VudCBmcm9tIHRoZSBicm93c2VyLidcbiAgICB9LFxuICAgIGR1bXBpbzoge1xuICAgICAgdmFsdWU6IGZhbHNlLFxuICAgICAgdHlwZTogJ2Jvb2xlYW4nLFxuICAgICAgZW52TGluazogJ0RFQlVHX0RVTVBJTycsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1JlZGlyZWN0cyBicm93c2VyIHByb2Nlc3Mgc3Rkb3V0IGFuZCBzdGRlcnIgdG8gcHJvY2Vzcy5zdGRvdXQgYW5kIHByb2Nlc3Muc3RkZXJyLidcbiAgICB9LFxuICAgIHNsb3dNbzoge1xuICAgICAgdmFsdWU6IDAsXG4gICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICAgIGVudkxpbms6ICdERUJVR19TTE9XX01PJyxcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnU2xvd3MgZG93biBQdXBwZXRlZXIgb3BlcmF0aW9ucyBieSB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiBtaWxsaXNlY29uZHMuJ1xuICAgIH0sXG4gICAgZGVidWdnaW5nUG9ydDoge1xuICAgICAgdmFsdWU6IDkyMjIsXG4gICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICAgIGVudkxpbms6ICdERUJVR19ERUJVR0dJTkdfUE9SVCcsXG4gICAgICBkZXNjcmlwdGlvbjogJ1NwZWNpZmllcyB0aGUgZGVidWdnaW5nIHBvcnQuJ1xuICAgIH1cbiAgfVxufTtcblxuLy8gVGhlIGNvbmZpZyBkZXNjcmlwdGlvbnMgb2JqZWN0IGZvciB0aGUgcHJvbXB0cyBmdW5jdGlvbmFsaXR5LiBJdCBjb250YWluc1xuLy8gaW5mb3JtYXRpb24gbGlrZTpcbi8vICogVHlwZSBvZiBhIHByb21wdFxuLy8gKiBOYW1lIG9mIGFuIG9wdGlvblxuLy8gKiBTaG9ydCBkZXNjcmlwdGlvbiBvZiBhIGNob3NlbiBvcHRpb25cbi8vICogSW5pdGlhbCB2YWx1ZVxuZXhwb3J0IGNvbnN0IHByb21wdHNDb25maWcgPSB7XG4gIHB1cHBldGVlcjogW1xuICAgIHtcbiAgICAgIHR5cGU6ICdsaXN0JyxcbiAgICAgIG5hbWU6ICdhcmdzJyxcbiAgICAgIG1lc3NhZ2U6ICdQdXBwZXRlZXIgYXJndW1lbnRzJyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcucHVwcGV0ZWVyLmFyZ3MudmFsdWUuam9pbignLCcpLFxuICAgICAgc2VwYXJhdG9yOiAnLCdcbiAgICB9XG4gIF0sXG4gIGhpZ2hjaGFydHM6IFtcbiAgICB7XG4gICAgICB0eXBlOiAndGV4dCcsXG4gICAgICBuYW1lOiAndmVyc2lvbicsXG4gICAgICBtZXNzYWdlOiAnSGlnaGNoYXJ0cyB2ZXJzaW9uJyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcuaGlnaGNoYXJ0cy52ZXJzaW9uLnZhbHVlXG4gICAgfSxcbiAgICB7XG4gICAgICB0eXBlOiAndGV4dCcsXG4gICAgICBuYW1lOiAnY2RuVVJMJyxcbiAgICAgIG1lc3NhZ2U6ICdUaGUgVVJMIG9mIENETicsXG4gICAgICBpbml0aWFsOiBkZWZhdWx0Q29uZmlnLmhpZ2hjaGFydHMuY2RuVVJMLnZhbHVlXG4gICAgfSxcbiAgICB7XG4gICAgICB0eXBlOiAnbXVsdGlzZWxlY3QnLFxuICAgICAgbmFtZTogJ2NvcmVTY3JpcHRzJyxcbiAgICAgIG1lc3NhZ2U6ICdBdmFpbGFibGUgY29yZSBzY3JpcHRzJyxcbiAgICAgIGluc3RydWN0aW9uczogJ1NwYWNlOiBTZWxlY3Qgc3BlY2lmaWMsIEE6IFNlbGVjdCBhbGwsIEVudGVyOiBDb25maXJtLicsXG4gICAgICBjaG9pY2VzOiBkZWZhdWx0Q29uZmlnLmhpZ2hjaGFydHMuY29yZVNjcmlwdHMudmFsdWVcbiAgICB9LFxuICAgIHtcbiAgICAgIHR5cGU6ICdtdWx0aXNlbGVjdCcsXG4gICAgICBuYW1lOiAnbW9kdWxlU2NyaXB0cycsXG4gICAgICBtZXNzYWdlOiAnQXZhaWxhYmxlIG1vZHVsZSBzY3JpcHRzJyxcbiAgICAgIGluc3RydWN0aW9uczogJ1NwYWNlOiBTZWxlY3Qgc3BlY2lmaWMsIEE6IFNlbGVjdCBhbGwsIEVudGVyOiBDb25maXJtLicsXG4gICAgICBjaG9pY2VzOiBkZWZhdWx0Q29uZmlnLmhpZ2hjaGFydHMubW9kdWxlU2NyaXB0cy52YWx1ZVxuICAgIH0sXG4gICAge1xuICAgICAgdHlwZTogJ211bHRpc2VsZWN0JyxcbiAgICAgIG5hbWU6ICdpbmRpY2F0b3JTY3JpcHRzJyxcbiAgICAgIG1lc3NhZ2U6ICdBdmFpbGFibGUgaW5kaWNhdG9yIHNjcmlwdHMnLFxuICAgICAgaW5zdHJ1Y3Rpb25zOiAnU3BhY2U6IFNlbGVjdCBzcGVjaWZpYywgQTogU2VsZWN0IGFsbCwgRW50ZXI6IENvbmZpcm0uJyxcbiAgICAgIGNob2ljZXM6IGRlZmF1bHRDb25maWcuaGlnaGNoYXJ0cy5pbmRpY2F0b3JTY3JpcHRzLnZhbHVlXG4gICAgfSxcbiAgICB7XG4gICAgICB0eXBlOiAnbGlzdCcsXG4gICAgICBuYW1lOiAnY3VzdG9tU2NyaXB0cycsXG4gICAgICBtZXNzYWdlOiAnQ3VzdG9tIHNjcmlwdHMnLFxuICAgICAgaW5pdGlhbDogZGVmYXVsdENvbmZpZy5oaWdoY2hhcnRzLmN1c3RvbVNjcmlwdHMudmFsdWUuam9pbignLCcpLFxuICAgICAgc2VwYXJhdG9yOiAnLCdcbiAgICB9LFxuICAgIHtcbiAgICAgIHR5cGU6ICd0b2dnbGUnLFxuICAgICAgbmFtZTogJ2ZvcmNlRmV0Y2gnLFxuICAgICAgbWVzc2FnZTogJ0ZvcmNlIHJlLWZldGNoIHRoZSBzY3JpcHRzJyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcuaGlnaGNoYXJ0cy5mb3JjZUZldGNoLnZhbHVlXG4gICAgfSxcbiAgICB7XG4gICAgICB0eXBlOiAndGV4dCcsXG4gICAgICBuYW1lOiAnY2FjaGVQYXRoJyxcbiAgICAgIG1lc3NhZ2U6ICdUaGUgcGF0aCB0byB0aGUgY2FjaGUgZGlyZWN0b3J5JyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcuaGlnaGNoYXJ0cy5jYWNoZVBhdGgudmFsdWVcbiAgICB9XG4gIF0sXG4gIGV4cG9ydDogW1xuICAgIHtcbiAgICAgIHR5cGU6ICdzZWxlY3QnLFxuICAgICAgbmFtZTogJ3R5cGUnLFxuICAgICAgbWVzc2FnZTogJ1RoZSBkZWZhdWx0IGV4cG9ydCBmaWxlIHR5cGUnLFxuICAgICAgaGludDogYERlZmF1bHQ6ICR7ZGVmYXVsdENvbmZpZy5leHBvcnQudHlwZS52YWx1ZX1gLFxuICAgICAgaW5pdGlhbDogMCxcbiAgICAgIGNob2ljZXM6IFsncG5nJywgJ2pwZWcnLCAncGRmJywgJ3N2ZyddXG4gICAgfSxcbiAgICB7XG4gICAgICB0eXBlOiAnc2VsZWN0JyxcbiAgICAgIG5hbWU6ICdjb25zdHInLFxuICAgICAgbWVzc2FnZTogJ1RoZSBkZWZhdWx0IGNvbnN0cnVjdG9yIGZvciBIaWdoY2hhcnRzJyxcbiAgICAgIGhpbnQ6IGBEZWZhdWx0OiAke2RlZmF1bHRDb25maWcuZXhwb3J0LmNvbnN0ci52YWx1ZX1gLFxuICAgICAgaW5pdGlhbDogMCxcbiAgICAgIGNob2ljZXM6IFsnY2hhcnQnLCAnc3RvY2tDaGFydCcsICdtYXBDaGFydCcsICdnYW50dENoYXJ0J11cbiAgICB9LFxuICAgIHtcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgbmFtZTogJ2RlZmF1bHRIZWlnaHQnLFxuICAgICAgbWVzc2FnZTogJ1RoZSBkZWZhdWx0IGZhbGxiYWNrIGhlaWdodCBvZiB0aGUgZXhwb3J0ZWQgY2hhcnQnLFxuICAgICAgaW5pdGlhbDogZGVmYXVsdENvbmZpZy5leHBvcnQuZGVmYXVsdEhlaWdodC52YWx1ZVxuICAgIH0sXG4gICAge1xuICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICBuYW1lOiAnZGVmYXVsdFdpZHRoJyxcbiAgICAgIG1lc3NhZ2U6ICdUaGUgZGVmYXVsdCBmYWxsYmFjayB3aWR0aCBvZiB0aGUgZXhwb3J0ZWQgY2hhcnQnLFxuICAgICAgaW5pdGlhbDogZGVmYXVsdENvbmZpZy5leHBvcnQuZGVmYXVsdFdpZHRoLnZhbHVlXG4gICAgfSxcbiAgICB7XG4gICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICAgIG5hbWU6ICdkZWZhdWx0U2NhbGUnLFxuICAgICAgbWVzc2FnZTogJ1RoZSBkZWZhdWx0IGZhbGxiYWNrIHNjYWxlIG9mIHRoZSBleHBvcnRlZCBjaGFydCcsXG4gICAgICBpbml0aWFsOiBkZWZhdWx0Q29uZmlnLmV4cG9ydC5kZWZhdWx0U2NhbGUudmFsdWUsXG4gICAgICBtaW46IDAuMSxcbiAgICAgIG1heDogNVxuICAgIH0sXG4gICAge1xuICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICBuYW1lOiAncmFzdGVyaXphdGlvblRpbWVvdXQnLFxuICAgICAgbWVzc2FnZTogJ1RoZSByZW5kZXJpbmcgd2VicGFnZSB0aW1lb3V0IGluIG1pbGxpc2Vjb25kcycsXG4gICAgICBpbml0aWFsOiBkZWZhdWx0Q29uZmlnLmV4cG9ydC5yYXN0ZXJpemF0aW9uVGltZW91dC52YWx1ZVxuICAgIH1cbiAgXSxcbiAgY3VzdG9tTG9naWM6IFtcbiAgICB7XG4gICAgICB0eXBlOiAndG9nZ2xlJyxcbiAgICAgIG5hbWU6ICdhbGxvd0NvZGVFeGVjdXRpb24nLFxuICAgICAgbWVzc2FnZTogJ0VuYWJsZSBleGVjdXRpb24gb2YgY3VzdG9tIGNvZGUnLFxuICAgICAgaW5pdGlhbDogZGVmYXVsdENvbmZpZy5jdXN0b21Mb2dpYy5hbGxvd0NvZGVFeGVjdXRpb24udmFsdWVcbiAgICB9LFxuICAgIHtcbiAgICAgIHR5cGU6ICd0b2dnbGUnLFxuICAgICAgbmFtZTogJ2FsbG93RmlsZVJlc291cmNlcycsXG4gICAgICBtZXNzYWdlOiAnRW5hYmxlIGZpbGUgcmVzb3VyY2VzJyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcuY3VzdG9tTG9naWMuYWxsb3dGaWxlUmVzb3VyY2VzLnZhbHVlXG4gICAgfVxuICBdLFxuICBzZXJ2ZXI6IFtcbiAgICB7XG4gICAgICB0eXBlOiAndG9nZ2xlJyxcbiAgICAgIG5hbWU6ICdlbmFibGUnLFxuICAgICAgbWVzc2FnZTogJ1N0YXJ0cyB0aGUgc2VydmVyIG9uIDAuMC4wLjAnLFxuICAgICAgaW5pdGlhbDogZGVmYXVsdENvbmZpZy5zZXJ2ZXIuZW5hYmxlLnZhbHVlXG4gICAgfSxcbiAgICB7XG4gICAgICB0eXBlOiAndGV4dCcsXG4gICAgICBuYW1lOiAnaG9zdCcsXG4gICAgICBtZXNzYWdlOiAnU2VydmVyIGhvc3RuYW1lJyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcuc2VydmVyLmhvc3QudmFsdWVcbiAgICB9LFxuICAgIHtcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgbmFtZTogJ3BvcnQnLFxuICAgICAgbWVzc2FnZTogJ1NlcnZlciBwb3J0JyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcuc2VydmVyLnBvcnQudmFsdWVcbiAgICB9LFxuICAgIHtcbiAgICAgIHR5cGU6ICd0b2dnbGUnLFxuICAgICAgbmFtZTogJ2JlbmNobWFya2luZycsXG4gICAgICBtZXNzYWdlOiAnRW5hYmxlIHNlcnZlciBiZW5jaG1hcmtpbmcnLFxuICAgICAgaW5pdGlhbDogZGVmYXVsdENvbmZpZy5zZXJ2ZXIuYmVuY2htYXJraW5nLnZhbHVlXG4gICAgfSxcbiAgICB7XG4gICAgICB0eXBlOiAndGV4dCcsXG4gICAgICBuYW1lOiAncHJveHkuaG9zdCcsXG4gICAgICBtZXNzYWdlOiAnVGhlIGhvc3Qgb2YgdGhlIHByb3h5IHNlcnZlciB0byB1c2UnLFxuICAgICAgaW5pdGlhbDogZGVmYXVsdENvbmZpZy5zZXJ2ZXIucHJveHkuaG9zdC52YWx1ZVxuICAgIH0sXG4gICAge1xuICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICBuYW1lOiAncHJveHkucG9ydCcsXG4gICAgICBtZXNzYWdlOiAnVGhlIHBvcnQgb2YgdGhlIHByb3h5IHNlcnZlciB0byB1c2UnLFxuICAgICAgaW5pdGlhbDogZGVmYXVsdENvbmZpZy5zZXJ2ZXIucHJveHkucG9ydC52YWx1ZVxuICAgIH0sXG4gICAge1xuICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICBuYW1lOiAncHJveHkudGltZW91dCcsXG4gICAgICBtZXNzYWdlOiAnVGhlIHRpbWVvdXQgZm9yIHRoZSBwcm94eSBzZXJ2ZXIgdG8gdXNlJyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcuc2VydmVyLnByb3h5LnRpbWVvdXQudmFsdWVcbiAgICB9LFxuICAgIHtcbiAgICAgIHR5cGU6ICd0b2dnbGUnLFxuICAgICAgbmFtZTogJ3JhdGVMaW1pdGluZy5lbmFibGUnLFxuICAgICAgbWVzc2FnZTogJ0VuYWJsZSByYXRlIGxpbWl0aW5nJyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcuc2VydmVyLnJhdGVMaW1pdGluZy5lbmFibGUudmFsdWVcbiAgICB9LFxuICAgIHtcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgbmFtZTogJ3JhdGVMaW1pdGluZy5tYXhSZXF1ZXN0cycsXG4gICAgICBtZXNzYWdlOiAnVGhlIG1heGltdW0gcmVxdWVzdHMgYWxsb3dlZCBwZXIgbWludXRlJyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcuc2VydmVyLnJhdGVMaW1pdGluZy5tYXhSZXF1ZXN0cy52YWx1ZVxuICAgIH0sXG4gICAge1xuICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICBuYW1lOiAncmF0ZUxpbWl0aW5nLndpbmRvdycsXG4gICAgICBtZXNzYWdlOiAnVGhlIHJhdGUtbGltaXRpbmcgdGltZSB3aW5kb3cgaW4gbWludXRlcycsXG4gICAgICBpbml0aWFsOiBkZWZhdWx0Q29uZmlnLnNlcnZlci5yYXRlTGltaXRpbmcud2luZG93LnZhbHVlXG4gICAgfSxcbiAgICB7XG4gICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICAgIG5hbWU6ICdyYXRlTGltaXRpbmcuZGVsYXknLFxuICAgICAgbWVzc2FnZTpcbiAgICAgICAgJ1RoZSBkZWxheSBmb3IgZWFjaCBzdWNjZXNzaXZlIHJlcXVlc3QgYmVmb3JlIHJlYWNoaW5nIHRoZSBtYXhpbXVtJyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcuc2VydmVyLnJhdGVMaW1pdGluZy5kZWxheS52YWx1ZVxuICAgIH0sXG4gICAge1xuICAgICAgdHlwZTogJ3RvZ2dsZScsXG4gICAgICBuYW1lOiAncmF0ZUxpbWl0aW5nLnRydXN0UHJveHknLFxuICAgICAgbWVzc2FnZTogJ1NldCB0byB0cnVlIGlmIGJlaGluZCBhIGxvYWQgYmFsYW5jZXInLFxuICAgICAgaW5pdGlhbDogZGVmYXVsdENvbmZpZy5zZXJ2ZXIucmF0ZUxpbWl0aW5nLnRydXN0UHJveHkudmFsdWVcbiAgICB9LFxuICAgIHtcbiAgICAgIHR5cGU6ICd0ZXh0JyxcbiAgICAgIG5hbWU6ICdyYXRlTGltaXRpbmcuc2tpcEtleScsXG4gICAgICBtZXNzYWdlOlxuICAgICAgICAnQWxsb3dzIGJ5cGFzc2luZyB0aGUgcmF0ZSBsaW1pdGVyIHdoZW4gcHJvdmlkZWQgd2l0aCB0aGUgc2tpcFRva2VuIGFyZ3VtZW50JyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcuc2VydmVyLnJhdGVMaW1pdGluZy5za2lwS2V5LnZhbHVlXG4gICAgfSxcbiAgICB7XG4gICAgICB0eXBlOiAndGV4dCcsXG4gICAgICBuYW1lOiAncmF0ZUxpbWl0aW5nLnNraXBUb2tlbicsXG4gICAgICBtZXNzYWdlOlxuICAgICAgICAnQWxsb3dzIGJ5cGFzc2luZyB0aGUgcmF0ZSBsaW1pdGVyIHdoZW4gcHJvdmlkZWQgd2l0aCB0aGUgc2tpcEtleSBhcmd1bWVudCcsXG4gICAgICBpbml0aWFsOiBkZWZhdWx0Q29uZmlnLnNlcnZlci5yYXRlTGltaXRpbmcuc2tpcFRva2VuLnZhbHVlXG4gICAgfSxcbiAgICB7XG4gICAgICB0eXBlOiAndG9nZ2xlJyxcbiAgICAgIG5hbWU6ICdzc2wuZW5hYmxlJyxcbiAgICAgIG1lc3NhZ2U6ICdFbmFibGUgU1NMIHByb3RvY29sJyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcuc2VydmVyLnNzbC5lbmFibGUudmFsdWVcbiAgICB9LFxuICAgIHtcbiAgICAgIHR5cGU6ICd0b2dnbGUnLFxuICAgICAgbmFtZTogJ3NzbC5mb3JjZScsXG4gICAgICBtZXNzYWdlOiAnRm9yY2Ugc2VydmluZyBvbmx5IG92ZXIgSFRUUFMnLFxuICAgICAgaW5pdGlhbDogZGVmYXVsdENvbmZpZy5zZXJ2ZXIuc3NsLmZvcmNlLnZhbHVlXG4gICAgfSxcbiAgICB7XG4gICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICAgIG5hbWU6ICdzc2wucG9ydCcsXG4gICAgICBtZXNzYWdlOiAnU1NMIHNlcnZlciBwb3J0JyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcuc2VydmVyLnNzbC5wb3J0LnZhbHVlXG4gICAgfSxcbiAgICB7XG4gICAgICB0eXBlOiAndGV4dCcsXG4gICAgICBuYW1lOiAnc3NsLmNlcnRQYXRoJyxcbiAgICAgIG1lc3NhZ2U6ICdUaGUgcGF0aCB0byBmaW5kIHRoZSBTU0wgY2VydGlmaWNhdGUva2V5JyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcuc2VydmVyLnNzbC5jZXJ0UGF0aC52YWx1ZVxuICAgIH1cbiAgXSxcbiAgcG9vbDogW1xuICAgIHtcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgbmFtZTogJ21pbldvcmtlcnMnLFxuICAgICAgbWVzc2FnZTogJ1RoZSBpbml0aWFsIG51bWJlciBvZiB3b3JrZXJzIHRvIHNwYXduJyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcucG9vbC5taW5Xb3JrZXJzLnZhbHVlXG4gICAgfSxcbiAgICB7XG4gICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICAgIG5hbWU6ICdtYXhXb3JrZXJzJyxcbiAgICAgIG1lc3NhZ2U6ICdUaGUgbWF4aW11bSBudW1iZXIgb2Ygd29ya2VycyB0byBzcGF3bicsXG4gICAgICBpbml0aWFsOiBkZWZhdWx0Q29uZmlnLnBvb2wubWF4V29ya2Vycy52YWx1ZVxuICAgIH0sXG4gICAge1xuICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICBuYW1lOiAnd29ya0xpbWl0JyxcbiAgICAgIG1lc3NhZ2U6XG4gICAgICAgICdUaGUgcGllY2VzIG9mIHdvcmsgdGhhdCBjYW4gYmUgcGVyZm9ybWVkIGJlZm9yZSByZXN0YXJ0aW5nIGEgUHVwcGV0ZWVyIHByb2Nlc3MnLFxuICAgICAgaW5pdGlhbDogZGVmYXVsdENvbmZpZy5wb29sLndvcmtMaW1pdC52YWx1ZVxuICAgIH0sXG4gICAge1xuICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICBuYW1lOiAnYWNxdWlyZVRpbWVvdXQnLFxuICAgICAgbWVzc2FnZTogJ1RoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIHRvIHdhaXQgZm9yIGFjcXVpcmluZyBhIHJlc291cmNlJyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcucG9vbC5hY3F1aXJlVGltZW91dC52YWx1ZVxuICAgIH0sXG4gICAge1xuICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICBuYW1lOiAnY3JlYXRlVGltZW91dCcsXG4gICAgICBtZXNzYWdlOiAnVGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgdG8gd2FpdCBmb3IgY3JlYXRpbmcgYSByZXNvdXJjZScsXG4gICAgICBpbml0aWFsOiBkZWZhdWx0Q29uZmlnLnBvb2wuY3JlYXRlVGltZW91dC52YWx1ZVxuICAgIH0sXG4gICAge1xuICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICBuYW1lOiAnZGVzdHJveVRpbWVvdXQnLFxuICAgICAgbWVzc2FnZTogJ1RoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIHRvIHdhaXQgZm9yIGRlc3Ryb3lpbmcgYSByZXNvdXJjZScsXG4gICAgICBpbml0aWFsOiBkZWZhdWx0Q29uZmlnLnBvb2wuZGVzdHJveVRpbWVvdXQudmFsdWVcbiAgICB9LFxuICAgIHtcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgbmFtZTogJ2lkbGVUaW1lb3V0JyxcbiAgICAgIG1lc3NhZ2U6ICdUaGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBhZnRlciBhbiBpZGxlIHJlc291cmNlIGlzIGRlc3Ryb3llZCcsXG4gICAgICBpbml0aWFsOiBkZWZhdWx0Q29uZmlnLnBvb2wuaWRsZVRpbWVvdXQudmFsdWVcbiAgICB9LFxuICAgIHtcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgbmFtZTogJ2NyZWF0ZVJldHJ5SW50ZXJ2YWwnLFxuICAgICAgbWVzc2FnZTpcbiAgICAgICAgJ1RoZSByZXRyeSBpbnRlcnZhbCBpbiBtaWxsaXNlY29uZHMgYWZ0ZXIgYSBjcmVhdGUgcHJvY2VzcyBmYWlscycsXG4gICAgICBpbml0aWFsOiBkZWZhdWx0Q29uZmlnLnBvb2wuY3JlYXRlUmV0cnlJbnRlcnZhbC52YWx1ZVxuICAgIH0sXG4gICAge1xuICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICBuYW1lOiAncmVhcGVySW50ZXJ2YWwnLFxuICAgICAgbWVzc2FnZTpcbiAgICAgICAgJ1RoZSByZWFwZXIgaW50ZXJ2YWwgaW4gbWlsbGlzZWNvbmRzIGFmdGVyIHRyaWdnZXJpbmcgdGhlIGNoZWNrIGZvciBpZGxlIHJlc291cmNlcyB0byBkZXN0cm95JyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcucG9vbC5yZWFwZXJJbnRlcnZhbC52YWx1ZVxuICAgIH0sXG4gICAge1xuICAgICAgdHlwZTogJ3RvZ2dsZScsXG4gICAgICBuYW1lOiAnYmVuY2htYXJraW5nJyxcbiAgICAgIG1lc3NhZ2U6ICdFbmFibGUgYmVuY2htYXJraW5nIGZvciBhIHJlc291cmNlIHBvb2wnLFxuICAgICAgaW5pdGlhbDogZGVmYXVsdENvbmZpZy5wb29sLmJlbmNobWFya2luZy52YWx1ZVxuICAgIH1cbiAgXSxcbiAgbG9nZ2luZzogW1xuICAgIHtcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgbmFtZTogJ2xldmVsJyxcbiAgICAgIG1lc3NhZ2U6XG4gICAgICAgICdUaGUgbG9nIGxldmVsICgwOiBzaWxlbnQsIDE6IGVycm9yLCAyOiB3YXJuaW5nLCAzOiBub3RpY2UsIDQ6IHZlcmJvc2UsIDU6IGJlbmNobWFyayknLFxuICAgICAgaW5pdGlhbDogZGVmYXVsdENvbmZpZy5sb2dnaW5nLmxldmVsLnZhbHVlLFxuICAgICAgcm91bmQ6IDAsXG4gICAgICBtaW46IDAsXG4gICAgICBtYXg6IDVcbiAgICB9LFxuICAgIHtcbiAgICAgIHR5cGU6ICd0ZXh0JyxcbiAgICAgIG5hbWU6ICdmaWxlJyxcbiAgICAgIG1lc3NhZ2U6XG4gICAgICAgICdBIGxvZyBmaWxlIG5hbWUuIFNldCB3aXRoIC0tdG9GaWxlIGFuZCAtLWxvZ0Rlc3QgdG8gZW5hYmxlIGZpbGUgbG9nZ2luZycsXG4gICAgICBpbml0aWFsOiBkZWZhdWx0Q29uZmlnLmxvZ2dpbmcuZmlsZS52YWx1ZVxuICAgIH0sXG4gICAge1xuICAgICAgdHlwZTogJ3RleHQnLFxuICAgICAgbmFtZTogJ2Rlc3QnLFxuICAgICAgbWVzc2FnZTogJ1RoZSBwYXRoIHRvIGEgbG9nIGZpbGUgd2hlbiB0aGUgZmlsZSBsb2dnaW5nIGlzIGVuYWJsZWQnLFxuICAgICAgaW5pdGlhbDogZGVmYXVsdENvbmZpZy5sb2dnaW5nLmRlc3QudmFsdWVcbiAgICB9LFxuICAgIHtcbiAgICAgIHR5cGU6ICd0b2dnbGUnLFxuICAgICAgbmFtZTogJ3RvQ29uc29sZScsXG4gICAgICBtZXNzYWdlOiAnRW5hYmxlIGxvZ2dpbmcgdG8gdGhlIGNvbnNvbGUnLFxuICAgICAgaW5pdGlhbDogZGVmYXVsdENvbmZpZy5sb2dnaW5nLnRvQ29uc29sZS52YWx1ZVxuICAgIH0sXG4gICAge1xuICAgICAgdHlwZTogJ3RvZ2dsZScsXG4gICAgICBuYW1lOiAndG9GaWxlJyxcbiAgICAgIG1lc3NhZ2U6ICdFbmFibGVzIGxvZ2dpbmcgdG8gYSBmaWxlJyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcubG9nZ2luZy50b0ZpbGUudmFsdWVcbiAgICB9XG4gIF0sXG4gIHVpOiBbXG4gICAge1xuICAgICAgdHlwZTogJ3RvZ2dsZScsXG4gICAgICBuYW1lOiAnZW5hYmxlJyxcbiAgICAgIG1lc3NhZ2U6ICdFbmFibGUgVUkgZm9yIHRoZSBleHBvcnQgc2VydmVyJyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcudWkuZW5hYmxlLnZhbHVlXG4gICAgfSxcbiAgICB7XG4gICAgICB0eXBlOiAndGV4dCcsXG4gICAgICBuYW1lOiAncm91dGUnLFxuICAgICAgbWVzc2FnZTogJ0Egcm91dGUgdG8gYXR0YWNoIHRoZSBVSScsXG4gICAgICBpbml0aWFsOiBkZWZhdWx0Q29uZmlnLnVpLnJvdXRlLnZhbHVlXG4gICAgfVxuICBdLFxuICBvdGhlcjogW1xuICAgIHtcbiAgICAgIHR5cGU6ICd0ZXh0JyxcbiAgICAgIG5hbWU6ICdub2RlRW52JyxcbiAgICAgIG1lc3NhZ2U6ICdUaGUgdHlwZSBvZiBOb2RlLmpzIGVudmlyb25tZW50JyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcub3RoZXIubm9kZUVudi52YWx1ZVxuICAgIH0sXG4gICAge1xuICAgICAgdHlwZTogJ3RvZ2dsZScsXG4gICAgICBuYW1lOiAnbGlzdGVuVG9Qcm9jZXNzRXhpdHMnLFxuICAgICAgbWVzc2FnZTogJ1NldCB0byBmYWxzZSB0byBza2lwIGF0dGFjaGluZyBwcm9jZXNzLmV4aXQgaGFuZGxlcnMnLFxuICAgICAgaW5pdGlhbDogZGVmYXVsdENvbmZpZy5vdGhlci5saXN0ZW5Ub1Byb2Nlc3NFeGl0cy52YWx1ZVxuICAgIH0sXG4gICAge1xuICAgICAgdHlwZTogJ3RvZ2dsZScsXG4gICAgICBuYW1lOiAnbm9Mb2dvJyxcbiAgICAgIG1lc3NhZ2U6ICdTa2lwIHByaW50aW5nIHRoZSBsb2dvIG9uIHN0YXJ0dXAuIFJlcGxhY2VkIGJ5IHNpbXBsZSB0ZXh0JyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcub3RoZXIubm9Mb2dvLnZhbHVlXG4gICAgfSxcbiAgICB7XG4gICAgICB0eXBlOiAndG9nZ2xlJyxcbiAgICAgIG5hbWU6ICdoYXJkUmVzZXRQYWdlJyxcbiAgICAgIG1lc3NhZ2U6ICdEZWNpZGVzIGlmIHRoZSBwYWdlIGNvbnRlbnQgc2hvdWxkIGJlIHJlc2V0IGVudGlyZWx5JyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcub3RoZXIuaGFyZFJlc2V0UGFnZS52YWx1ZVxuICAgIH0sXG4gICAge1xuICAgICAgdHlwZTogJ3RvZ2dsZScsXG4gICAgICBuYW1lOiAnYnJvd3NlclNoZWxsTW9kZScsXG4gICAgICBtZXNzYWdlOiAnRGVjaWRlcyBpZiB0aGUgYnJvd3NlciBydW5zIGluIHRoZSBzaGVsbCBtb2RlJyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcub3RoZXIuYnJvd3NlclNoZWxsTW9kZS52YWx1ZVxuICAgIH1cbiAgXSxcbiAgZGVidWc6IFtcbiAgICB7XG4gICAgICB0eXBlOiAndG9nZ2xlJyxcbiAgICAgIG5hbWU6ICdlbmFibGUnLFxuICAgICAgbWVzc2FnZTogJ0VuYWJsZXMgZGVidWcgbW9kZSBmb3IgdGhlIGJyb3dzZXIgaW5zdGFuY2UnLFxuICAgICAgaW5pdGlhbDogZGVmYXVsdENvbmZpZy5kZWJ1Zy5lbmFibGUudmFsdWVcbiAgICB9LFxuICAgIHtcbiAgICAgIHR5cGU6ICd0b2dnbGUnLFxuICAgICAgbmFtZTogJ2hlYWRsZXNzJyxcbiAgICAgIG1lc3NhZ2U6ICdUaGUgbW9kZSBzZXR0aW5nIGZvciB0aGUgYnJvd3NlcicsXG4gICAgICBpbml0aWFsOiBkZWZhdWx0Q29uZmlnLmRlYnVnLmhlYWRsZXNzLnZhbHVlXG4gICAgfSxcbiAgICB7XG4gICAgICB0eXBlOiAndG9nZ2xlJyxcbiAgICAgIG5hbWU6ICdkZXZ0b29scycsXG4gICAgICBtZXNzYWdlOiAnVGhlIERldlRvb2xzIGZvciB0aGUgaGVhZGZ1bCBicm93c2VyJyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcuZGVidWcuZGV2dG9vbHMudmFsdWVcbiAgICB9LFxuICAgIHtcbiAgICAgIHR5cGU6ICd0b2dnbGUnLFxuICAgICAgbmFtZTogJ2xpc3RlblRvQ29uc29sZScsXG4gICAgICBtZXNzYWdlOiAnVGhlIGV2ZW50IGxpc3RlbmVyIGZvciBjb25zb2xlIG1lc3NhZ2VzIGZyb20gdGhlIGJyb3dzZXInLFxuICAgICAgaW5pdGlhbDogZGVmYXVsdENvbmZpZy5kZWJ1Zy5saXN0ZW5Ub0NvbnNvbGUudmFsdWVcbiAgICB9LFxuICAgIHtcbiAgICAgIHR5cGU6ICd0b2dnbGUnLFxuICAgICAgbmFtZTogJ2R1bXBpbycsXG4gICAgICBtZXNzYWdlOiAnUmVkaXJlY3RzIHRoZSBicm93c2VyIHN0ZG91dCBhbmQgc3RkZXJyIHRvIE5vZGVKUyBwcm9jZXNzJyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcuZGVidWcuZHVtcGlvLnZhbHVlXG4gICAgfSxcbiAgICB7XG4gICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICAgIG5hbWU6ICdzbG93TW8nLFxuICAgICAgbWVzc2FnZTogJ1B1cHBldGVlciBvcGVyYXRpb25zIHNsb3cgZG93biBpbiBtaWxsaXNlY29uZHMnLFxuICAgICAgaW5pdGlhbDogZGVmYXVsdENvbmZpZy5kZWJ1Zy5zbG93TW8udmFsdWVcbiAgICB9LFxuICAgIHtcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgbmFtZTogJ2RlYnVnZ2luZ1BvcnQnLFxuICAgICAgbWVzc2FnZTogJ1RoZSBwb3J0IG51bWJlciBmb3IgZGVidWdnaW5nJyxcbiAgICAgIGluaXRpYWw6IGRlZmF1bHRDb25maWcuZGVidWcuZGVidWdnaW5nUG9ydC52YWx1ZVxuICAgIH1cbiAgXVxufTtcblxuLy8gQWJzb2x1dGUgcHJvcHMgdGhhdCwgaW4gY2FzZSBvZiBtZXJnaW5nIHJlY3Vyc2l2ZWx5LCBuZWVkIHRvIGJlIGZvcmNlIG1lcmdlZFxuZXhwb3J0IGNvbnN0IGFic29sdXRlUHJvcHMgPSBbXG4gICdvcHRpb25zJyxcbiAgJ2dsb2JhbE9wdGlvbnMnLFxuICAndGhlbWVPcHRpb25zJyxcbiAgJ3Jlc291cmNlcycsXG4gICdwYXlsb2FkJ1xuXTtcblxuLy8gQXJndW1lbnQgbmVzdGluZyBsZXZlbCBvZiBhbGwgZXhwb3J0IHNlcnZlciBvcHRpb25zXG5leHBvcnQgY29uc3QgbmVzdGVkQXJncyA9IHt9O1xuXG4vKipcbiAqIFJlY3Vyc2l2ZWx5IGNyZWF0ZXMgYSBjaGFpbiBvZiBuZXN0ZWQgYXJndW1lbnRzIGZyb20gYW4gb2JqZWN0LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmogLSBUaGUgb2JqZWN0IGNvbnRhaW5pbmcgbmVzdGVkIGFyZ3VtZW50cy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wQ2hhaW4gLSBUaGUgY3VycmVudCBjaGFpbiBvZiBuZXN0ZWQgcHJvcGVydGllc1xuICogKHVzZWQgaW50ZXJuYWxseSBkdXJpbmcgcmVjdXJzaW9uKS5cbiAqL1xuY29uc3QgY3JlYXRlTmVzdGVkQXJncyA9IChvYmosIHByb3BDaGFpbiA9ICcnKSA9PiB7XG4gIE9iamVjdC5rZXlzKG9iaikuZm9yRWFjaCgoaykgPT4ge1xuICAgIGlmICghWydwdXBwZXRlZXInLCAnaGlnaGNoYXJ0cyddLmluY2x1ZGVzKGspKSB7XG4gICAgICBjb25zdCBlbnRyeSA9IG9ialtrXTtcbiAgICAgIGlmICh0eXBlb2YgZW50cnkudmFsdWUgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIC8vIEdvIGRlZXBlciBpbiB0aGUgbmVzdGVkIGFyZ3VtZW50c1xuICAgICAgICBjcmVhdGVOZXN0ZWRBcmdzKGVudHJ5LCBgJHtwcm9wQ2hhaW59LiR7a31gKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIENyZWF0ZSB0aGUgY2hhaW4gb2YgbmVzdGVkIGFyZ3VtZW50c1xuICAgICAgICBuZXN0ZWRBcmdzW2VudHJ5LmNsaU5hbWUgfHwga10gPSBgJHtwcm9wQ2hhaW59LiR7a31gLnN1YnN0cmluZygxKTtcblxuICAgICAgICAvLyBTdXBwb3J0IGZvciB0aGUgbGVnYWN5LCBQaGFudG9tSlMgcHJvcGVydGllcyBuYW1lc1xuICAgICAgICBpZiAoZW50cnkubGVnYWN5TmFtZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgbmVzdGVkQXJnc1tlbnRyeS5sZWdhY3lOYW1lXSA9IGAke3Byb3BDaGFpbn0uJHtrfWAuc3Vic3RyaW5nKDEpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9KTtcbn07XG5cbmNyZWF0ZU5lc3RlZEFyZ3MoZGVmYXVsdENvbmZpZyk7XG4iLCIvKipcbiAqIEBmaWxlb3ZlcnZpZXdcbiAqIFRoaXMgZmlsZSBpcyByZXNwb25zaWJsZSBmb3IgcGFyc2luZyB0aGUgZW52aXJvbm1lbnQgdmFyaWFibGVzIHdpdGggdGhlICd6b2QnXG4gKiBsaWJyYXJ5LiBUaGUgcGFyc2VkIGVudmlyb25tZW50IHZhcmlhYmxlcyBhcmUgdGhlbiBleHBvcnRlZCB0byBiZSB1c2VkXG4gKiBpbiB0aGUgYXBwbGljYXRpb24gYXMgXCJlbnZzXCIuIFdlIHNob3VsZCBub3QgdXNlIHByb2Nlc3MuZW52IGRpcmVjdGx5XG4gKiBpbiB0aGUgYXBwbGljYXRpb24gYXMgdGhlc2Ugd291bGQgbm90IGJlIHBhcnNlZCBwcm9wZXJseS5cbiAqXG4gKiBUaGUgZW52aXJvbm1lbnQgdmFyaWFibGVzIGFyZSBwYXJzZWQgYW5kIHZhbGlkYXRlZCBvbmx5IG9uY2Ugd2hlblxuICogdGhlIGFwcGxpY2F0aW9uIHN0YXJ0cy4gV2Ugc2hvdWxkIHdyaXRlIGEgY3VzdG9tIHZhbGlkYXRvciBvciBhIHRyYW5zZm9ybWVyXG4gKiBmb3IgZWFjaCBvZiB0aGUgb3B0aW9ucy5cbiAqL1xuXG5pbXBvcnQgZG90ZW52IGZyb20gJ2RvdGVudic7XG5pbXBvcnQgeyB6IH0gZnJvbSAnem9kJztcblxuaW1wb3J0IHsgc2NyaXB0c05hbWVzIH0gZnJvbSAnLi9zY2hlbWFzL2NvbmZpZy5qcyc7XG5cbi8vIExvYWQgLmVudiBpbnRvIGVudmlyb25tZW50IHZhcmlhYmxlc1xuZG90ZW52LmNvbmZpZygpO1xuXG4vLyBPYmplY3Qgd2l0aCBjdXN0b20gdmFsaWRhdG9ycyBhbmQgdHJhbnNmb3JtZXJzLCB0byBhdm9pZCByZXBldGl0aW9uXG4vLyBpbiB0aGUgQ29uZmlnIG9iamVjdFxuY29uc3QgdiA9IHtcbiAgLy8gU3BsaXRzIHN0cmluZyB2YWx1ZSBpbnRvIGVsZW1lbnRzIGluIGFuIGFycmF5LCB0cmltcyBldmVyeSBlbGVtZW50LCBjaGVja3NcbiAgLy8gaWYgYW4gYXJyYXkgaXMgY29ycmVjdCwgaWYgaXQgaXMgZW1wdHksIGFuZCBpZiBpdCBpcywgcmV0dXJucyB1bmRlZmluZWRcbiAgYXJyYXk6IChmaWx0ZXJBcnJheSkgPT5cbiAgICB6XG4gICAgICAuc3RyaW5nKClcbiAgICAgIC50cmFuc2Zvcm0oKHZhbHVlKSA9PlxuICAgICAgICB2YWx1ZVxuICAgICAgICAgIC5zcGxpdCgnLCcpXG4gICAgICAgICAgLm1hcCgodmFsdWUpID0+IHZhbHVlLnRyaW0oKSlcbiAgICAgICAgICAuZmlsdGVyKCh2YWx1ZSkgPT4gZmlsdGVyQXJyYXkuaW5jbHVkZXModmFsdWUpKVxuICAgICAgKVxuICAgICAgLnRyYW5zZm9ybSgodmFsdWUpID0+ICh2YWx1ZS5sZW5ndGggPyB2YWx1ZSA6IHVuZGVmaW5lZCkpLFxuXG4gIC8vIEFsbG93cyBvbmx5IHRydWUsIGZhbHNlIGFuZCBjb3JyZWN0bHkgcGFyc2UgdGhlIHZhbHVlIHRvIGJvb2xlYW5cbiAgLy8gb3Igbm8gdmFsdWUgaW4gd2hpY2ggY2FzZSB0aGUgcmV0dXJuZWQgdmFsdWUgd2lsbCBiZSB1bmRlZmluZWRcbiAgYm9vbGVhbjogKCkgPT5cbiAgICB6XG4gICAgICAuZW51bShbJ3RydWUnLCAnZmFsc2UnLCAnJ10pXG4gICAgICAudHJhbnNmb3JtKCh2YWx1ZSkgPT4gKHZhbHVlICE9PSAnJyA/IHZhbHVlID09PSAndHJ1ZScgOiB1bmRlZmluZWQpKSxcblxuICAvLyBBbGxvd3MgcGFzc2VkIHZhbHVlcyBvciBubyB2YWx1ZSBpbiB3aGljaCBjYXNlIHRoZSByZXR1cm5lZCB2YWx1ZSB3aWxsXG4gIC8vIGJlIHVuZGVmaW5lZFxuICBlbnVtOiAodmFsdWVzKSA9PlxuICAgIHpcbiAgICAgIC5lbnVtKFsuLi52YWx1ZXMsICcnXSlcbiAgICAgIC50cmFuc2Zvcm0oKHZhbHVlKSA9PiAodmFsdWUgIT09ICcnID8gdmFsdWUgOiB1bmRlZmluZWQpKSxcblxuICAvLyBUcmltcyB0aGUgc3RyaW5nIHZhbHVlIGFuZCBjaGVja3MgaWYgaXQgaXMgZW1wdHkgb3IgY29udGFpbnMgc3RyaW5naWZpZWRcbiAgLy8gdmFsdWVzIHN1Y2ggYXMgZmFsc2UsIHVuZGVmaW5lZCwgbnVsbCwgTmFOLCBpZiBpdCBkb2VzLCByZXR1cm5zIHVuZGVmaW5lZFxuICBzdHJpbmc6ICgpID0+XG4gICAgelxuICAgICAgLnN0cmluZygpXG4gICAgICAudHJpbSgpXG4gICAgICAucmVmaW5lKFxuICAgICAgICAodmFsdWUpID0+XG4gICAgICAgICAgIVsnZmFsc2UnLCAndW5kZWZpbmVkJywgJ251bGwnLCAnTmFOJ10uaW5jbHVkZXModmFsdWUpIHx8XG4gICAgICAgICAgdmFsdWUgPT09ICcnLFxuICAgICAgICAodmFsdWUpID0+ICh7XG4gICAgICAgICAgbWVzc2FnZTogYFRoZSBzdHJpbmcgY29udGFpbnMgZm9yYmlkZGVuIHZhbHVlcywgcmVjZWl2ZWQgJyR7dmFsdWV9J2BcbiAgICAgICAgfSlcbiAgICAgIClcbiAgICAgIC50cmFuc2Zvcm0oKHZhbHVlKSA9PiAodmFsdWUgIT09ICcnID8gdmFsdWUgOiB1bmRlZmluZWQpKSxcblxuICAvLyBDaGVja3MgaWYgdGhlIHN0cmluZyBpcyBhIHZhbGlkIHBhdGggZGlyZWN0b3J5IChwYXRoIGZvcm1hdClcbiAgcGF0aDogKCkgPT5cbiAgICB6XG4gICAgICAuc3RyaW5nKClcbiAgICAgIC50cmltKClcbiAgICAgIC5yZWZpbmUoXG4gICAgICAgICh2YWx1ZSkgPT4ge1xuICAgICAgICAgIC8vIFNpbXBsaWZpZWQgcmVnZXggdG8gbWF0Y2ggYm90aCBhYnNvbHV0ZSBhbmQgcmVsYXRpdmUgcGF0aHNcbiAgICAgICAgICByZXR1cm4gL14oXFwuXFwvfFxcLlxcLlxcL3xcXC98W2EtekEtWl06XFxcXHxbYS16QS1aXTpcXC8pPygoPzpbXFx3LV0rKVtcXFxcL10/KSskLy50ZXN0KFxuICAgICAgICAgICAgdmFsdWVcbiAgICAgICAgICApO1xuICAgICAgICB9LFxuICAgICAgICB7fSxcbiAgICAgICAge1xuICAgICAgICAgIG1lc3NhZ2U6ICdUaGUgc3RyaW5nIGlzIGFuIGludmFsaWQgcGF0aCBkaXJlY3Rvcnkgc3RyaW5nLidcbiAgICAgICAgfVxuICAgICAgKSxcblxuICAvLyBBbGxvd3MgcG9zaXRpdmUgbnVtYmVycyBvciBubyB2YWx1ZSBpbiB3aGljaCBjYXNlIHRoZSByZXR1cm5lZCB2YWx1ZSB3aWxsXG4gIC8vIGJlIHVuZGVmaW5lZFxuICBwb3NpdGl2ZU51bTogKCkgPT5cbiAgICB6XG4gICAgICAuc3RyaW5nKClcbiAgICAgIC50cmltKClcbiAgICAgIC5yZWZpbmUoXG4gICAgICAgICh2YWx1ZSkgPT5cbiAgICAgICAgICB2YWx1ZSA9PT0gJycgfHwgKCFpc05hTihwYXJzZUZsb2F0KHZhbHVlKSkgJiYgcGFyc2VGbG9hdCh2YWx1ZSkgPiAwKSxcbiAgICAgICAgKHZhbHVlKSA9PiAoe1xuICAgICAgICAgIG1lc3NhZ2U6IGBUaGUgdmFsdWUgbXVzdCBiZSBudW1lcmljIGFuZCBwb3NpdGl2ZSwgcmVjZWl2ZWQgJyR7dmFsdWV9J2BcbiAgICAgICAgfSlcbiAgICAgIClcbiAgICAgIC50cmFuc2Zvcm0oKHZhbHVlKSA9PiAodmFsdWUgIT09ICcnID8gcGFyc2VGbG9hdCh2YWx1ZSkgOiB1bmRlZmluZWQpKSxcblxuICAvLyBBbGxvd3Mgbm9uLW5lZ2F0aXZlIG51bWJlcnMgb3Igbm8gdmFsdWUgaW4gd2hpY2ggY2FzZSB0aGUgcmV0dXJuZWQgdmFsdWVcbiAgLy8gd2lsbCBiZSB1bmRlZmluZWRcbiAgbm9uTmVnYXRpdmVOdW06ICgpID0+XG4gICAgelxuICAgICAgLnN0cmluZygpXG4gICAgICAudHJpbSgpXG4gICAgICAucmVmaW5lKFxuICAgICAgICAodmFsdWUpID0+XG4gICAgICAgICAgdmFsdWUgPT09ICcnIHx8ICghaXNOYU4ocGFyc2VGbG9hdCh2YWx1ZSkpICYmIHBhcnNlRmxvYXQodmFsdWUpID49IDApLFxuICAgICAgICAodmFsdWUpID0+ICh7XG4gICAgICAgICAgbWVzc2FnZTogYFRoZSB2YWx1ZSBtdXN0IGJlIG51bWVyaWMgYW5kIG5vbi1uZWdhdGl2ZSwgcmVjZWl2ZWQgJyR7dmFsdWV9J2BcbiAgICAgICAgfSlcbiAgICAgIClcbiAgICAgIC50cmFuc2Zvcm0oKHZhbHVlKSA9PiAodmFsdWUgIT09ICcnID8gcGFyc2VGbG9hdCh2YWx1ZSkgOiB1bmRlZmluZWQpKVxufTtcblxuZXhwb3J0IGNvbnN0IENvbmZpZyA9IHoub2JqZWN0KHtcbiAgLy8gcHVwcGV0ZWVyXG4gIFBVUFBFVEVFUl9URU1QX0RJUjogdi5wYXRoKCksXG5cbiAgLy8gaGlnaGNoYXJ0c1xuICBISUdIQ0hBUlRTX1ZFUlNJT046IHpcbiAgICAuc3RyaW5nKClcbiAgICAudHJpbSgpXG4gICAgLnJlZmluZShcbiAgICAgICh2YWx1ZSkgPT4gL14obGF0ZXN0fFxcZCsoXFwuXFxkKyl7MCwyfSkkLy50ZXN0KHZhbHVlKSB8fCB2YWx1ZSA9PT0gJycsXG4gICAgICAodmFsdWUpID0+ICh7XG4gICAgICAgIG1lc3NhZ2U6IGBISUdIQ0hBUlRTX1ZFUlNJT04gbXVzdCBiZSAnbGF0ZXN0JywgYSBtYWpvciB2ZXJzaW9uLCBvciBpbiB0aGUgZm9ybSBYWC5ZWS5aWiwgcmVjZWl2ZWQgJyR7dmFsdWV9J2BcbiAgICAgIH0pXG4gICAgKVxuICAgIC50cmFuc2Zvcm0oKHZhbHVlKSA9PiAodmFsdWUgIT09ICcnID8gdmFsdWUgOiB1bmRlZmluZWQpKSxcbiAgSElHSENIQVJUU19DRE5fVVJMOiB6XG4gICAgLnN0cmluZygpXG4gICAgLnRyaW0oKVxuICAgIC5yZWZpbmUoXG4gICAgICAodmFsdWUpID0+XG4gICAgICAgIHZhbHVlLnN0YXJ0c1dpdGgoJ2h0dHBzOi8vJykgfHxcbiAgICAgICAgdmFsdWUuc3RhcnRzV2l0aCgnaHR0cDovLycpIHx8XG4gICAgICAgIHZhbHVlID09PSAnJyxcbiAgICAgICh2YWx1ZSkgPT4gKHtcbiAgICAgICAgbWVzc2FnZTogYEludmFsaWQgdmFsdWUgZm9yIEhJR0hDSEFSVFNfQ0ROX1VSTC4gSXQgc2hvdWxkIHN0YXJ0IHdpdGggaHR0cDovLyBvciBodHRwczovLywgcmVjZWl2ZWQgJyR7dmFsdWV9J2BcbiAgICAgIH0pXG4gICAgKVxuICAgIC50cmFuc2Zvcm0oKHZhbHVlKSA9PiAodmFsdWUgIT09ICcnID8gdmFsdWUgOiB1bmRlZmluZWQpKSxcbiAgSElHSENIQVJUU19DT1JFX1NDUklQVFM6IHYuYXJyYXkoc2NyaXB0c05hbWVzLmNvcmUpLFxuICBISUdIQ0hBUlRTX01PRFVMRV9TQ1JJUFRTOiB2LmFycmF5KHNjcmlwdHNOYW1lcy5tb2R1bGVzKSxcbiAgSElHSENIQVJUU19JTkRJQ0FUT1JfU0NSSVBUUzogdi5hcnJheShzY3JpcHRzTmFtZXMuaW5kaWNhdG9ycyksXG4gIEhJR0hDSEFSVFNfRk9SQ0VfRkVUQ0g6IHYuYm9vbGVhbigpLFxuICBISUdIQ0hBUlRTX0NBQ0hFX1BBVEg6IHYuc3RyaW5nKCksXG4gIEhJR0hDSEFSVFNfQURNSU5fVE9LRU46IHYuc3RyaW5nKCksXG5cbiAgLy8gZXhwb3J0XG4gIEVYUE9SVF9UWVBFOiB2LmVudW0oWydqcGVnJywgJ3BuZycsICdwZGYnLCAnc3ZnJ10pLFxuICBFWFBPUlRfQ09OU1RSOiB2LmVudW0oWydjaGFydCcsICdzdG9ja0NoYXJ0JywgJ21hcENoYXJ0JywgJ2dhbnR0Q2hhcnQnXSksXG4gIEVYUE9SVF9ERUZBVUxUX0hFSUdIVDogdi5wb3NpdGl2ZU51bSgpLFxuICBFWFBPUlRfREVGQVVMVF9XSURUSDogdi5wb3NpdGl2ZU51bSgpLFxuICBFWFBPUlRfREVGQVVMVF9TQ0FMRTogdi5wb3NpdGl2ZU51bSgpLFxuICBFWFBPUlRfUkFTVEVSSVpBVElPTl9USU1FT1VUOiB2Lm5vbk5lZ2F0aXZlTnVtKCksXG5cbiAgLy8gY3VzdG9tXG4gIENVU1RPTV9MT0dJQ19BTExPV19DT0RFX0VYRUNVVElPTjogdi5ib29sZWFuKCksXG4gIENVU1RPTV9MT0dJQ19BTExPV19GSUxFX1JFU09VUkNFUzogdi5ib29sZWFuKCksXG5cbiAgLy8gc2VydmVyXG4gIFNFUlZFUl9FTkFCTEU6IHYuYm9vbGVhbigpLFxuICBTRVJWRVJfSE9TVDogdi5zdHJpbmcoKSxcbiAgU0VSVkVSX1BPUlQ6IHYucG9zaXRpdmVOdW0oKSxcbiAgU0VSVkVSX01BWF9VUExPQURfU0laRTogdi5wb3NpdGl2ZU51bSgpLFxuICBTRVJWRVJfQkVOQ0hNQVJLSU5HOiB2LmJvb2xlYW4oKSxcblxuICAvLyBzZXJ2ZXIgcHJveHlcbiAgU0VSVkVSX1BST1hZX0hPU1Q6IHYuc3RyaW5nKCksXG4gIFNFUlZFUl9QUk9YWV9QT1JUOiB2LnBvc2l0aXZlTnVtKCksXG4gIFNFUlZFUl9QUk9YWV9VU0VSTkFNRTogdi5zdHJpbmcoKSxcbiAgU0VSVkVSX1BST1hZX1BBU1NXT1JEOiB2LnN0cmluZygpLFxuICBTRVJWRVJfUFJPWFlfVElNRU9VVDogdi5ub25OZWdhdGl2ZU51bSgpLFxuXG4gIC8vIHNlcnZlciByYXRlIGxpbWl0aW5nXG4gIFNFUlZFUl9SQVRFX0xJTUlUSU5HX0VOQUJMRTogdi5ib29sZWFuKCksXG4gIFNFUlZFUl9SQVRFX0xJTUlUSU5HX01BWF9SRVFVRVNUUzogdi5ub25OZWdhdGl2ZU51bSgpLFxuICBTRVJWRVJfUkFURV9MSU1JVElOR19XSU5ET1c6IHYubm9uTmVnYXRpdmVOdW0oKSxcbiAgU0VSVkVSX1JBVEVfTElNSVRJTkdfREVMQVk6IHYubm9uTmVnYXRpdmVOdW0oKSxcbiAgU0VSVkVSX1JBVEVfTElNSVRJTkdfVFJVU1RfUFJPWFk6IHYuYm9vbGVhbigpLFxuICBTRVJWRVJfUkFURV9MSU1JVElOR19TS0lQX0tFWTogdi5zdHJpbmcoKSxcbiAgU0VSVkVSX1JBVEVfTElNSVRJTkdfU0tJUF9UT0tFTjogdi5zdHJpbmcoKSxcblxuICAvLyBzZXJ2ZXIgc3NsXG4gIFNFUlZFUl9TU0xfRU5BQkxFOiB2LmJvb2xlYW4oKSxcbiAgU0VSVkVSX1NTTF9GT1JDRTogdi5ib29sZWFuKCksXG4gIFNFUlZFUl9TU0xfUE9SVDogdi5wb3NpdGl2ZU51bSgpLFxuICBTRVJWRVJfU1NMX0NFUlRfUEFUSDogdi5zdHJpbmcoKSxcblxuICAvLyBwb29sXG4gIFBPT0xfTUlOX1dPUktFUlM6IHYubm9uTmVnYXRpdmVOdW0oKSxcbiAgUE9PTF9NQVhfV09SS0VSUzogdi5ub25OZWdhdGl2ZU51bSgpLFxuICBQT09MX1dPUktfTElNSVQ6IHYucG9zaXRpdmVOdW0oKSxcbiAgUE9PTF9BQ1FVSVJFX1RJTUVPVVQ6IHYubm9uTmVnYXRpdmVOdW0oKSxcbiAgUE9PTF9DUkVBVEVfVElNRU9VVDogdi5ub25OZWdhdGl2ZU51bSgpLFxuICBQT09MX0RFU1RST1lfVElNRU9VVDogdi5ub25OZWdhdGl2ZU51bSgpLFxuICBQT09MX0lETEVfVElNRU9VVDogdi5ub25OZWdhdGl2ZU51bSgpLFxuICBQT09MX0NSRUFURV9SRVRSWV9JTlRFUlZBTDogdi5ub25OZWdhdGl2ZU51bSgpLFxuICBQT09MX1JFQVBFUl9JTlRFUlZBTDogdi5ub25OZWdhdGl2ZU51bSgpLFxuICBQT09MX0JFTkNITUFSS0lORzogdi5ib29sZWFuKCksXG5cbiAgLy8gbG9nZ2VyXG4gIExPR0dJTkdfTEVWRUw6IHpcbiAgICAuc3RyaW5nKClcbiAgICAudHJpbSgpXG4gICAgLnJlZmluZShcbiAgICAgICh2YWx1ZSkgPT5cbiAgICAgICAgdmFsdWUgPT09ICcnIHx8XG4gICAgICAgICghaXNOYU4ocGFyc2VGbG9hdCh2YWx1ZSkpICYmXG4gICAgICAgICAgcGFyc2VGbG9hdCh2YWx1ZSkgPj0gMCAmJlxuICAgICAgICAgIHBhcnNlRmxvYXQodmFsdWUpIDw9IDUpLFxuICAgICAgKHZhbHVlKSA9PiAoe1xuICAgICAgICBtZXNzYWdlOiBgSW52YWxpZCB2YWx1ZSBmb3IgTE9HR0lOR19MRVZFTC4gV2Ugb25seSBhY2NlcHQgdmFsdWVzIGZyb20gMCB0byA1IGFzIGxvZ2dpbmcgbGV2ZWxzLCByZWNlaXZlZCAnJHt2YWx1ZX0nYFxuICAgICAgfSlcbiAgICApXG4gICAgLnRyYW5zZm9ybSgodmFsdWUpID0+ICh2YWx1ZSAhPT0gJycgPyBwYXJzZUZsb2F0KHZhbHVlKSA6IHVuZGVmaW5lZCkpLFxuICBMT0dHSU5HX0ZJTEU6IHYuc3RyaW5nKCksXG4gIExPR0dJTkdfREVTVDogdi5zdHJpbmcoKSxcbiAgTE9HR0lOR19UT19DT05TT0xFOiB2LmJvb2xlYW4oKSxcbiAgTE9HR0lOR19UT19GSUxFOiB2LmJvb2xlYW4oKSxcblxuICAvLyB1aVxuICBVSV9FTkFCTEU6IHYuYm9vbGVhbigpLFxuICBVSV9ST1VURTogdi5zdHJpbmcoKSxcblxuICAvLyBvdGhlclxuICBPVEhFUl9OT0RFX0VOVjogdi5lbnVtKFsnZGV2ZWxvcG1lbnQnLCAncHJvZHVjdGlvbicsICd0ZXN0J10pLFxuICBPVEhFUl9MSVNURU5fVE9fUFJPQ0VTU19FWElUUzogdi5ib29sZWFuKCksXG4gIE9USEVSX05PX0xPR086IHYuYm9vbGVhbigpLFxuICBPVEhFUl9IQVJEX1JFU0VUX1BBR0U6IHYuYm9vbGVhbigpLFxuICBPVEhFUl9CUk9XU0VSX1NIRUxMX01PREU6IHYuYm9vbGVhbigpLFxuICBPVEhFUl9BTExPV19YTElOSzogdi5ib29sZWFuKCksXG5cbiAgLy8gZGVidWdnZXJcbiAgREVCVUdfRU5BQkxFOiB2LmJvb2xlYW4oKSxcbiAgREVCVUdfSEVBRExFU1M6IHYuYm9vbGVhbigpLFxuICBERUJVR19ERVZUT09MUzogdi5ib29sZWFuKCksXG4gIERFQlVHX0xJU1RFTl9UT19DT05TT0xFOiB2LmJvb2xlYW4oKSxcbiAgREVCVUdfRFVNUElPOiB2LmJvb2xlYW4oKSxcbiAgREVCVUdfU0xPV19NTzogdi5ub25OZWdhdGl2ZU51bSgpLFxuICBERUJVR19ERUJVR0dJTkdfUE9SVDogdi5wb3NpdGl2ZU51bSgpXG59KTtcblxuZXhwb3J0IGNvbnN0IGVudnMgPSBDb25maWcucGFydGlhbCgpLnBhcnNlKHByb2Nlc3MuZW52KTtcbiIsIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG5cbkhpZ2hjaGFydHMgRXhwb3J0IFNlcnZlclxuXG5Db3B5cmlnaHQgKGMpIDIwMTYtMjAyNCwgSGlnaHNvZnRcblxuTGljZW5jZWQgdW5kZXIgdGhlIE1JVCBsaWNlbmNlLlxuXG5BZGRpdGlvbmFsbHkgYSB2YWxpZCBIaWdoY2hhcnRzIGxpY2Vuc2UgaXMgcmVxdWlyZWQgZm9yIHVzZS5cblxuU2VlIExJQ0VOU0UgZmlsZSBpbiByb290IGZvciBkZXRhaWxzLlxuXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG5pbXBvcnQgeyBhcHBlbmRGaWxlLCBleGlzdHNTeW5jLCBta2RpclN5bmMgfSBmcm9tICdmcyc7XG5cbi8vIFRoZSBhdmFpbGFibGUgY29sb3JzXG5jb25zdCBjb2xvcnMgPSBbJ3JlZCcsICd5ZWxsb3cnLCAnYmx1ZScsICdncmF5JywgJ2dyZWVuJ107XG5cbi8vIFRoZSBkZWZhdWx0IGxvZ2dpbmcgY29uZmlnXG5sZXQgbG9nZ2luZyA9IHtcbiAgLy8gRmxhZ3MgZm9yIGxvZ2dpbmcgc3RhdHVzXG4gIHRvQ29uc29sZTogdHJ1ZSxcbiAgdG9GaWxlOiBmYWxzZSxcbiAgcGF0aENyZWF0ZWQ6IGZhbHNlLFxuICAvLyBMb2cgbGV2ZWxzXG4gIGxldmVsc0Rlc2M6IFtcbiAgICB7XG4gICAgICB0aXRsZTogJ2Vycm9yJyxcbiAgICAgIGNvbG9yOiBjb2xvcnNbMF1cbiAgICB9LFxuICAgIHtcbiAgICAgIHRpdGxlOiAnd2FybmluZycsXG4gICAgICBjb2xvcjogY29sb3JzWzFdXG4gICAgfSxcbiAgICB7XG4gICAgICB0aXRsZTogJ25vdGljZScsXG4gICAgICBjb2xvcjogY29sb3JzWzJdXG4gICAgfSxcbiAgICB7XG4gICAgICB0aXRsZTogJ3ZlcmJvc2UnLFxuICAgICAgY29sb3I6IGNvbG9yc1szXVxuICAgIH0sXG4gICAge1xuICAgICAgdGl0bGU6ICdiZW5jaG1hcmsnLFxuICAgICAgY29sb3I6IGNvbG9yc1s0XVxuICAgIH1cbiAgXSxcbiAgLy8gTG9nIGxpc3RlbmVyc1xuICBsaXN0ZW5lcnM6IFtdXG59O1xuXG4vKipcbiAqIExvZ3MgdGhlIHByb3ZpZGVkIHRleHRzIHRvIGEgZmlsZSwgaWYgZmlsZSBsb2dnaW5nIGlzIGVuYWJsZWQuIEl0IGNyZWF0ZXNcbiAqIHRoZSBuZWNlc3NhcnkgZGlyZWN0b3J5IHN0cnVjdHVyZSBpZiBub3QgYWxyZWFkeSBjcmVhdGVkIGFuZCBhcHBlbmRzIHRoZVxuICogY29udGVudCwgaW5jbHVkaW5nIGFuIG9wdGlvbmFsIHByZWZpeCwgdG8gdGhlIHNwZWNpZmllZCBsb2cgZmlsZS5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ1tdfSB0ZXh0cyAtIEFuIGFycmF5IG9mIHRleHRzIHRvIGJlIGxvZ2dlZC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBwcmVmaXggLSBBbiBvcHRpb25hbCBwcmVmaXggdG8gYmUgYWRkZWQgdG8gZWFjaCBsb2cgZW50cnkuXG4gKi9cbmNvbnN0IGxvZ1RvRmlsZSA9ICh0ZXh0cywgcHJlZml4KSA9PiB7XG4gIGlmICghbG9nZ2luZy5wYXRoQ3JlYXRlZCkge1xuICAgIC8vIENyZWF0ZSBpZiBkb2VzIG5vdCBleGlzdFxuICAgICFleGlzdHNTeW5jKGxvZ2dpbmcuZGVzdCkgJiYgbWtkaXJTeW5jKGxvZ2dpbmcuZGVzdCk7XG5cbiAgICAvLyBXZSBub3cgYXNzdW1lIHRoZSBwYXRoIGlzIGF2YWlsYWJsZSwgZS5nLiBpdCdzIHRoZSByZXNwb25zaWJpbGl0eVxuICAgIC8vIG9mIHRoZSB1c2VyIHRvIGNyZWF0ZSB0aGUgcGF0aCB3aXRoIHRoZSBjb3JyZWN0IGFjY2VzcyByaWdodHMuXG4gICAgbG9nZ2luZy5wYXRoQ3JlYXRlZCA9IHRydWU7XG4gIH1cblxuICAvLyBBZGQgdGhlIGNvbnRlbnQgdG8gYSBmaWxlXG4gIGFwcGVuZEZpbGUoXG4gICAgYCR7bG9nZ2luZy5kZXN0fSR7bG9nZ2luZy5maWxlfWAsXG4gICAgW3ByZWZpeF0uY29uY2F0KHRleHRzKS5qb2luKCcgJykgKyAnXFxuJyxcbiAgICAoZXJyb3IpID0+IHtcbiAgICAgIGlmIChlcnJvcikge1xuICAgICAgICBjb25zb2xlLmxvZyhgW2xvZ2dlcl0gVW5hYmxlIHRvIHdyaXRlIHRvIGxvZyBmaWxlOiAke2Vycm9yfWApO1xuICAgICAgICBsb2dnaW5nLnRvRmlsZSA9IGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgKTtcbn07XG5cbi8qKlxuICogTG9ncyBhIG1lc3NhZ2UuIEFjY2VwdHMgYSB2YXJpYWJsZSBhbW91bnQgb2YgYXJndW1lbnRzLiBBcmd1bWVudHMgYWZ0ZXJcbiAqIGBsZXZlbGAgd2lsbCBiZSBwYXNzZWQgZGlyZWN0bHkgdG8gY29uc29sZS5sb2csIGFuZC9vciB3aWxsIGJlIGpvaW5lZFxuICogYW5kIGFwcGVuZGVkIHRvIHRoZSBsb2cgZmlsZS5cbiAqXG4gKiBAcGFyYW0ge2FueX0gYXJncyAtIEFuIGFycmF5IG9mIGFyZ3VtZW50cyB3aGVyZSB0aGUgZmlyc3QgaXMgdGhlIGxvZyBsZXZlbFxuICogYW5kIHRoZSByZXN0IGFyZSBzdHJpbmdzIHRvIGJ1aWxkIGEgbWVzc2FnZSB3aXRoLlxuICovXG5leHBvcnQgY29uc3QgbG9nID0gKC4uLmFyZ3MpID0+IHtcbiAgY29uc3QgW25ld0xldmVsLCAuLi50ZXh0c10gPSBhcmdzO1xuXG4gIC8vIEN1cnJlbnQgbG9nZ2luZyBvcHRpb25zXG4gIGNvbnN0IHsgbGV2ZWxzRGVzYywgbGV2ZWwgfSA9IGxvZ2dpbmc7XG5cbiAgLy8gQ2hlY2sgaWYgbG9nIGxldmVsIGlzIHdpdGhpbiBhIGNvcnJlY3QgcmFuZ2Ugb3IgaXMgYSBiZW5jaG1hcmsgbG9nXG4gIGlmIChcbiAgICBuZXdMZXZlbCAhPT0gNSAmJlxuICAgIChuZXdMZXZlbCA9PT0gMCB8fCBuZXdMZXZlbCA+IGxldmVsIHx8IGxldmVsID4gbGV2ZWxzRGVzYy5sZW5ndGgpXG4gICkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIEdldCByaWQgb2YgdGhlIEdNVCB0ZXh0IGluZm9ybWF0aW9uXG4gIGNvbnN0IG5ld0RhdGUgPSBuZXcgRGF0ZSgpLnRvU3RyaW5nKCkuc3BsaXQoJygnKVswXS50cmltKCk7XG5cbiAgLy8gQ3JlYXRlIGEgbWVzc2FnZSdzIHByZWZpeFxuICBjb25zdCBwcmVmaXggPSBgJHtuZXdEYXRlfSBbJHtsZXZlbHNEZXNjW25ld0xldmVsIC0gMV0udGl0bGV9XSAtYDtcblxuICAvLyBDYWxsIGF2YWlsYWJsZSBsb2cgbGlzdGVuZXJzXG4gIGxvZ2dpbmcubGlzdGVuZXJzLmZvckVhY2goKGZuKSA9PiB7XG4gICAgZm4ocHJlZml4LCB0ZXh0cy5qb2luKCcgJykpO1xuICB9KTtcblxuICAvLyBMb2cgdG8gY29uc29sZVxuICBpZiAobG9nZ2luZy50b0NvbnNvbGUpIHtcbiAgICBjb25zb2xlLmxvZy5hcHBseShcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIFtwcmVmaXgudG9TdHJpbmcoKVtsb2dnaW5nLmxldmVsc0Rlc2NbbmV3TGV2ZWwgLSAxXS5jb2xvcl1dLmNvbmNhdCh0ZXh0cylcbiAgICApO1xuICB9XG5cbiAgLy8gTG9nIHRvIGZpbGVcbiAgaWYgKGxvZ2dpbmcudG9GaWxlKSB7XG4gICAgbG9nVG9GaWxlKHRleHRzLCBwcmVmaXgpO1xuICB9XG59O1xuXG4vKipcbiAqIExvZ3MgYW4gZXJyb3IgbWVzc2FnZSB3aXRoIGl0cyBzdGFjayB0cmFjZS4gT3B0aW9uYWxseSwgYSBjdXN0b20gbWVzc2FnZVxuICogY2FuIGJlIHByb3ZpZGVkLlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBsZXZlbCAtIFRoZSBsb2cgbGV2ZWwuXG4gKiBAcGFyYW0ge0Vycm9yfSBlcnJvciAtIFRoZSBlcnJvciBvYmplY3QuXG4gKiBAcGFyYW0ge3N0cmluZ30gY3VzdG9tTWVzc2FnZSAtIEFuIG9wdGlvbmFsIGN1c3RvbSBtZXNzYWdlIHRvIGJlIGxvZ2dlZCBhbG9uZ1xuICogd2l0aCB0aGUgZXJyb3IuXG4gKi9cbmV4cG9ydCBjb25zdCBsb2dXaXRoU3RhY2sgPSAobmV3TGV2ZWwsIGVycm9yLCBjdXN0b21NZXNzYWdlKSA9PiB7XG4gIC8vIEdldCB0aGUgbWFpbiBtZXNzYWdlXG4gIGNvbnN0IG1haW5NZXNzYWdlID0gY3VzdG9tTWVzc2FnZSB8fCBlcnJvci5tZXNzYWdlO1xuXG4gIC8vIEN1cnJlbnQgbG9nZ2luZyBvcHRpb25zXG4gIGNvbnN0IHsgbGV2ZWwsIGxldmVsc0Rlc2MgfSA9IGxvZ2dpbmc7XG5cbiAgLy8gQ2hlY2sgaWYgbG9nIGxldmVsIGlzIHdpdGhpbiBhIGNvcnJlY3QgcmFuZ2VcbiAgaWYgKG5ld0xldmVsID09PSAwIHx8IG5ld0xldmVsID4gbGV2ZWwgfHwgbGV2ZWwgPiBsZXZlbHNEZXNjLmxlbmd0aCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIEdldCByaWQgb2YgdGhlIEdNVCB0ZXh0IGluZm9ybWF0aW9uXG4gIGNvbnN0IG5ld0RhdGUgPSBuZXcgRGF0ZSgpLnRvU3RyaW5nKCkuc3BsaXQoJygnKVswXS50cmltKCk7XG5cbiAgLy8gQ3JlYXRlIGEgbWVzc2FnZSdzIHByZWZpeFxuICBjb25zdCBwcmVmaXggPSBgJHtuZXdEYXRlfSBbJHtsZXZlbHNEZXNjW25ld0xldmVsIC0gMV0udGl0bGV9XSAtYDtcblxuICAvLyBJZiB0aGUgY3VzdG9tTWVzc2FnZSBleGlzdHMsIHdlIHdhbnQgdG8gZGlzcGxheSB0aGUgd2hvbGUgc3RhY2sgbWVzc2FnZVxuICBjb25zdCBzdGFja01lc3NhZ2UgPVxuICAgIGVycm9yLm1lc3NhZ2UgIT09IGVycm9yLnN0YWNrTWVzc2FnZSB8fCBlcnJvci5zdGFja01lc3NhZ2UgPT09IHVuZGVmaW5lZFxuICAgICAgPyBlcnJvci5zdGFja1xuICAgICAgOiBlcnJvci5zdGFjay5zcGxpdCgnXFxuJykuc2xpY2UoMSkuam9pbignXFxuJyk7XG5cbiAgLy8gQ29tYmluZSBjdXN0b20gbWVzc2FnZSBvciBlcnJvciBtZXNzYWdlIHdpdGggZXJyb3Igc3RhY2sgbWVzc2FnZVxuICBjb25zdCB0ZXh0cyA9IFttYWluTWVzc2FnZSwgJ1xcbicsIHN0YWNrTWVzc2FnZV07XG5cbiAgLy8gTG9nIHRvIGNvbnNvbGVcbiAgaWYgKGxvZ2dpbmcudG9Db25zb2xlKSB7XG4gICAgY29uc29sZS5sb2cuYXBwbHkoXG4gICAgICB1bmRlZmluZWQsXG4gICAgICBbcHJlZml4LnRvU3RyaW5nKClbbG9nZ2luZy5sZXZlbHNEZXNjW25ld0xldmVsIC0gMV0uY29sb3JdXS5jb25jYXQoW1xuICAgICAgICBtYWluTWVzc2FnZVtjb2xvcnNbbmV3TGV2ZWwgLSAxXV0sXG4gICAgICAgICdcXG4nLFxuICAgICAgICBzdGFja01lc3NhZ2VcbiAgICAgIF0pXG4gICAgKTtcbiAgfVxuXG4gIC8vIENhbGwgYXZhaWxhYmxlIGxvZyBsaXN0ZW5lcnNcbiAgbG9nZ2luZy5saXN0ZW5lcnMuZm9yRWFjaCgoZm4pID0+IHtcbiAgICBmbihwcmVmaXgsIHRleHRzLmpvaW4oJyAnKSk7XG4gIH0pO1xuXG4gIC8vIExvZyB0byBmaWxlXG4gIGlmIChsb2dnaW5nLnRvRmlsZSkge1xuICAgIGxvZ1RvRmlsZSh0ZXh0cywgcHJlZml4KTtcbiAgfVxufTtcblxuLyoqXG4gKiBTZXRzIHRoZSBsb2cgbGV2ZWwgdG8gdGhlIHNwZWNpZmllZCB2YWx1ZS4gTG9nIGxldmVscyBhcmUgKDAgPSBubyBsb2dnaW5nLFxuICogMSA9IGVycm9yLCAyID0gd2FybmluZywgMyA9IG5vdGljZSwgNCA9IHZlcmJvc2Ugb3IgNSA9IGJlbmNobWFyaylcbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gbmV3TGV2ZWwgLSBUaGUgbmV3IGxvZyBsZXZlbCB0byBiZSBzZXQuXG4gKi9cbmV4cG9ydCBjb25zdCBzZXRMb2dMZXZlbCA9IChuZXdMZXZlbCkgPT4ge1xuICBpZiAobmV3TGV2ZWwgPj0gMCAmJiBuZXdMZXZlbCA8PSBsb2dnaW5nLmxldmVsc0Rlc2MubGVuZ3RoKSB7XG4gICAgbG9nZ2luZy5sZXZlbCA9IG5ld0xldmVsO1xuICB9XG59O1xuXG4vKipcbiAqIEVuYWJsZXMgZmlsZSBsb2dnaW5nIHdpdGggdGhlIHNwZWNpZmllZCBkZXN0aW5hdGlvbiBhbmQgbG9nIGZpbGUuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGxvZ0Rlc3QgLSBUaGUgZGVzdGluYXRpb24gcGF0aCBmb3IgbG9nIGZpbGVzLlxuICogQHBhcmFtIHtzdHJpbmd9IGxvZ0ZpbGUgLSBUaGUgbG9nIGZpbGUgbmFtZS5cbiAqL1xuZXhwb3J0IGNvbnN0IGVuYWJsZUZpbGVMb2dnaW5nID0gKGxvZ0Rlc3QsIGxvZ0ZpbGUpID0+IHtcbiAgLy8gVXBkYXRlIGxvZ2dpbmcgb3B0aW9uc1xuICBsb2dnaW5nID0ge1xuICAgIC4uLmxvZ2dpbmcsXG4gICAgZGVzdDogbG9nRGVzdCB8fCBsb2dnaW5nLmRlc3QsXG4gICAgZmlsZTogbG9nRmlsZSB8fCBsb2dnaW5nLmZpbGUsXG4gICAgdG9GaWxlOiB0cnVlXG4gIH07XG5cbiAgaWYgKGxvZ2dpbmcuZGVzdC5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gbG9nKDEsICdbbG9nZ2VyXSBGaWxlIGxvZ2dpbmcgaW5pdGlhbGl6YXRpb246IG5vIHBhdGggc3VwcGxpZWQuJyk7XG4gIH1cblxuICBpZiAoIWxvZ2dpbmcuZGVzdC5lbmRzV2l0aCgnLycpKSB7XG4gICAgbG9nZ2luZy5kZXN0ICs9ICcvJztcbiAgfVxufTtcblxuLyoqXG4gKiBJbml0aWFsaXplcyBsb2dnaW5nIHdpdGggdGhlIHNwZWNpZmllZCBsb2dnaW5nIGNvbmZpZ3VyYXRpb24uXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGxvZ2dpbmdPcHRpb25zIC0gVGhlIGxvZ2dpbmcgY29uZmlndXJhdGlvbiBvYmplY3QuXG4gKi9cbmV4cG9ydCBjb25zdCBpbml0TG9nZ2luZyA9IChsb2dnaW5nT3B0aW9ucykgPT4ge1xuICAvLyBTZXQgYWxsIHRoZSBsb2dnaW5nIG9wdGlvbnMgb24gb3VyIGxvZ2dpbmcgbW9kdWxlIG9iamVjdFxuICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhsb2dnaW5nT3B0aW9ucykpIHtcbiAgICBsb2dnaW5nW2tleV0gPSB2YWx1ZTtcbiAgfVxuXG4gIC8vIFNldCB0aGUgbG9nIGxldmVsXG4gIHNldExvZ0xldmVsKGxvZ2dpbmdPcHRpb25zICYmIHBhcnNlSW50KGxvZ2dpbmdPcHRpb25zLmxldmVsKSk7XG5cbiAgLy8gU2V0IHRoZSBsb2cgZmlsZSBwYXRoIGFuZCBuYW1lXG4gIGlmIChsb2dnaW5nT3B0aW9ucyAmJiBsb2dnaW5nT3B0aW9ucy5kZXN0ICYmIGxvZ2dpbmdPcHRpb25zLnRvRmlsZSkge1xuICAgIGVuYWJsZUZpbGVMb2dnaW5nKFxuICAgICAgbG9nZ2luZ09wdGlvbnMuZGVzdCxcbiAgICAgIGxvZ2dpbmdPcHRpb25zLmZpbGUgfHwgJ2hpZ2hjaGFydHMtZXhwb3J0LXNlcnZlci5sb2cnXG4gICAgKTtcbiAgfVxufTtcblxuLyoqXG4gKiBBZGRzIGEgbGlzdGVuZXIgZnVuY3Rpb24gdG8gdGhlIGxvZ2dpbmcgc3lzdGVtLlxuICpcbiAqIEBwYXJhbSB7ZnVuY3Rpb259IGZuIC0gVGhlIGxpc3RlbmVyIGZ1bmN0aW9uIHRvIGJlIGFkZGVkLlxuICovXG5leHBvcnQgY29uc3QgbGlzdGVuID0gKGZuKSA9PiB7XG4gIGxvZ2dpbmcubGlzdGVuZXJzLnB1c2goZm4pO1xufTtcblxuZXhwb3J0IGRlZmF1bHQge1xuICBsb2csXG4gIGxvZ1dpdGhTdGFjayxcbiAgc2V0TG9nTGV2ZWwsXG4gIGVuYWJsZUZpbGVMb2dnaW5nLFxuICBpbml0TG9nZ2luZyxcbiAgbGlzdGVuXG59O1xuIiwiLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcblxuSGlnaGNoYXJ0cyBFeHBvcnQgU2VydmVyXG5cbkNvcHlyaWdodCAoYykgMjAxNi0yMDI0LCBIaWdoc29mdFxuXG5MaWNlbmNlZCB1bmRlciB0aGUgTUlUIGxpY2VuY2UuXG5cbkFkZGl0aW9uYWxseSBhIHZhbGlkIEhpZ2hjaGFydHMgbGljZW5zZSBpcyByZXF1aXJlZCBmb3IgdXNlLlxuXG5TZWUgTElDRU5TRSBmaWxlIGluIHJvb3QgZm9yIGRldGFpbHMuXG5cbioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG5cbmltcG9ydCB7IHJlYWRGaWxlU3luYyB9IGZyb20gJ2ZzJztcbmltcG9ydCB7IGpvaW4gfSBmcm9tICdwYXRoJztcbmltcG9ydCB7IGZpbGVVUkxUb1BhdGggfSBmcm9tICd1cmwnO1xuXG5pbXBvcnQgeyBkZWZhdWx0Q29uZmlnIH0gZnJvbSAnLi4vbGliL3NjaGVtYXMvY29uZmlnLmpzJztcbmltcG9ydCB7IGxvZywgbG9nV2l0aFN0YWNrIH0gZnJvbSAnLi9sb2dnZXIuanMnO1xuXG5jb25zdCBNQVhfQkFDS09GRl9BVFRFTVBUUyA9IDY7XG5cbmV4cG9ydCBjb25zdCBfX2Rpcm5hbWUgPSBmaWxlVVJMVG9QYXRoKG5ldyBVUkwoJy4uLy4nLCBpbXBvcnQubWV0YS51cmwpKTtcblxuLyoqXG4gKiBDbGVhcnMgYW5kIHN0YW5kYXJkaXplcyB0ZXh0IGJ5IHJlcGxhY2luZyBtdWx0aXBsZSBjb25zZWN1dGl2ZSB3aGl0ZXNwYWNlXG4gKiBjaGFyYWN0ZXJzIHdpdGggYSBzaW5nbGUgc3BhY2UgYW5kIHRyaW1taW5nIGFueSBsZWFkaW5nIG9yIHRyYWlsaW5nXG4gKiB3aGl0ZXNwYWNlLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IC0gVGhlIGlucHV0IHRleHQgdG8gYmUgY2xlYXJlZC5cbiAqIEBwYXJhbSB7UmVnRXhwfSBbcnVsZT0vXFxzXFxzKy9nXSAtIFRoZSByZWd1bGFyIGV4cHJlc3Npb24gcnVsZSB0byBtYXRjaFxuICogbXVsdGlwbGUgY29uc2VjdXRpdmUgd2hpdGVzcGFjZSBjaGFyYWN0ZXJzLlxuICogQHBhcmFtIHtzdHJpbmd9IFtyZXBsYWNlcj0nICddIC0gVGhlIHN0cmluZyB1c2VkIHRvIHJlcGxhY2UgbXVsdGlwbGVcbiAqIGNvbnNlY3V0aXZlIHdoaXRlc3BhY2UgY2hhcmFjdGVycy5cbiAqXG4gKiBAcmV0dXJucyB7c3RyaW5nfSAtIFRoZSBjbGVhcmVkIGFuZCBzdGFuZGFyZGl6ZWQgdGV4dC5cbiAqL1xuZXhwb3J0IGNvbnN0IGNsZWFyVGV4dCA9ICh0ZXh0LCBydWxlID0gL1xcc1xccysvZywgcmVwbGFjZXIgPSAnICcpID0+XG4gIHRleHQucmVwbGFjZUFsbChydWxlLCByZXBsYWNlcikudHJpbSgpO1xuXG4vKipcbiAqIEltcGxlbWVudHMgYW4gZXhwb25lbnRpYWwgYmFja29mZiBzdHJhdGVneSBmb3IgcmV0cnlpbmcgYSBmdW5jdGlvbiB1bnRpbFxuICogYSBjZXJ0YWluIG51bWJlciBvZiBhdHRlbXB0cyBhcmUgcmVhY2hlZC5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiAtIFRoZSBmdW5jdGlvbiB0byBiZSByZXRyaWVkLlxuICogQHBhcmFtIHtudW1iZXJ9IFthdHRlbXB0PTBdIC0gVGhlIGN1cnJlbnQgYXR0ZW1wdCBudW1iZXIuXG4gKiBAcGFyYW0gey4uLmFueX0gYXJncyAtIEFyZ3VtZW50cyB0byBiZSBwYXNzZWQgdG8gdGhlIGZ1bmN0aW9uLlxuICpcbiAqIEByZXR1cm5zIHtQcm9taXNlfSAtIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSByZXN1bHQgb2YgdGhlIGZ1bmN0aW9uXG4gKiBpZiBzdWNjZXNzZnVsLlxuICpcbiAqIEB0aHJvd3Mge0Vycm9yfSAtIFRocm93cyBhbiBlcnJvciBpZiB0aGUgbWF4aW11bSBudW1iZXIgb2YgYXR0ZW1wdHNcbiAqIGlzIHJlYWNoZWQuXG4gKi9cbmV4cG9ydCBjb25zdCBleHBCYWNrb2ZmID0gYXN5bmMgKGZuLCBhdHRlbXB0ID0gMCwgLi4uYXJncykgPT4ge1xuICB0cnkge1xuICAgIC8vIFRyeSB0byBjYWxsIHRoZSBmdW5jdGlvblxuICAgIHJldHVybiBhd2FpdCBmbiguLi5hcmdzKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAvLyBDYWxjdWxhdGUgZGVsYXkgaW4gbXNcbiAgICBjb25zdCBkZWxheUluTXMgPSAyICoqIGF0dGVtcHQgKiAxMDAwO1xuXG4gICAgLy8gSWYgdGhlIGF0dGVtcHQgZXhjZWVkcyB0aGUgbWF4aW11bSBhdHRlbXB0cyBvZiByZWFwZWF0LCB0aHJvdyBhbiBlcnJvclxuICAgIGlmICgrK2F0dGVtcHQgPj0gTUFYX0JBQ0tPRkZfQVRURU1QVFMpIHtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cblxuICAgIC8vIFdhaXQgZ2l2ZW4gYW1vdW50IG9mIHRpbWVcbiAgICBhd2FpdCBuZXcgUHJvbWlzZSgocmVzcG9uc2UpID0+IHNldFRpbWVvdXQocmVzcG9uc2UsIGRlbGF5SW5NcykpO1xuICAgIGxvZyhcbiAgICAgIDMsXG4gICAgICBgW3Bvb2xdIFdhaXRlZCAke2RlbGF5SW5Nc31tcyB1bnRpbCBuZXh0IGNhbGwgZm9yIHRoZSByZXNvdXJjZSBpZDogJHthcmdzWzBdfS5gXG4gICAgKTtcblxuICAgIC8vIFRyeSBhZ2FpblxuICAgIHJldHVybiBleHBCYWNrb2ZmKGZuLCBhdHRlbXB0LCAuLi5hcmdzKTtcbiAgfVxufTtcblxuLyoqXG4gKiBGaXhlcyB0aGUgZXhwb3J0IHR5cGUgYmFzZWQgb24gTUlNRSB0eXBlcyBhbmQgZmlsZSBleHRlbnNpb25zLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIC0gVGhlIG9yaWdpbmFsIGV4cG9ydCB0eXBlLlxuICogQHBhcmFtIHtzdHJpbmd9IG91dGZpbGUgLSBUaGUgZmlsZSBwYXRoIG9yIG5hbWUuXG4gKlxuICogQHJldHVybnMge3N0cmluZ30gLSBUaGUgY29ycmVjdGVkIGV4cG9ydCB0eXBlLlxuICovXG5leHBvcnQgY29uc3QgZml4VHlwZSA9ICh0eXBlLCBvdXRmaWxlKSA9PiB7XG4gIC8vIE1JTUUgdHlwZXNcbiAgY29uc3QgbWltZVR5cGVzID0ge1xuICAgICdpbWFnZS9wbmcnOiAncG5nJyxcbiAgICAnaW1hZ2UvanBlZyc6ICdqcGVnJyxcbiAgICAnYXBwbGljYXRpb24vcGRmJzogJ3BkZicsXG4gICAgJ2ltYWdlL3N2Zyt4bWwnOiAnc3ZnJ1xuICB9O1xuXG4gIC8vIEZvcm1hdHNcbiAgY29uc3QgZm9ybWF0cyA9IFsncG5nJywgJ2pwZWcnLCAncGRmJywgJ3N2ZyddO1xuXG4gIC8vIENoZWNrIGlmIHR5cGUgYW5kIG91dGZpbGUncyBleHRlbnNpb25zIGFyZSB0aGUgc2FtZVxuICBpZiAob3V0ZmlsZSkge1xuICAgIGNvbnN0IG91dFR5cGUgPSBvdXRmaWxlLnNwbGl0KCcuJykucG9wKCk7XG5cbiAgICBpZiAob3V0VHlwZSA9PT0gJ2pwZycpIHtcbiAgICAgIHR5cGUgPSAnanBlZyc7XG4gICAgfSBlbHNlIGlmIChmb3JtYXRzLmluY2x1ZGVzKG91dFR5cGUpICYmIHR5cGUgIT09IG91dFR5cGUpIHtcbiAgICAgIHR5cGUgPSBvdXRUeXBlO1xuICAgIH1cbiAgfVxuXG4gIC8vIFJldHVybiBhIGNvcnJlY3QgdHlwZVxuICByZXR1cm4gbWltZVR5cGVzW3R5cGVdIHx8IGZvcm1hdHMuZmluZCgodCkgPT4gdCA9PT0gdHlwZSkgfHwgJ3BuZyc7XG59O1xuXG4vKipcbiAqIEhhbmRsZXMgYW5kIHZhbGlkYXRlcyByZXNvdXJjZXMgZm9yIGV4cG9ydC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdHxzdHJpbmd9IHJlc291cmNlcyAtIFRoZSByZXNvdXJjZXMgdG8gYmUgaGFuZGxlZC4gQ2FuIGJlIGVpdGhlclxuICogYSBKU09OIG9iamVjdCwgc3RyaW5naWZpZWQgSlNPTiBvciBhIHBhdGggdG8gYSBKU09OIGZpbGUuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGFsbG93RmlsZVJlc291cmNlcyAtIFdoZXRoZXIgdG8gYWxsb3cgbG9hZGluZyByZXNvdXJjZXMgZnJvbVxuICogZmlsZXMuXG4gKlxuICogQHJldHVybnMge09iamVjdHx1bmRlZmluZWR9IC0gVGhlIGhhbmRsZWQgcmVzb3VyY2VzIG9yIHVuZGVmaW5lZCBpZiBubyB2YWxpZFxuICogcmVzb3VyY2VzIGFyZSBmb3VuZC5cbiAqL1xuZXhwb3J0IGNvbnN0IGhhbmRsZVJlc291cmNlcyA9IChyZXNvdXJjZXMgPSBmYWxzZSwgYWxsb3dGaWxlUmVzb3VyY2VzKSA9PiB7XG4gIGNvbnN0IGFsbG93ZWRQcm9wcyA9IFsnanMnLCAnY3NzJywgJ2ZpbGVzJ107XG5cbiAgbGV0IGhhbmRsZWRSZXNvdXJjZXMgPSByZXNvdXJjZXM7XG4gIGxldCBjb3JyZWN0UmVzb3VyY2VzID0gZmFsc2U7XG5cbiAgLy8gVHJ5IHRvIGxvYWQgcmVzb3VyY2VzIGZyb20gYSBmaWxlXG4gIGlmIChhbGxvd0ZpbGVSZXNvdXJjZXMgJiYgcmVzb3VyY2VzLmVuZHNXaXRoKCcuanNvbicpKSB7XG4gICAgdHJ5IHtcbiAgICAgIGhhbmRsZWRSZXNvdXJjZXMgPSBpc0NvcnJlY3RKU09OKHJlYWRGaWxlU3luYyhyZXNvdXJjZXMsICd1dGY4JykpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICByZXR1cm4gbG9nV2l0aFN0YWNrKDIsIGVycm9yLCBgW2NsaV0gTm8gcmVzb3VyY2VzIGZvdW5kLmApO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICAvLyBUcnkgdG8gZ2V0IEpTT05cbiAgICBoYW5kbGVkUmVzb3VyY2VzID0gaXNDb3JyZWN0SlNPTihyZXNvdXJjZXMpO1xuXG4gICAgLy8gR2V0IHJpZCBvZiB0aGUgZmlsZXMgc2VjdGlvblxuICAgIGlmIChoYW5kbGVkUmVzb3VyY2VzICYmICFhbGxvd0ZpbGVSZXNvdXJjZXMpIHtcbiAgICAgIGRlbGV0ZSBoYW5kbGVkUmVzb3VyY2VzLmZpbGVzO1xuICAgIH1cbiAgfVxuXG4gIC8vIEZpbHRlciBmcm9tIHVubmVjZXNzYXJ5IHByb3BlcnRpZXNcbiAgZm9yIChjb25zdCBwcm9wTmFtZSBpbiBoYW5kbGVkUmVzb3VyY2VzKSB7XG4gICAgaWYgKCFhbGxvd2VkUHJvcHMuaW5jbHVkZXMocHJvcE5hbWUpKSB7XG4gICAgICBkZWxldGUgaGFuZGxlZFJlc291cmNlc1twcm9wTmFtZV07XG4gICAgfSBlbHNlIGlmICghY29ycmVjdFJlc291cmNlcykge1xuICAgICAgY29ycmVjdFJlc291cmNlcyA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgLy8gQ2hlY2sgaWYgYXQgbGVhc3Qgb25lIG9mIGFsbG93ZWQgcHJvcGVydGllcyBpcyBwcmVzZW50XG4gIGlmICghY29ycmVjdFJlc291cmNlcykge1xuICAgIHJldHVybiBsb2coMywgYFtjbGldIE5vIHJlc291cmNlcyBmb3VuZC5gKTtcbiAgfVxuXG4gIC8vIEhhbmRsZSBmaWxlcyBzZWN0aW9uXG4gIGlmIChoYW5kbGVkUmVzb3VyY2VzLmZpbGVzKSB7XG4gICAgaGFuZGxlZFJlc291cmNlcy5maWxlcyA9IGhhbmRsZWRSZXNvdXJjZXMuZmlsZXMubWFwKChpdGVtKSA9PiBpdGVtLnRyaW0oKSk7XG4gICAgaWYgKCFoYW5kbGVkUmVzb3VyY2VzLmZpbGVzIHx8IGhhbmRsZWRSZXNvdXJjZXMuZmlsZXMubGVuZ3RoIDw9IDApIHtcbiAgICAgIGRlbGV0ZSBoYW5kbGVkUmVzb3VyY2VzLmZpbGVzO1xuICAgIH1cbiAgfVxuXG4gIC8vIFJldHVybiByZXNvdXJjZXNcbiAgcmV0dXJuIGhhbmRsZWRSZXNvdXJjZXM7XG59O1xuXG4vKipcbiAqIFZhbGlkYXRlcyBhbmQgcGFyc2VzIEpTT04gZGF0YS4gQ2hlY2tzIGlmIHByb3ZpZGVkIGRhdGEgaXMgb3IgY2FuXG4gKiBiZSBhIGNvcnJlY3QgSlNPTi4gSWYgYSBwcmltaXRpdmUgaXMgcHJvdmlkZWQsIGl0IGlzIHN0cmluZ2lmaWVkIGFuZCByZXR1cm5lZC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdHxzdHJpbmd9IGRhdGEgLSBUaGUgSlNPTiBkYXRhIHRvIGJlIHZhbGlkYXRlZCBhbmQgcGFyc2VkLlxuICogQHBhcmFtIHtib29sZWFufSB0b1N0cmluZyAtIFdoZXRoZXIgdG8gcmV0dXJuIGEgc3RyaW5naWZpZWQgcmVwcmVzZW50YXRpb25cbiAqIG9mIHRoZSBwYXJzZWQgSlNPTi5cbiAqXG4gKiBAcmV0dXJucyB7T2JqZWN0fHN0cmluZ3xib29sZWFufSAtIFRoZSBwYXJzZWQgSlNPTiBvYmplY3QsIHN0cmluZ2lmaWVkIEpTT04sXG4gKiBvciBmYWxzZSBpZiB2YWxpZGF0aW9uIGZhaWxzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNDb3JyZWN0SlNPTihkYXRhLCB0b1N0cmluZykge1xuICB0cnkge1xuICAgIC8vIEdldCB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIGlmIG5vdCBhbHJlYWR5IGJlZm9yZSBwYXJzaW5nXG4gICAgY29uc3QgcGFyc2VkRGF0YSA9IEpTT04ucGFyc2UoXG4gICAgICB0eXBlb2YgZGF0YSAhPT0gJ3N0cmluZycgPyBKU09OLnN0cmluZ2lmeShkYXRhKSA6IGRhdGFcbiAgICApO1xuXG4gICAgLy8gUmV0dXJuIGEgc3RyaW5naWZpZWQgcmVwcmVzZW50YXRpb24gb2YgYSBKU09OIGlmIHJlcXVpcmVkXG4gICAgaWYgKHR5cGVvZiBwYXJzZWREYXRhICE9PSAnc3RyaW5nJyAmJiB0b1N0cmluZykge1xuICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHBhcnNlZERhdGEpO1xuICAgIH1cblxuICAgIC8vIFJldHVybiBhIEpTT05cbiAgICByZXR1cm4gcGFyc2VkRGF0YTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBpdGVtIGlzIGFuIG9iamVjdC5cbiAqXG4gKiBAcGFyYW0ge2FueX0gaXRlbSAtIFRoZSBpdGVtIHRvIGJlIGNoZWNrZWQuXG4gKlxuICogQHJldHVybnMge2Jvb2xlYW59IC0gVHJ1ZSBpZiB0aGUgaXRlbSBpcyBhbiBvYmplY3QsIGZhbHNlIG90aGVyd2lzZS5cbiAqL1xuZXhwb3J0IGNvbnN0IGlzT2JqZWN0ID0gKGl0ZW0pID0+XG4gIHR5cGVvZiBpdGVtID09PSAnb2JqZWN0JyAmJiAhQXJyYXkuaXNBcnJheShpdGVtKSAmJiBpdGVtICE9PSBudWxsO1xuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gb2JqZWN0IGlzIGVtcHR5LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBpdGVtIC0gVGhlIG9iamVjdCB0byBiZSBjaGVja2VkLlxuICpcbiAqIEByZXR1cm5zIHtib29sZWFufSAtIFRydWUgaWYgdGhlIG9iamVjdCBpcyBlbXB0eSwgZmFsc2Ugb3RoZXJ3aXNlLlxuICovXG5leHBvcnQgY29uc3QgaXNPYmplY3RFbXB0eSA9IChpdGVtKSA9PlxuICB0eXBlb2YgaXRlbSA9PT0gJ29iamVjdCcgJiZcbiAgIUFycmF5LmlzQXJyYXkoaXRlbSkgJiZcbiAgaXRlbSAhPT0gbnVsbCAmJlxuICBPYmplY3Qua2V5cyhpdGVtKS5sZW5ndGggPT09IDA7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGEgcHJpdmF0ZSBJUCByYW5nZSBVUkwgaXMgZm91bmQgaW4gdGhlIGdpdmVuIHN0cmluZy5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gaXRlbSAtIFRoZSBzdHJpbmcgdG8gYmUgY2hlY2tlZCBmb3IgYSBwcml2YXRlIElQIHJhbmdlIFVSTC5cbiAqXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBUcnVlIGlmIGEgcHJpdmF0ZSBJUCByYW5nZSBVUkwgaXMgZm91bmQsIGZhbHNlXG4gKiBvdGhlcndpc2UuXG4gKi9cbmV4cG9ydCBjb25zdCBpc1ByaXZhdGVSYW5nZVVybEZvdW5kID0gKGl0ZW0pID0+IHtcbiAgY29uc3QgcmVnZXhQYXR0ZXJucyA9IFtcbiAgICAveGxpbms6aHJlZj1cIig/Omh0dHA6XFwvXFwvfGh0dHBzOlxcL1xcLyk/bG9jYWxob3N0XFxiLyxcbiAgICAveGxpbms6aHJlZj1cIig/Omh0dHA6XFwvXFwvfGh0dHBzOlxcL1xcLyk/MTBcXC5cXGR7MSwzfVxcLlxcZHsxLDN9XFwuXFxkezEsM31cXGIvLFxuICAgIC94bGluazpocmVmPVwiKD86aHR0cDpcXC9cXC98aHR0cHM6XFwvXFwvKT8xMjdcXC5cXGR7MSwzfVxcLlxcZHsxLDN9XFwuXFxkezEsM31cXGIvLFxuICAgIC94bGluazpocmVmPVwiKD86aHR0cDpcXC9cXC98aHR0cHM6XFwvXFwvKT8xNzJcXC4oMVs2LTldfDJbMC05XXwzWzAtMV0pXFwuXFxkezEsM31cXC5cXGR7MSwzfVxcYi8sXG4gICAgL3hsaW5rOmhyZWY9XCIoPzpodHRwOlxcL1xcL3xodHRwczpcXC9cXC8pPzE5MlxcLjE2OFxcLlxcZHsxLDN9XFwuXFxkezEsM31cXGIvXG4gIF07XG5cbiAgcmV0dXJuIHJlZ2V4UGF0dGVybnMuc29tZSgocGF0dGVybikgPT4gcGF0dGVybi50ZXN0KGl0ZW0pKTtcbn07XG5cbi8qKlxuICogQ3JlYXRlcyBhIGRlZXAgY29weSBvZiB0aGUgZ2l2ZW4gb2JqZWN0IG9yIGFycmF5LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fEFycmF5fSBvYmogLSBUaGUgb2JqZWN0IG9yIGFycmF5IHRvIGJlIGRlZXBseSBjb3BpZWQuXG4gKlxuICogQHJldHVybnMge09iamVjdHxBcnJheX0gLSBUaGUgZGVlcCBjb3B5IG9mIHRoZSBwcm92aWRlZCBvYmplY3Qgb3IgYXJyYXkuXG4gKi9cbmV4cG9ydCBjb25zdCBkZWVwQ29weSA9IChvYmopID0+IHtcbiAgaWYgKG9iaiA9PT0gbnVsbCB8fCB0eXBlb2Ygb2JqICE9PSAnb2JqZWN0Jykge1xuICAgIHJldHVybiBvYmo7XG4gIH1cblxuICBjb25zdCBjb3B5ID0gQXJyYXkuaXNBcnJheShvYmopID8gW10gOiB7fTtcblxuICBmb3IgKGNvbnN0IGtleSBpbiBvYmopIHtcbiAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KSkge1xuICAgICAgY29weVtrZXldID0gZGVlcENvcHkob2JqW2tleV0pO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBjb3B5O1xufTtcblxuLyoqXG4gKiBDb252ZXJ0cyB0aGUgcHJvdmlkZWQgb3B0aW9ucyBvYmplY3QgdG8gYSBKU09OLWZvcm1hdHRlZCBzdHJpbmcgd2l0aCB0aGVcbiAqIG9wdGlvbiB0byBwcmVzZXJ2ZSBmdW5jdGlvbnMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgLSBUaGUgb3B0aW9ucyBvYmplY3QgdG8gYmUgY29udmVydGVkIHRvIGEgc3RyaW5nLlxuICogQHBhcmFtIHtib29sZWFufSBhbGxvd0Z1bmN0aW9ucyAtIElmIHNldCB0byB0cnVlLCBmdW5jdGlvbnMgYXJlIHByZXNlcnZlZFxuICogaW4gdGhlIG91dHB1dC5cbiAqXG4gKiBAcmV0dXJucyB7c3RyaW5nfSAtIFRoZSBKU09OLWZvcm1hdHRlZCBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBvcHRpb25zLlxuICovXG5leHBvcnQgY29uc3Qgb3B0aW9uc1N0cmluZ2lmeSA9IChvcHRpb25zLCBhbGxvd0Z1bmN0aW9ucykgPT4ge1xuICBjb25zdCByZXBsYWNlckNhbGxiYWNrID0gKG5hbWUsIHZhbHVlKSA9PiB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHZhbHVlID0gdmFsdWUudHJpbSgpO1xuXG4gICAgICAvLyBJZiBhbGxvd0Z1bmN0aW9ucyBpcyBzZXQgdG8gdHJ1ZSwgcHJlc2VydmUgZnVuY3Rpb25zXG4gICAgICBpZiAoXG4gICAgICAgICh2YWx1ZS5zdGFydHNXaXRoKCdmdW5jdGlvbignKSB8fCB2YWx1ZS5zdGFydHNXaXRoKCdmdW5jdGlvbiAoJykpICYmXG4gICAgICAgIHZhbHVlLmVuZHNXaXRoKCd9JylcbiAgICAgICkge1xuICAgICAgICB2YWx1ZSA9IGFsbG93RnVuY3Rpb25zXG4gICAgICAgICAgPyBgRVhQX0ZVTiR7KHZhbHVlICsgJycpLnJlcGxhY2VBbGwoL1xcbnxcXHR8XFxyL2csICcgJyl9RVhQX0ZVTmBcbiAgICAgICAgICA6IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nXG4gICAgICA/IGBFWFBfRlVOJHsodmFsdWUgKyAnJykucmVwbGFjZUFsbCgvXFxufFxcdHxcXHIvZywgJyAnKX1FWFBfRlVOYFxuICAgICAgOiB2YWx1ZTtcbiAgfTtcblxuICAvLyBTdHJpbmdpZnkgb3B0aW9ucyBhbmQgaWYgcmVxdWlyZWQsIHJlcGxhY2Ugc3BlY2lhbCBmdW5jdGlvbnMgbWFya3NcbiAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KG9wdGlvbnMsIHJlcGxhY2VyQ2FsbGJhY2spLnJlcGxhY2VBbGwoXG4gICAgL1wiRVhQX0ZVTnxFWFBfRlVOXCIvZyxcbiAgICAnJ1xuICApO1xufTtcblxuLyoqXG4gKiBQcmludHMgdGhlIEhpZ2hjaGFydHMgRXhwb3J0IFNlcnZlciBsb2dvIGFuZCB2ZXJzaW9uIGluZm9ybWF0aW9uLlxuICpcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gbm9Mb2dvIC0gSWYgdHJ1ZSwgb25seSBwcmludHMgdmVyc2lvbiBpbmZvcm1hdGlvbiB3aXRob3V0XG4gKiB0aGUgbG9nby5cbiAqL1xuZXhwb3J0IGNvbnN0IHByaW50TG9nbyA9IChub0xvZ28pID0+IHtcbiAgLy8gR2V0IHBhY2thZ2UgdmVyc2lvbiBlaXRoZXIgZnJvbSBlbnYgb3IgZnJvbSBwYWNrYWdlLmpzb25cbiAgY29uc3QgcGFja2FnZVZlcnNpb24gPSBKU09OLnBhcnNlKFxuICAgIHJlYWRGaWxlU3luYyhqb2luKF9fZGlybmFtZSwgJ3BhY2thZ2UuanNvbicpKVxuICApLnZlcnNpb247XG5cbiAgLy8gUHJpbnQgdGV4dCBvbmx5XG4gIGlmIChub0xvZ28pIHtcbiAgICBjb25zb2xlLmxvZyhgU3RhcnRpbmcgSGlnaGNoYXJ0cyBFeHBvcnQgU2VydmVyIHYke3BhY2thZ2VWZXJzaW9ufS4uLmApO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIFByaW50IHRoZSBsb2dvXG4gIGNvbnNvbGUubG9nKFxuICAgIHJlYWRGaWxlU3luYyhfX2Rpcm5hbWUgKyAnL21zZy9zdGFydHVwLm1zZycpLnRvU3RyaW5nKCkuYm9sZC55ZWxsb3csXG4gICAgYHYke3BhY2thZ2VWZXJzaW9ufVxcbmAuYm9sZFxuICApO1xufTtcblxuLyoqXG4gKiBQcmludHMgdGhlIHVzYWdlIGluZm9ybWF0aW9uIGZvciBDTEkgYXJndW1lbnRzLiBJZiByZXF1aXJlZCwgaXQgY2FuIGxpc3RcbiAqIHByb3BlcnRpZXMgcmVjdXJzaXZlbHlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHByaW50VXNhZ2UoKSB7XG4gIGNvbnN0IHBhZCA9IDQ4O1xuICBjb25zdCByZWFkbWUgPSAnaHR0cHM6Ly9naXRodWIuY29tL2hpZ2hjaGFydHMvbm9kZS1leHBvcnQtc2VydmVyI3JlYWRtZSc7XG5cbiAgLy8gRGlzcGxheSByZWFkbWUgaW5mb3JtYXRpb25cbiAgY29uc29sZS5sb2coXG4gICAgJ1xcblVzYWdlIG9mIENMSSBhcmd1bWVudHM6Jy5ib2xkLFxuICAgICdcXG4tLS0tLS0nLFxuICAgIGBcXG5Gb3IgbW9yZSBkZXRhaWxlZCBpbmZvcm1hdGlvbiwgdmlzaXQgdGhlIHJlYWRtZSBhdDogJHtyZWFkbWUuYm9sZC55ZWxsb3d9LmBcbiAgKTtcblxuICBjb25zdCBjeWNsZUNhdGVnb3JpZXMgPSAob3B0aW9ucykgPT4ge1xuICAgIGZvciAoY29uc3QgW25hbWUsIG9wdGlvbl0gb2YgT2JqZWN0LmVudHJpZXMob3B0aW9ucykpIHtcbiAgICAgIC8vIElmIGNhdGVnb3J5IGhhcyBtb3JlIGxldmVscywgZ28gZnVydGhlclxuICAgICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob3B0aW9uLCAndmFsdWUnKSkge1xuICAgICAgICBjeWNsZUNhdGVnb3JpZXMob3B0aW9uKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxldCBkZXNjTmFtZSA9IGAgIC0tJHtvcHRpb24uY2xpTmFtZSB8fCBuYW1lfSAke1xuICAgICAgICAgICgnPCcgKyBvcHRpb24udHlwZSArICc+JykuZ3JlZW5cbiAgICAgICAgfSBgO1xuICAgICAgICBpZiAoZGVzY05hbWUubGVuZ3RoIDwgcGFkKSB7XG4gICAgICAgICAgZm9yIChsZXQgaSA9IGRlc2NOYW1lLmxlbmd0aDsgaSA8IHBhZDsgaSsrKSB7XG4gICAgICAgICAgICBkZXNjTmFtZSArPSAnLic7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gRGlzcGxheSBjb3JyZWN0bHkgYWxpZ25lZCBtZXNzYWdlc1xuICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICBkZXNjTmFtZSxcbiAgICAgICAgICBvcHRpb24uZGVzY3JpcHRpb24sXG4gICAgICAgICAgYFtEZWZhdWx0OiAke29wdGlvbi52YWx1ZS50b1N0cmluZygpLmJvbGR9XWAuYmx1ZVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICAvLyBDeWNsZSB0aHJvdWdoIG9wdGlvbnMgb2YgZWFjaCBjYXRlZ29yaWVzIGFuZCBkaXNwbGF5IHRoZSB1c2FnZSBpbmZvXG4gIE9iamVjdC5rZXlzKGRlZmF1bHRDb25maWcpLmZvckVhY2goKGNhdGVnb3J5KSA9PiB7XG4gICAgLy8gT25seSBwdXBwZXRlZXIgYW5kIGhpZ2hjaGFydHMgY2F0ZWdvcmllcyBjYW5ub3QgYmUgY29uZmlndXJlZCB0aHJvdWdoIENMSVxuICAgIGlmICghWydwdXBwZXRlZXInLCAnaGlnaGNoYXJ0cyddLmluY2x1ZGVzKGNhdGVnb3J5KSkge1xuICAgICAgY29uc29sZS5sb2coYFxcbiR7Y2F0ZWdvcnkudG9VcHBlckNhc2UoKX1gLnJlZCk7XG4gICAgICBjeWNsZUNhdGVnb3JpZXMoZGVmYXVsdENvbmZpZ1tjYXRlZ29yeV0pO1xuICAgIH1cbiAgfSk7XG4gIGNvbnNvbGUubG9nKCdcXG4nKTtcbn1cblxuLyoqXG4gKiBSb3VuZHMgYSBudW1iZXIgdG8gdGhlIHNwZWNpZmllZCBwcmVjaXNpb24uXG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIC0gVGhlIG51bWJlciB0byBiZSByb3VuZGVkLlxuICogQHBhcmFtIHtudW1iZXJ9IHByZWNpc2lvbiAtIFRoZSBudW1iZXIgb2YgZGVjaW1hbCBwbGFjZXMgdG8gcm91bmQgdG8uXG4gKlxuICogQHJldHVybnMge251bWJlcn0gLSBUaGUgcm91bmRlZCBudW1iZXIuXG4gKi9cbmV4cG9ydCBjb25zdCByb3VuZE51bWJlciA9ICh2YWx1ZSwgcHJlY2lzaW9uID0gMSkgPT4ge1xuICBjb25zdCBtdWx0aXBsaWVyID0gTWF0aC5wb3coMTAsIHByZWNpc2lvbiB8fCAwKTtcbiAgcmV0dXJuIE1hdGgucm91bmQoK3ZhbHVlICogbXVsdGlwbGllcikgLyBtdWx0aXBsaWVyO1xufTtcblxuLyoqXG4gKiBDb252ZXJ0cyBhIHZhbHVlIHRvIGEgYm9vbGVhbi5cbiAqXG4gKiBAcGFyYW0ge2FueX0gaXRlbSAtIFRoZSB2YWx1ZSB0byBiZSBjb252ZXJ0ZWQgdG8gYSBib29sZWFuLlxuICpcbiAqIEByZXR1cm5zIHtib29sZWFufSAtIFRoZSBib29sZWFuIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBpbnB1dCB2YWx1ZS5cbiAqL1xuZXhwb3J0IGNvbnN0IHRvQm9vbGVhbiA9IChpdGVtKSA9PlxuICBbJ2ZhbHNlJywgJ3VuZGVmaW5lZCcsICdudWxsJywgJ05hTicsICcwJywgJyddLmluY2x1ZGVzKGl0ZW0pXG4gICAgPyBmYWxzZVxuICAgIDogISFpdGVtO1xuXG4vKipcbiAqIFdyYXBzIGN1c3RvbSBjb2RlIHRvIGV4ZWN1dGUgaXQgc2FmZWx5LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBjdXN0b21Db2RlIC0gVGhlIGN1c3RvbSBjb2RlIHRvIGJlIHdyYXBwZWQuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGFsbG93RmlsZVJlc291cmNlcyAtIEZsYWcgdG8gYWxsb3cgbG9hZGluZyBjb2RlIGZyb20gYSBmaWxlLlxuICpcbiAqIEByZXR1cm5zIHtzdHJpbmd8Ym9vbGVhbn0gLSBUaGUgd3JhcHBlZCBjdXN0b20gY29kZSBvciBmYWxzZSBpZiB3cmFwcGluZ1xuICogZmFpbHMuXG4gKi9cbmV4cG9ydCBjb25zdCB3cmFwQXJvdW5kID0gKGN1c3RvbUNvZGUsIGFsbG93RmlsZVJlc291cmNlcykgPT4ge1xuICBpZiAoY3VzdG9tQ29kZSAmJiB0eXBlb2YgY3VzdG9tQ29kZSA9PT0gJ3N0cmluZycpIHtcbiAgICBjdXN0b21Db2RlID0gY3VzdG9tQ29kZS50cmltKCk7XG5cbiAgICBpZiAoY3VzdG9tQ29kZS5lbmRzV2l0aCgnLmpzJykpIHtcbiAgICAgIHJldHVybiBhbGxvd0ZpbGVSZXNvdXJjZXNcbiAgICAgICAgPyB3cmFwQXJvdW5kKHJlYWRGaWxlU3luYyhjdXN0b21Db2RlLCAndXRmOCcpKVxuICAgICAgICA6IGZhbHNlO1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICBjdXN0b21Db2RlLnN0YXJ0c1dpdGgoJ2Z1bmN0aW9uKCknKSB8fFxuICAgICAgY3VzdG9tQ29kZS5zdGFydHNXaXRoKCdmdW5jdGlvbiAoKScpIHx8XG4gICAgICBjdXN0b21Db2RlLnN0YXJ0c1dpdGgoJygpPT4nKSB8fFxuICAgICAgY3VzdG9tQ29kZS5zdGFydHNXaXRoKCcoKSA9PicpXG4gICAgKSB7XG4gICAgICByZXR1cm4gYCgke2N1c3RvbUNvZGV9KSgpYDtcbiAgICB9XG4gICAgcmV0dXJuIGN1c3RvbUNvZGUucmVwbGFjZSgvOyQvLCAnJyk7XG4gIH1cbn07XG5cbi8qKlxuICogVXRpbGl0eSB0byBtZWFzdXJlIGVsYXBzZWQgdGltZSB1c2luZyB0aGUgTm9kZS5qcyBwcm9jZXNzLmhydGltZSgpIG1ldGhvZC5cbiAqXG4gKiBAcmV0dXJucyB7ZnVuY3Rpb24oKTogbnVtYmVyfSAtIEEgZnVuY3Rpb24gdG8gY2FsY3VsYXRlIHRoZSBlbGFwc2VkIHRpbWVcbiAqIGluIG1pbGxpc2Vjb25kcy5cbiAqL1xuZXhwb3J0IGNvbnN0IG1lYXN1cmVUaW1lID0gKCkgPT4ge1xuICBjb25zdCBzdGFydCA9IHByb2Nlc3MuaHJ0aW1lLmJpZ2ludCgpO1xuICByZXR1cm4gKCkgPT4gTnVtYmVyKHByb2Nlc3MuaHJ0aW1lLmJpZ2ludCgpIC0gc3RhcnQpIC8gMTAwMDAwMDtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19kaXJuYW1lLFxuICBjbGVhclRleHQsXG4gIGV4cEJhY2tvZmYsXG4gIGZpeFR5cGUsXG4gIGhhbmRsZVJlc291cmNlcyxcbiAgaXNDb3JyZWN0SlNPTixcbiAgaXNPYmplY3QsXG4gIGlzT2JqZWN0RW1wdHksXG4gIGlzUHJpdmF0ZVJhbmdlVXJsRm91bmQsXG4gIG9wdGlvbnNTdHJpbmdpZnksXG4gIHByaW50TG9nbyxcbiAgcHJpbnRVc2FnZSxcbiAgcm91bmROdW1iZXIsXG4gIHRvQm9vbGVhbixcbiAgd3JhcEFyb3VuZCxcbiAgbWVhc3VyZVRpbWVcbn07XG4iLCIvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuXG5IaWdoY2hhcnRzIEV4cG9ydCBTZXJ2ZXJcblxuQ29weXJpZ2h0IChjKSAyMDE2LTIwMjQsIEhpZ2hzb2Z0XG5cbkxpY2VuY2VkIHVuZGVyIHRoZSBNSVQgbGljZW5jZS5cblxuQWRkaXRpb25hbGx5IGEgdmFsaWQgSGlnaGNoYXJ0cyBsaWNlbnNlIGlzIHJlcXVpcmVkIGZvciB1c2UuXG5cblNlZSBMSUNFTlNFIGZpbGUgaW4gcm9vdCBmb3IgZGV0YWlscy5cblxuKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuaW1wb3J0IHsgZXhpc3RzU3luYywgcmVhZEZpbGVTeW5jLCBwcm9taXNlcyBhcyBmc1Byb21pc2VzIH0gZnJvbSAnZnMnO1xuXG5pbXBvcnQgcHJvbXB0cyBmcm9tICdwcm9tcHRzJztcblxuaW1wb3J0IHtcbiAgYWJzb2x1dGVQcm9wcyxcbiAgZGVmYXVsdENvbmZpZyxcbiAgbmVzdGVkQXJncyxcbiAgcHJvbXB0c0NvbmZpZ1xufSBmcm9tICcuL3NjaGVtYXMvY29uZmlnLmpzJztcbmltcG9ydCB7IGVudnMgfSBmcm9tICcuL2VudnMuanMnO1xuaW1wb3J0IHsgbG9nLCBsb2dXaXRoU3RhY2sgfSBmcm9tICcuL2xvZ2dlci5qcyc7XG5pbXBvcnQgeyBkZWVwQ29weSwgaXNPYmplY3QsIHByaW50VXNhZ2UsIHRvQm9vbGVhbiB9IGZyb20gJy4vdXRpbHMuanMnO1xuXG5sZXQgZ2VuZXJhbE9wdGlvbnMgPSB7fTtcblxuLyoqXG4gKiBSZXRyaWV2ZXMgYW5kIHJldHVybnMgdGhlIGdlbmVyYWwgb3B0aW9ucyBmb3IgdGhlIGV4cG9ydCBwcm9jZXNzLlxuICpcbiAqIEByZXR1cm5zIHtPYmplY3R9IFRoZSBnZW5lcmFsIG9wdGlvbnMgb2JqZWN0LlxuICovXG5leHBvcnQgY29uc3QgZ2V0T3B0aW9ucyA9ICgpID0+IGdlbmVyYWxPcHRpb25zO1xuXG4vKipcbiAqIEluaXRpYWxpemVzIGFuZCBzZXRzIHRoZSBnZW5lcmFsIG9wdGlvbnMgZm9yIHRoZSBzZXJ2ZXIgaW5zdGFjZSwga2VlcGluZ1xuICogdGhlIHByaW5jaXBsZSBvZiB0aGUgb3B0aW9ucyBsb2FkIHByaW9yaXR5LiBJdCBhY2NlcHRzIG9wdGlvbmFsIHVzZXJPcHRpb25zXG4gKiBhbmQgYXJncyBmcm9tIHRoZSBDTEkuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHVzZXJPcHRpb25zIC0gVXNlci1wcm92aWRlZCBvcHRpb25zIGZvciBjdXN0b21pemF0aW9uLlxuICogQHBhcmFtIHtBcnJheX0gYXJncyAtIENvbW1hbmQtbGluZSBhcmd1bWVudHMgZm9yIGFkZGl0aW9uYWwgY29uZmlndXJhdGlvblxuICogKENMSSB1c2FnZSkuXG4gKlxuICogQHJldHVybnMge09iamVjdH0gVGhlIHVwZGF0ZWQgZ2VuZXJhbCBvcHRpb25zIG9iamVjdC5cbiAqL1xuZXhwb3J0IGNvbnN0IHNldE9wdGlvbnMgPSAodXNlck9wdGlvbnMsIGFyZ3MpID0+IHtcbiAgLy8gT25seSBmb3IgdGhlIENMSSB1c2FnZVxuICBpZiAoYXJncz8ubGVuZ3RoKSB7XG4gICAgLy8gR2V0IHRoZSBhZGRpdGlvbmFsIG9wdGlvbnMgZnJvbSB0aGUgY3VzdG9tIEpTT04gZmlsZVxuICAgIGdlbmVyYWxPcHRpb25zID0gbG9hZENvbmZpZ0ZpbGUoYXJncyk7XG4gIH1cblxuICAvLyBVcGRhdGUgdGhlIGRlZmF1bHQgY29uZmlnIHdpdGggYSBjb3JyZWN0IG9wdGlvbiB2YWx1ZXNcbiAgdXBkYXRlRGVmYXVsdENvbmZpZyhkZWZhdWx0Q29uZmlnLCBnZW5lcmFsT3B0aW9ucyk7XG5cbiAgLy8gU2V0IHZhbHVlcyBmb3Igc2VydmVyJ3Mgb3B0aW9ucyBhbmQgcmV0dXJucyB0aGVtXG4gIGdlbmVyYWxPcHRpb25zID0gaW5pdE9wdGlvbnMoZGVmYXVsdENvbmZpZyk7XG5cbiAgLy8gQXBwbHkgdXNlciBvcHRpb25zIGlmIHRoZXJlIGFyZSBhbnlcbiAgaWYgKHVzZXJPcHRpb25zKSB7XG4gICAgLy8gTWVyZ2UgdXNlciBvcHRpb25zXG4gICAgZ2VuZXJhbE9wdGlvbnMgPSBtZXJnZUNvbmZpZ09wdGlvbnMoXG4gICAgICBnZW5lcmFsT3B0aW9ucyxcbiAgICAgIHVzZXJPcHRpb25zLFxuICAgICAgYWJzb2x1dGVQcm9wc1xuICAgICk7XG4gIH1cblxuICAvLyBPbmx5IGZvciB0aGUgQ0xJIHVzYWdlXG4gIGlmIChhcmdzPy5sZW5ndGgpIHtcbiAgICAvLyBQYWlyIHByb3ZpZGVkIGFyZ3VtZW50c1xuICAgIGdlbmVyYWxPcHRpb25zID0gcGFpckFyZ3VtZW50VmFsdWUoZ2VuZXJhbE9wdGlvbnMsIGFyZ3MsIGRlZmF1bHRDb25maWcpO1xuICB9XG5cbiAgLy8gUmV0dXJuIGZpbmFsIGdlbmVyYWwgb3B0aW9uc1xuICByZXR1cm4gZ2VuZXJhbE9wdGlvbnM7XG59O1xuXG4vKipcbiAqIEFsbG93cyBtYW51YWwgY29uZmlndXJhdGlvbiBiYXNlZCBvbiBzcGVjaWZpZWQgcHJvbXB0cyBhbmQgc2F2ZXNcbiAqIHRoZSBjb25maWd1cmF0aW9uIHRvIGEgZmlsZS5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gY29uZmlnRmlsZU5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgY29uZmlndXJhdGlvbiBmaWxlLlxuICpcbiAqIEByZXR1cm5zIHtQcm9taXNlPGJvb2xlYW4+fSBBIFByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0cnVlIG9uY2UgdGhlIG1hbnVhbFxuICogY29uZmlndXJhdGlvbiBpcyBjb21wbGV0ZWQgYW5kIHNhdmVkLlxuICovXG5leHBvcnQgY29uc3QgbWFudWFsQ29uZmlnID0gYXN5bmMgKGNvbmZpZ0ZpbGVOYW1lKSA9PiB7XG4gIC8vIFByZXBhcmUgYSBjb25maWcgb2JqZWN0XG4gIGxldCBjb25maWdGaWxlID0ge307XG5cbiAgLy8gQ2hlY2sgaWYgcHJvdmlkZWQgY29uZmlnIGZpbGUgZXhpc3RzXG4gIGlmIChleGlzdHNTeW5jKGNvbmZpZ0ZpbGVOYW1lKSkge1xuICAgIGNvbmZpZ0ZpbGUgPSBKU09OLnBhcnNlKHJlYWRGaWxlU3luYyhjb25maWdGaWxlTmFtZSwgJ3V0ZjgnKSk7XG4gIH1cblxuICAvLyBRdWVzdGlvbiBhYm91dCBhIGNvbmZpZ3VyYXRpb24gY2F0ZWdvcnlcbiAgY29uc3Qgb25TdWJtaXQgPSBhc3luYyAocCwgY2F0ZWdvcmllcykgPT4ge1xuICAgIGxldCBxdWVzdGlvbnNDb3VudGVyID0gMDtcbiAgICBsZXQgYWxsUXVlc3Rpb25zID0gW107XG5cbiAgICAvLyBDcmVhdGUgYSBjb3JyZXNwb25kaW5nIHByb3BlcnR5IGluIHRoZSBtYW51YWxDb25maWcgb2JqZWN0XG4gICAgZm9yIChjb25zdCBzZWN0aW9uIG9mIGNhdGVnb3JpZXMpIHtcbiAgICAgIC8vIE1hcmsgZWFjaCBvcHRpb24gd2l0aCBhIHNlY3Rpb25cbiAgICAgIHByb21wdHNDb25maWdbc2VjdGlvbl0gPSBwcm9tcHRzQ29uZmlnW3NlY3Rpb25dLm1hcCgob3B0aW9uKSA9PiAoe1xuICAgICAgICAuLi5vcHRpb24sXG4gICAgICAgIHNlY3Rpb25cbiAgICAgIH0pKTtcblxuICAgICAgLy8gQ29sbGVjdCB0aGUgcXVlc3Rpb25zXG4gICAgICBhbGxRdWVzdGlvbnMgPSBbLi4uYWxsUXVlc3Rpb25zLCAuLi5wcm9tcHRzQ29uZmlnW3NlY3Rpb25dXTtcbiAgICB9XG5cbiAgICBhd2FpdCBwcm9tcHRzKGFsbFF1ZXN0aW9ucywge1xuICAgICAgb25TdWJtaXQ6IGFzeW5jIChwcm9tcHQsIGFuc3dlcikgPT4ge1xuICAgICAgICAvLyBHZXQgdGhlIGRlZmF1bHQgbW9kdWxlIHNjcmlwdHNcbiAgICAgICAgaWYgKHByb21wdC5uYW1lID09PSAnbW9kdWxlU2NyaXB0cycpIHtcbiAgICAgICAgICBhbnN3ZXIgPSBhbnN3ZXIubGVuZ3RoXG4gICAgICAgICAgICA/IGFuc3dlci5tYXAoKG1vZHVsZSkgPT4gcHJvbXB0LmNob2ljZXNbbW9kdWxlXSlcbiAgICAgICAgICAgIDogcHJvbXB0LmNob2ljZXM7XG5cbiAgICAgICAgICBjb25maWdGaWxlW3Byb21wdC5zZWN0aW9uXVtwcm9tcHQubmFtZV0gPSBhbnN3ZXI7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uZmlnRmlsZVtwcm9tcHQuc2VjdGlvbl0gPSByZWN1cnNpdmVQcm9wcyhcbiAgICAgICAgICAgIE9iamVjdC5hc3NpZ24oe30sIGNvbmZpZ0ZpbGVbcHJvbXB0LnNlY3Rpb25dIHx8IHt9KSxcbiAgICAgICAgICAgIHByb21wdC5uYW1lLnNwbGl0KCcuJyksXG4gICAgICAgICAgICBwcm9tcHQuY2hvaWNlcyA/IHByb21wdC5jaG9pY2VzW2Fuc3dlcl0gOiBhbnN3ZXJcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCsrcXVlc3Rpb25zQ291bnRlciA9PT0gYWxsUXVlc3Rpb25zLmxlbmd0aCkge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhd2FpdCBmc1Byb21pc2VzLndyaXRlRmlsZShcbiAgICAgICAgICAgICAgY29uZmlnRmlsZU5hbWUsXG4gICAgICAgICAgICAgIEpTT04uc3RyaW5naWZ5KGNvbmZpZ0ZpbGUsIG51bGwsIDIpLFxuICAgICAgICAgICAgICAndXRmOCdcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGxvZ1dpdGhTdGFjayhcbiAgICAgICAgICAgICAgMSxcbiAgICAgICAgICAgICAgZXJyb3IsXG4gICAgICAgICAgICAgIGBbY29uZmlnXSBBbiBlcnJvciBvY2N1cnJlZCB3aGlsZSBjcmVhdGluZyB0aGUgJHtjb25maWdGaWxlTmFtZX0gZmlsZS5gXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHRydWU7XG4gIH07XG5cbiAgLy8gRmluZCB0aGUgY2F0ZWdvcmllc1xuICBjb25zdCBjaG9pY2VzID0gT2JqZWN0LmtleXMocHJvbXB0c0NvbmZpZykubWFwKChjaG9pY2UpID0+ICh7XG4gICAgdGl0bGU6IGAke2Nob2ljZX0gb3B0aW9uc2AsXG4gICAgdmFsdWU6IGNob2ljZVxuICB9KSk7XG5cbiAgLy8gQ2F0ZWdvcnkgcHJvbXB0XG4gIHJldHVybiBwcm9tcHRzKFxuICAgIHtcbiAgICAgIHR5cGU6ICdtdWx0aXNlbGVjdCcsXG4gICAgICBuYW1lOiAnY2F0ZWdvcnknLFxuICAgICAgbWVzc2FnZTogJ1doaWNoIGNhdGVnb3J5IGRvIHlvdSB3YW50IHRvIGNvbmZpZ3VyZT8nLFxuICAgICAgaGludDogJ1NwYWNlOiBTZWxlY3Qgc3BlY2lmaWMsIEE6IFNlbGVjdCBhbGwsIEVudGVyOiBDb25maXJtLicsXG4gICAgICBpbnN0cnVjdGlvbnM6ICcnLFxuICAgICAgY2hvaWNlc1xuICAgIH0sXG4gICAgeyBvblN1Ym1pdCB9XG4gICk7XG59O1xuXG4vKipcbiAqIE1hcHMgb2xkLXN0cnVjdHVyZWQgKFBoYW50b21KUykgb3B0aW9ucyB0byBhIG5ldyBjb25maWd1cmF0aW9uIGZvcm1hdFxuICogKFB1cHBldGVlcikuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9sZE9wdGlvbnMgLSBPbGQtc3RydWN0dXJlZCBvcHRpb25zIHRvIGJlIG1hcHBlZC5cbiAqXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBOZXcgb3B0aW9ucyBzdHJ1Y3R1cmVkIGJhc2VkIG9uIHRoZSBkZWZpbmVkIG5lc3RlZEFyZ3NcbiAqIG1hcHBpbmcuXG4gKi9cbmV4cG9ydCBjb25zdCBtYXBUb05ld0NvbmZpZyA9IChvbGRPcHRpb25zKSA9PiB7XG4gIGNvbnN0IG5ld09wdGlvbnMgPSB7fTtcbiAgLy8gQ3ljbGUgdGhyb3VnaCBvbGQtc3RydWN0dXJlZCBvcHRpb25zXG4gIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKG9sZE9wdGlvbnMpKSB7XG4gICAgY29uc3QgcHJvcGVydGllc0NoYWluID0gbmVzdGVkQXJnc1trZXldID8gbmVzdGVkQXJnc1trZXldLnNwbGl0KCcuJykgOiBbXTtcblxuICAgIC8vIFBvcHVsYXRlIG9iamVjdCBpbiBjb3JyZWN0IHByb3BlcnRpZXMgbGV2ZWxzXG4gICAgcHJvcGVydGllc0NoYWluLnJlZHVjZShcbiAgICAgIChvYmosIHByb3AsIGluZGV4KSA9PlxuICAgICAgICAob2JqW3Byb3BdID1cbiAgICAgICAgICBwcm9wZXJ0aWVzQ2hhaW4ubGVuZ3RoIC0gMSA9PT0gaW5kZXggPyB2YWx1ZSA6IG9ialtwcm9wXSB8fCB7fSksXG4gICAgICBuZXdPcHRpb25zXG4gICAgKTtcbiAgfVxuICByZXR1cm4gbmV3T3B0aW9ucztcbn07XG5cbi8qKlxuICogTWVyZ2VzIHR3byBzZXRzIG9mIGNvbmZpZ3VyYXRpb24gb3B0aW9ucywgY29uc2lkZXJpbmcgYWJzb2x1dGUgcHJvcGVydGllcy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIE9yaWdpbmFsIGNvbmZpZ3VyYXRpb24gb3B0aW9ucy5cbiAqIEBwYXJhbSB7T2JqZWN0fSBuZXdPcHRpb25zIC0gTmV3IGNvbmZpZ3VyYXRpb24gb3B0aW9ucyB0byBiZSBtZXJnZWQuXG4gKiBAcGFyYW0ge0FycmF5fSBhYnNvbHV0ZVByb3BzIC0gTGlzdCBvZiBwcm9wZXJ0aWVzIHRoYXQgc2hvdWxkXG4gKiBub3QgYmUgcmVjdXJzaXZlbHkgbWVyZ2VkLlxuICpcbiAqIEByZXR1cm5zIHtPYmplY3R9IE1lcmdlZCBjb25maWd1cmF0aW9uIG9wdGlvbnMuXG4gKi9cbmV4cG9ydCBjb25zdCBtZXJnZUNvbmZpZ09wdGlvbnMgPSAob3B0aW9ucywgbmV3T3B0aW9ucywgYWJzb2x1dGVQcm9wcyA9IFtdKSA9PiB7XG4gIGNvbnN0IG1lcmdlZE9wdGlvbnMgPSBkZWVwQ29weShvcHRpb25zKTtcblxuICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhuZXdPcHRpb25zKSkge1xuICAgIG1lcmdlZE9wdGlvbnNba2V5XSA9XG4gICAgICBpc09iamVjdCh2YWx1ZSkgJiZcbiAgICAgICFhYnNvbHV0ZVByb3BzLmluY2x1ZGVzKGtleSkgJiZcbiAgICAgIG1lcmdlZE9wdGlvbnNba2V5XSAhPT0gdW5kZWZpbmVkXG4gICAgICAgID8gbWVyZ2VDb25maWdPcHRpb25zKG1lcmdlZE9wdGlvbnNba2V5XSwgdmFsdWUsIGFic29sdXRlUHJvcHMpXG4gICAgICAgIDogdmFsdWUgIT09IHVuZGVmaW5lZFxuICAgICAgICAgID8gdmFsdWVcbiAgICAgICAgICA6IG1lcmdlZE9wdGlvbnNba2V5XTtcbiAgfVxuXG4gIHJldHVybiBtZXJnZWRPcHRpb25zO1xufTtcblxuLyoqXG4gKiBJbml0aWFsaXplcyBleHBvcnQgc2V0dGluZ3MgYmFzZWQgb24gcHJvdmlkZWQgZXhwb3J0T3B0aW9uc1xuICogYW5kIGdlbmVyYWxPcHRpb25zLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBleHBvcnRPcHRpb25zIC0gT3B0aW9ucyBzcGVjaWZpYyB0byB0aGUgZXhwb3J0IHByb2Nlc3MuXG4gKiBAcGFyYW0ge09iamVjdH0gZ2VuZXJhbE9wdGlvbnMgLSBHZW5lcmFsIGNvbmZpZ3VyYXRpb24gb3B0aW9ucy5cbiAqXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBJbml0aWFsaXplZCBleHBvcnQgc2V0dGluZ3MuXG4gKi9cbmV4cG9ydCBjb25zdCBpbml0RXhwb3J0U2V0dGluZ3MgPSAoZXhwb3J0T3B0aW9ucywgZ2VuZXJhbE9wdGlvbnMgPSB7fSkgPT4ge1xuICBsZXQgb3B0aW9ucyA9IHt9O1xuXG4gIGlmIChleHBvcnRPcHRpb25zLnN2Zykge1xuICAgIG9wdGlvbnMgPSBkZWVwQ29weShnZW5lcmFsT3B0aW9ucyk7XG4gICAgb3B0aW9ucy5leHBvcnQudHlwZSA9IGV4cG9ydE9wdGlvbnMudHlwZSB8fCBleHBvcnRPcHRpb25zLmV4cG9ydC50eXBlO1xuICAgIG9wdGlvbnMuZXhwb3J0LnNjYWxlID0gZXhwb3J0T3B0aW9ucy5zY2FsZSB8fCBleHBvcnRPcHRpb25zLmV4cG9ydC5zY2FsZTtcbiAgICBvcHRpb25zLmV4cG9ydC5vdXRmaWxlID1cbiAgICAgIGV4cG9ydE9wdGlvbnMub3V0ZmlsZSB8fCBleHBvcnRPcHRpb25zLmV4cG9ydC5vdXRmaWxlO1xuICAgIG9wdGlvbnMucGF5bG9hZCA9IHtcbiAgICAgIHN2ZzogZXhwb3J0T3B0aW9ucy5zdmdcbiAgICB9O1xuICB9IGVsc2Uge1xuICAgIG9wdGlvbnMgPSBtZXJnZUNvbmZpZ09wdGlvbnMoXG4gICAgICBnZW5lcmFsT3B0aW9ucyxcbiAgICAgIGV4cG9ydE9wdGlvbnMsXG4gICAgICAvLyBPbWl0IGdvaW5nIGRvd24gcmVjdXJzaXZlbHkgd2l0aCB0aGUgYmVsb3dzXG4gICAgICBhYnNvbHV0ZVByb3BzXG4gICAgKTtcbiAgfVxuXG4gIG9wdGlvbnMuZXhwb3J0Lm91dGZpbGUgPVxuICAgIG9wdGlvbnMuZXhwb3J0Py5vdXRmaWxlIHx8IGBjaGFydC4ke29wdGlvbnMuZXhwb3J0Py50eXBlIHx8ICdwbmcnfWA7XG4gIHJldHVybiBvcHRpb25zO1xufTtcblxuLyoqXG4gKiBMb2FkcyBhZGRpdGlvbmFsIGNvbmZpZ3VyYXRpb24gZnJvbSBhIHNwZWNpZmllZCBmaWxlIHVzaW5nXG4gKiB0aGUgLS1sb2FkQ29uZmlnIG9wdGlvbi5cbiAqXG4gKiBAcGFyYW0ge0FycmF5fSBhcmdzIC0gQ29tbWFuZC1saW5lIGFyZ3VtZW50cyB0byBjaGVjayBmb3JcbiAqIHRoZSAtLWxvYWRDb25maWcgb3B0aW9uLlxuICpcbiAqIEByZXR1cm5zIHtPYmplY3R9IEFkZGl0aW9uYWwgY29uZmlndXJhdGlvbiBsb2FkZWQgZnJvbSB0aGUgc3BlY2lmaWVkIGZpbGUsXG4gKiBvciBhbiBlbXB0eSBvYmplY3QgaWYgbm90IGZvdW5kIG9yIGludmFsaWQuXG4gKi9cbmZ1bmN0aW9uIGxvYWRDb25maWdGaWxlKGFyZ3MpIHtcbiAgLy8gQ2hlY2sgaWYgdGhlIC0tbG9hZENvbmZpZyBvcHRpb24gd2FzIHVzZWRcbiAgY29uc3QgY29uZmlnSW5kZXggPSBhcmdzLmZpbmRJbmRleChcbiAgICAoYXJnKSA9PiBhcmcucmVwbGFjZSgvLS9nLCAnJykgPT09ICdsb2FkQ29uZmlnJ1xuICApO1xuXG4gIC8vIENoZWNrIGlmIHRoZSAtLWxvYWRDb25maWcgaGFzIGEgdmFsdWVcbiAgaWYgKGNvbmZpZ0luZGV4ID4gLTEgJiYgYXJnc1tjb25maWdJbmRleCArIDFdKSB7XG4gICAgY29uc3QgZmlsZU5hbWUgPSBhcmdzW2NvbmZpZ0luZGV4ICsgMV07XG4gICAgdHJ5IHtcbiAgICAgIC8vIENoZWNrIGlmIGFuIGFkZGl0aW9uYWwgY29uZmlnIGZpbGUgaXMgYSBjb3JyZWN0IEpTT04gZmlsZVxuICAgICAgaWYgKGZpbGVOYW1lICYmIGZpbGVOYW1lLmVuZHNXaXRoKCcuanNvbicpKSB7XG4gICAgICAgIC8vIExvYWQgYW4gb3B0aW9uYWwgY3VzdG9tIEpTT04gY29uZmlnIGZpbGVcbiAgICAgICAgcmV0dXJuIEpTT04ucGFyc2UocmVhZEZpbGVTeW5jKGZpbGVOYW1lKSk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ1dpdGhTdGFjayhcbiAgICAgICAgMixcbiAgICAgICAgZXJyb3IsXG4gICAgICAgIGBbY29uZmlnXSBVbmFibGUgdG8gbG9hZCB0aGUgY29uZmlndXJhdGlvbiBmcm9tIHRoZSAke2ZpbGVOYW1lfSBmaWxlLmBcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLy8gTm8gYWRkaXRpb25hbCBvcHRpb25zIHRvIHJldHVyblxuICByZXR1cm4ge307XG59XG5cbi8qKlxuICogVXBkYXRlcyB0aGUgZGVmYXVsdCBjb25maWd1cmF0aW9uIG9iamVjdCB3aXRoIHZhbHVlcyBmcm9tIGEgY3VzdG9tIG9iamVjdFxuICogYW5kIGVudmlyb25tZW50IHZhcmlhYmxlcy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gY29uZmlnT2JqIC0gVGhlIGRlZmF1bHQgY29uZmlndXJhdGlvbiBvYmplY3QuXG4gKiBAcGFyYW0ge09iamVjdH0gY3VzdG9tT2JqIC0gQ3VzdG9tIGNvbmZpZ3VyYXRpb24gb2JqZWN0IHRvIG92ZXJyaWRlIGRlZmF1bHRzLlxuICogQHBhcmFtIHtzdHJpbmd9IHByb3BDaGFpbiAtIFByb3BlcnR5IGNoYWluIGZvciB0cmFja2luZyBuZXN0ZWQgcHJvcGVydGllc1xuICogZHVyaW5nIHJlY3Vyc2lvbi5cbiAqL1xuZnVuY3Rpb24gdXBkYXRlRGVmYXVsdENvbmZpZyhjb25maWdPYmosIGN1c3RvbU9iaiA9IHt9LCBwcm9wQ2hhaW4gPSAnJykge1xuICBPYmplY3Qua2V5cyhjb25maWdPYmopLmZvckVhY2goKGtleSkgPT4ge1xuICAgIGNvbnN0IGVudHJ5ID0gY29uZmlnT2JqW2tleV07XG4gICAgY29uc3QgY3VzdG9tVmFsdWUgPSBjdXN0b21PYmogJiYgY3VzdG9tT2JqW2tleV07XG5cbiAgICBpZiAodHlwZW9mIGVudHJ5LnZhbHVlID09PSAndW5kZWZpbmVkJykge1xuICAgICAgdXBkYXRlRGVmYXVsdENvbmZpZyhlbnRyeSwgY3VzdG9tVmFsdWUsIGAke3Byb3BDaGFpbn0uJHtrZXl9YCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIElmIGEgdmFsdWUgZnJvbSBhIGN1c3RvbSBKU09OIGV4aXN0cywgaXQgdGFrZSBwcmVjZWRlbmNlXG4gICAgICBpZiAoY3VzdG9tVmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBlbnRyeS52YWx1ZSA9IGN1c3RvbVZhbHVlO1xuICAgICAgfVxuXG4gICAgICAvLyBJZiBhIHZhbHVlIGZyb20gYW4gZW52IHZhcmlhYmxlIGV4aXN0cywgaXQgdGFrZSBwcmVjZWRlbmNlXG4gICAgICBpZiAoZW50cnkuZW52TGluayBpbiBlbnZzICYmIGVudnNbZW50cnkuZW52TGlua10gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBlbnRyeS52YWx1ZSA9IGVudnNbZW50cnkuZW52TGlua107XG4gICAgICB9XG4gICAgfVxuICB9KTtcbn1cblxuLyoqXG4gKiBJbml0aWFsaXplcyBvcHRpb25zIG9iamVjdCBiYXNlZCBvbiBwcm92aWRlZCBpdGVtcywgc2V0dGluZyB2YWx1ZXMgZnJvbVxuICogbmVzdGVkIHByb3BlcnRpZXMgcmVjdXJzaXZlbHkuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGl0ZW1zIC0gQ29uZmlndXJhdGlvbiBpdGVtcyB0byBiZSB1c2VkIGZvciBpbml0aWFsaXppbmdcbiAqIG9wdGlvbnMuXG4gKlxuICogQHJldHVybnMge09iamVjdH0gSW5pdGlhbGl6ZWQgb3B0aW9ucyBvYmplY3QuXG4gKi9cbmZ1bmN0aW9uIGluaXRPcHRpb25zKGl0ZW1zKSB7XG4gIGxldCBvcHRpb25zID0ge307XG4gIGZvciAoY29uc3QgW25hbWUsIGl0ZW1dIG9mIE9iamVjdC5lbnRyaWVzKGl0ZW1zKSkge1xuICAgIG9wdGlvbnNbbmFtZV0gPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoaXRlbSwgJ3ZhbHVlJylcbiAgICAgID8gaXRlbS52YWx1ZVxuICAgICAgOiBpbml0T3B0aW9ucyhpdGVtKTtcbiAgfVxuICByZXR1cm4gb3B0aW9ucztcbn1cblxuLyoqXG4gKiBQYWlycyBhcmd1bWVudCB2YWx1ZXMgd2l0aCBjb3JyZXNwb25kaW5nIG9wdGlvbnMgaW4gdGhlIGNvbmZpZ3VyYXRpb24sXG4gKiB1cGRhdGluZyB0aGUgb3B0aW9ucyBvYmplY3QuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgLSBDb25maWd1cmF0aW9uIG9wdGlvbnMgb2JqZWN0IHRvIGJlIHVwZGF0ZWQuXG4gKiBAcGFyYW0ge0FycmF5fSBhcmdzIC0gQ29tbWFuZC1saW5lIGFyZ3VtZW50cyBjb250YWluaW5nIHZhbHVlcyBmb3Igc3BlY2lmaWNcbiAqIG9wdGlvbnMuXG4gKiBAcGFyYW0ge09iamVjdH0gZGVmYXVsdENvbmZpZyAtIERlZmF1bHQgY29uZmlndXJhdGlvbiBvYmplY3QgZm9yIHJlZmVyZW5jZS5cbiAqXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBVcGRhdGVkIG9wdGlvbnMgb2JqZWN0LlxuICovXG5mdW5jdGlvbiBwYWlyQXJndW1lbnRWYWx1ZShvcHRpb25zLCBhcmdzLCBkZWZhdWx0Q29uZmlnKSB7XG4gIGxldCBzaG93VXNhZ2UgPSBmYWxzZTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBhcmdzLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3Qgb3B0aW9uID0gYXJnc1tpXS5yZXBsYWNlKC8tL2csICcnKTtcblxuICAgIC8vIEZpbmQgdGhlIHJpZ2h0IHBsYWNlIGZvciBwcm9wZXJ0eSdzIHZhbHVlXG4gICAgY29uc3QgcHJvcGVydGllc0NoYWluID0gbmVzdGVkQXJnc1tvcHRpb25dXG4gICAgICA/IG5lc3RlZEFyZ3Nbb3B0aW9uXS5zcGxpdCgnLicpXG4gICAgICA6IFtdO1xuXG4gICAgLy8gR2V0IHRoZSBjb3JyZWN0IHR5cGUgZm9yIENMSSBhcmdzIHdoaWNoIGFyZSBwYXNzZWQgYXMgc3RyaW5nc1xuICAgIGxldCBhcmd1bWVudFR5cGU7XG4gICAgcHJvcGVydGllc0NoYWluLnJlZHVjZSgob2JqLCBwcm9wLCBpbmRleCkgPT4ge1xuICAgICAgaWYgKHByb3BlcnRpZXNDaGFpbi5sZW5ndGggLSAxID09PSBpbmRleCkge1xuICAgICAgICBhcmd1bWVudFR5cGUgPSBvYmpbcHJvcF0udHlwZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBvYmpbcHJvcF07XG4gICAgfSwgZGVmYXVsdENvbmZpZyk7XG5cbiAgICBwcm9wZXJ0aWVzQ2hhaW4ucmVkdWNlKChvYmosIHByb3AsIGluZGV4KSA9PiB7XG4gICAgICBpZiAocHJvcGVydGllc0NoYWluLmxlbmd0aCAtIDEgPT09IGluZGV4KSB7XG4gICAgICAgIC8vIEZpbmRzIGFuIG9wdGlvbiBhbmQgc2V0IGEgY29ycmVzcG9uZGluZyB2YWx1ZVxuICAgICAgICBpZiAodHlwZW9mIG9ialtwcm9wXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICBpZiAoYXJnc1srK2ldKSB7XG4gICAgICAgICAgICBpZiAoYXJndW1lbnRUeXBlID09PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICAgICAgb2JqW3Byb3BdID0gdG9Cb29sZWFuKGFyZ3NbaV0pO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChhcmd1bWVudFR5cGUgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICAgIG9ialtwcm9wXSA9ICthcmdzW2ldO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChhcmd1bWVudFR5cGUuaW5kZXhPZignXScpID49IDApIHtcbiAgICAgICAgICAgICAgb2JqW3Byb3BdID0gYXJnc1tpXS5zcGxpdCgnLCcpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgb2JqW3Byb3BdID0gYXJnc1tpXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbG9nKFxuICAgICAgICAgICAgICAyLFxuICAgICAgICAgICAgICBgW2NvbmZpZ10gTWlzc2luZyB2YWx1ZSBmb3IgdGhlICcke29wdGlvbn0nIGFyZ3VtZW50LiBVc2luZyB0aGUgZGVmYXVsdCB2YWx1ZS5gXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgc2hvd1VzYWdlID0gdHJ1ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBvYmpbcHJvcF07XG4gICAgfSwgb3B0aW9ucyk7XG4gIH1cblxuICAvLyBEaXNwbGF5IHRoZSB1c2FnZSBmb3IgdGhlIHJlZmVyZW5jZSBpZiBuZWVkZWRcbiAgaWYgKHNob3dVc2FnZSkge1xuICAgIHByaW50VXNhZ2UoZGVmYXVsdENvbmZpZyk7XG4gIH1cblxuICByZXR1cm4gb3B0aW9ucztcbn1cblxuLyoqXG4gKiBSZWN1cnNpdmVseSB1cGRhdGVzIHByb3BlcnRpZXMgaW4gYW4gb2JqZWN0IGJhc2VkIG9uIG5lc3RlZCBuYW1lcyBhbmQgYXNzaWduc1xuICogdGhlIGZpbmFsIHZhbHVlLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RUb1VwZGF0ZSAtIFRoZSBvYmplY3QgdG8gYmUgdXBkYXRlZC5cbiAqIEBwYXJhbSB7QXJyYXl9IG5lc3RlZE5hbWVzIC0gQXJyYXkgb2YgbmVzdGVkIHByb3BlcnR5IG5hbWVzLlxuICogQHBhcmFtIHthbnl9IHZhbHVlIC0gVGhlIGZpbmFsIHZhbHVlIHRvIGJlIGFzc2lnbmVkLlxuICpcbiAqIEByZXR1cm5zIHtPYmplY3R9IFVwZGF0ZWQgb2JqZWN0IHdpdGggYXNzaWduZWQgdmFsdWVzLlxuICovXG5mdW5jdGlvbiByZWN1cnNpdmVQcm9wcyhvYmplY3RUb1VwZGF0ZSwgbmVzdGVkTmFtZXMsIHZhbHVlKSB7XG4gIHdoaWxlIChuZXN0ZWROYW1lcy5sZW5ndGggPiAxKSB7XG4gICAgY29uc3QgcHJvcE5hbWUgPSBuZXN0ZWROYW1lcy5zaGlmdCgpO1xuXG4gICAgLy8gQ3JlYXRlIGEgcHJvcGVydHkgaW4gb2JqZWN0IGlmIGl0IGRvZXNuJ3QgZXhpc3RcbiAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3RUb1VwZGF0ZSwgcHJvcE5hbWUpKSB7XG4gICAgICBvYmplY3RUb1VwZGF0ZVtwcm9wTmFtZV0gPSB7fTtcbiAgICB9XG5cbiAgICAvLyBDYWxsIGZ1bmN0aW9uIGFnYWluIGlmIHRoZXJlIHN0aWxsIG5hbWVzIHRvIGdvXG4gICAgb2JqZWN0VG9VcGRhdGVbcHJvcE5hbWVdID0gcmVjdXJzaXZlUHJvcHMoXG4gICAgICBPYmplY3QuYXNzaWduKHt9LCBvYmplY3RUb1VwZGF0ZVtwcm9wTmFtZV0pLFxuICAgICAgbmVzdGVkTmFtZXMsXG4gICAgICB2YWx1ZVxuICAgICk7XG5cbiAgICByZXR1cm4gb2JqZWN0VG9VcGRhdGU7XG4gIH1cblxuICAvLyBBc3NpZ24gdGhlIGZpbmFsIHZhbHVlXG4gIG9iamVjdFRvVXBkYXRlW25lc3RlZE5hbWVzWzBdXSA9IHZhbHVlO1xuICByZXR1cm4gb2JqZWN0VG9VcGRhdGU7XG59XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgZ2V0T3B0aW9ucyxcbiAgc2V0T3B0aW9ucyxcbiAgbWFudWFsQ29uZmlnLFxuICBtYXBUb05ld0NvbmZpZyxcbiAgbWVyZ2VDb25maWdPcHRpb25zLFxuICBpbml0RXhwb3J0U2V0dGluZ3Ncbn07XG4iLCIvKipcbiAqIFRoaXMgbW9kdWxlIGV4cG9ydHMgdHdvIGZ1bmN0aW9uczogZmV0Y2ggKGZvciBHRVQgcmVxdWVzdHMpIGFuZCBwb3N0IChmb3IgUE9TVCByZXF1ZXN0cykuXG4gKi9cblxuaW1wb3J0IGh0dHAgZnJvbSAnaHR0cCc7XG5pbXBvcnQgaHR0cHMgZnJvbSAnaHR0cHMnO1xuXG4vKipcbiAqIFJldHVybnMgdGhlIEhUVFAgb3IgSFRUUFMgcHJvdG9jb2wgbW9kdWxlIGJhc2VkIG9uIHRoZSBwcm92aWRlZCBVUkwuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHVybCAtIFRoZSBVUkwgdG8gZGV0ZXJtaW5lIHRoZSBwcm90b2NvbC5cbiAqXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBUaGUgSFRUUCBvciBIVFRQUyBwcm90b2NvbCBtb2R1bGUgKGh0dHAgb3IgaHR0cHMpLlxuICovXG5jb25zdCBnZXRQcm90b2NvbCA9ICh1cmwpID0+ICh1cmwuc3RhcnRzV2l0aCgnaHR0cHMnKSA/IGh0dHBzIDogaHR0cCk7XG5cbi8qKlxuICogRmV0Y2hlcyBkYXRhIGZyb20gdGhlIHNwZWNpZmllZCBVUkwgdXNpbmcgZWl0aGVyIEhUVFAgb3IgSFRUUFMgcHJvdG9jb2wuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHVybCAtIFRoZSBVUkwgdG8gZmV0Y2ggZGF0YSBmcm9tLlxuICogQHBhcmFtIHtPYmplY3R9IHJlcXVlc3RPcHRpb25zIC0gT3B0aW9ucyBmb3IgdGhlIEhUVFAgcmVxdWVzdCAob3B0aW9uYWwpLlxuICpcbiAqIEByZXR1cm5zIHtQcm9taXNlPE9iamVjdD59IFByb21pc2UgcmVzb2x2aW5nIHRvIHRoZSBIVFRQIHJlc3BvbnNlIG9iamVjdFxuICogd2l0aCBhZGRlZCAndGV4dCcgcHJvcGVydHkgb3IgcmVqZWN0aW5nIHdpdGggYW4gZXJyb3IuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGZldGNoKHVybCwgcmVxdWVzdE9wdGlvbnMgPSB7fSkge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGNvbnN0IHByb3RvY29sID0gZ2V0UHJvdG9jb2wodXJsKTtcblxuICAgIHByb3RvY29sXG4gICAgICAuZ2V0KFxuICAgICAgICB1cmwsXG4gICAgICAgIE9iamVjdC5hc3NpZ24oXG4gICAgICAgICAge1xuICAgICAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICAgICAnVXNlci1BZ2VudCc6ICdoaWdoY2hhcnRzL2V4cG9ydCcsXG4gICAgICAgICAgICAgIFJlZmVyZXI6ICdoaWdoY2hhcnRzLmV4cG9ydCdcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LFxuICAgICAgICAgIHJlcXVlc3RPcHRpb25zIHx8IHt9XG4gICAgICAgICksXG4gICAgICAgIChyZXMpID0+IHtcbiAgICAgICAgICBsZXQgZGF0YSA9ICcnO1xuXG4gICAgICAgICAgLy8gQSBjaHVuayBvZiBkYXRhIGhhcyBiZWVuIHJlY2VpdmVkLlxuICAgICAgICAgIHJlcy5vbignZGF0YScsIChjaHVuaykgPT4ge1xuICAgICAgICAgICAgZGF0YSArPSBjaHVuaztcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIC8vIFRoZSB3aG9sZSByZXNwb25zZSBoYXMgYmVlbiByZWNlaXZlZC5cbiAgICAgICAgICByZXMub24oJ2VuZCcsICgpID0+IHtcbiAgICAgICAgICAgIGlmICghZGF0YSkge1xuICAgICAgICAgICAgICByZWplY3QoJ05vdGhpbmcgd2FzIGZldGNoZWQgZnJvbSB0aGUgVVJMLicpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXMudGV4dCA9IGRhdGE7XG4gICAgICAgICAgICByZXNvbHZlKHJlcyk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIClcbiAgICAgIC5vbignZXJyb3InLCAoZXJyb3IpID0+IHtcbiAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgIH0pO1xuICB9KTtcbn1cblxuLyoqXG4gKiBTZW5kcyBhIFBPU1QgcmVxdWVzdCB0byB0aGUgc3BlY2lmaWVkIFVSTCB3aXRoIHRoZSBwcm92aWRlZCBKU09OIGJvZHkgdXNpbmdcbiAqIGVpdGhlciBIVFRQIG9yIEhUVFBTIHByb3RvY29sLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB1cmwgLSBUaGUgVVJMIHRvIHNlbmQgdGhlIFBPU1QgcmVxdWVzdCB0by5cbiAqIEBwYXJhbSB7T2JqZWN0fSBib2R5IC0gVGhlIEpTT04gYm9keSB0byBpbmNsdWRlIGluIHRoZSBQT1NUIHJlcXVlc3RcbiAqIChvcHRpb25hbCwgZGVmYXVsdCBpcyBhbiBlbXB0eSBvYmplY3QpLlxuICogQHBhcmFtIHtPYmplY3R9IHJlcXVlc3RPcHRpb25zIC0gT3B0aW9ucyBmb3IgdGhlIEhUVFAgcmVxdWVzdCAob3B0aW9uYWwpLlxuICpcbiAqIEByZXR1cm5zIHtQcm9taXNlPE9iamVjdD59IFByb21pc2UgcmVzb2x2aW5nIHRvIHRoZSBIVFRQIHJlc3BvbnNlIG9iamVjdCB3aXRoXG4gKiBhZGRlZCAndGV4dCcgcHJvcGVydHkgb3IgcmVqZWN0aW5nIHdpdGggYW4gZXJyb3IuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHBvc3QodXJsLCBib2R5ID0ge30sIHJlcXVlc3RPcHRpb25zID0ge30pIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjb25zdCBwcm90b2NvbCA9IGdldFByb3RvY29sKHVybCk7XG4gICAgY29uc3QgZGF0YSA9IEpTT04uc3RyaW5naWZ5KGJvZHkpO1xuXG4gICAgLy8gU2V0IGRlZmF1bHQgaGVhZGVycyBhbmQgbWVyZ2Ugd2l0aCByZXF1ZXN0T3B0aW9uc1xuICAgIGNvbnN0IG9wdGlvbnMgPSBPYmplY3QuYXNzaWduKFxuICAgICAge1xuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICAgICAgJ0NvbnRlbnQtTGVuZ3RoJzogZGF0YS5sZW5ndGhcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIHJlcXVlc3RPcHRpb25zXG4gICAgKTtcblxuICAgIGNvbnN0IHJlcSA9IHByb3RvY29sXG4gICAgICAucmVxdWVzdCh1cmwsIG9wdGlvbnMsIChyZXMpID0+IHtcbiAgICAgICAgbGV0IHJlc3BvbnNlRGF0YSA9ICcnO1xuXG4gICAgICAgIC8vIEEgY2h1bmsgb2YgZGF0YSBoYXMgYmVlbiByZWNlaXZlZC5cbiAgICAgICAgcmVzLm9uKCdkYXRhJywgKGNodW5rKSA9PiB7XG4gICAgICAgICAgcmVzcG9uc2VEYXRhICs9IGNodW5rO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBUaGUgd2hvbGUgcmVzcG9uc2UgaGFzIGJlZW4gcmVjZWl2ZWQuXG4gICAgICAgIHJlcy5vbignZW5kJywgKCkgPT4ge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXMudGV4dCA9IHJlc3BvbnNlRGF0YTtcbiAgICAgICAgICAgIHJlc29sdmUocmVzKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSlcbiAgICAgIC5vbignZXJyb3InLCAoZXJyb3IpID0+IHtcbiAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgIH0pO1xuXG4gICAgLy8gV3JpdGUgdGhlIHJlcXVlc3QgYm9keSBhbmQgZW5kIHRoZSByZXF1ZXN0LlxuICAgIHJlcS53cml0ZShkYXRhKTtcbiAgICByZXEuZW5kKCk7XG4gIH0pO1xufVxuXG5leHBvcnQgZGVmYXVsdCBmZXRjaDtcbmV4cG9ydCB7IGZldGNoLCBwb3N0IH07XG4iLCJjbGFzcyBFeHBvcnRFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgY29uc3RydWN0b3IobWVzc2FnZSkge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy5tZXNzYWdlID0gbWVzc2FnZTtcbiAgICB0aGlzLnN0YWNrTWVzc2FnZSA9IG1lc3NhZ2U7XG4gIH1cblxuICBzZXRFcnJvcihlcnJvcikge1xuICAgIHRoaXMuZXJyb3IgPSBlcnJvcjtcbiAgICBpZiAoZXJyb3IubmFtZSkge1xuICAgICAgdGhpcy5uYW1lID0gZXJyb3IubmFtZTtcbiAgICB9XG4gICAgaWYgKGVycm9yLnN0YXR1c0NvZGUpIHtcbiAgICAgIHRoaXMuc3RhdHVzQ29kZSA9IGVycm9yLnN0YXR1c0NvZGU7XG4gICAgfVxuICAgIGlmIChlcnJvci5zdGFjaykge1xuICAgICAgdGhpcy5zdGFja01lc3NhZ2UgPSBlcnJvci5tZXNzYWdlO1xuICAgICAgdGhpcy5zdGFjayA9IGVycm9yLnN0YWNrO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBFeHBvcnRFcnJvcjtcbiIsIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG5cbkhpZ2hjaGFydHMgRXhwb3J0IFNlcnZlclxuXG5Db3B5cmlnaHQgKGMpIDIwMTYtMjAyNCwgSGlnaHNvZnRcblxuTGljZW5jZWQgdW5kZXIgdGhlIE1JVCBsaWNlbmNlLlxuXG5BZGRpdGlvbmFsbHkgYSB2YWxpZCBIaWdoY2hhcnRzIGxpY2Vuc2UgaXMgcmVxdWlyZWQgZm9yIHVzZS5cblxuU2VlIExJQ0VOU0UgZmlsZSBpbiByb290IGZvciBkZXRhaWxzLlxuXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG4vLyBUaGUgY2FjaGUgbWFuYWdlciBtYW5hZ2VzIHRoZSBIaWdoY2hhcnRzIGxpYnJhcnkgYW5kIGl0cyBkZXBlbmRlbmNpZXMuXG4vLyBUaGUgY2FjaGUgaXRzZWxmIGlzIHN0b3JlZCBpbiAuY2FjaGUsIGFuZCBpcyBjaGVja2VkIGJ5IHRoZSBjb25maWcgc3lzdGVtXG4vLyBiZWZvcmUgc3RhcnRpbmcgdGhlIHNlcnZpY2VcblxuaW1wb3J0IHsgZXhpc3RzU3luYywgbWtkaXJTeW5jLCByZWFkRmlsZVN5bmMsIHdyaXRlRmlsZVN5bmMgfSBmcm9tICdmcyc7XG5pbXBvcnQgeyBqb2luIH0gZnJvbSAncGF0aCc7XG5cbmltcG9ydCB7IEh0dHBzUHJveHlBZ2VudCB9IGZyb20gJ2h0dHBzLXByb3h5LWFnZW50JztcblxuaW1wb3J0IHsgZ2V0T3B0aW9ucyB9IGZyb20gJy4vY29uZmlnLmpzJztcbmltcG9ydCB7IGVudnMgfSBmcm9tICcuL2VudnMuanMnO1xuaW1wb3J0IHsgZmV0Y2ggfSBmcm9tICcuL2ZldGNoLmpzJztcbmltcG9ydCB7IGxvZyB9IGZyb20gJy4vbG9nZ2VyLmpzJztcbmltcG9ydCB7IF9fZGlybmFtZSB9IGZyb20gJy4vdXRpbHMuanMnO1xuXG5pbXBvcnQgRXhwb3J0RXJyb3IgZnJvbSAnLi9lcnJvcnMvRXhwb3J0RXJyb3IuanMnO1xuXG5jb25zdCBjYWNoZSA9IHtcbiAgY2RuVVJMOiAnaHR0cHM6Ly9jb2RlLmhpZ2hjaGFydHMuY29tLycsXG4gIGFjdGl2ZU1hbmlmZXN0OiB7fSxcbiAgc291cmNlczogJycsXG4gIGhjVmVyc2lvbjogJydcbn07XG5cbi8qKlxuICogRXh0cmFjdHMgYW5kIGNhY2hlcyB0aGUgSGlnaGNoYXJ0cyB2ZXJzaW9uIGZyb20gdGhlIHNvdXJjZXMgc3RyaW5nLlxuICpcbiAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBleHRyYWN0ZWQgSGlnaGNoYXJ0cyB2ZXJzaW9uLlxuICovXG5leHBvcnQgY29uc3QgZXh0cmFjdFZlcnNpb24gPSAoY2FjaGUpID0+IHtcbiAgcmV0dXJuIGNhY2hlLnNvdXJjZXNcbiAgICAuc3Vic3RyaW5nKDAsIGNhY2hlLnNvdXJjZXMuaW5kZXhPZignKi8nKSlcbiAgICAucmVwbGFjZSgnLyonLCAnJylcbiAgICAucmVwbGFjZSgnKi8nLCAnJylcbiAgICAucmVwbGFjZSgvXFxuL2csICcnKVxuICAgIC50cmltKCk7XG59O1xuXG4vKipcbiAqIEV4dHJhY3RzIHRoZSBIaWdoY2hhcnRzIG1vZHVsZSBuYW1lIGJhc2VkIG9uIHRoZSBzY3JpcHRQYXRoLlxuICovXG5leHBvcnQgY29uc3QgZXh0cmFjdE1vZHVsZU5hbWUgPSAoc2NyaXB0UGF0aCkgPT4ge1xuICByZXR1cm4gc2NyaXB0UGF0aC5yZXBsYWNlKFxuICAgIC8oLiopXFwvfCguKiltb2R1bGVzXFwvfHN0b2NrXFwvKC4qKWluZGljYXRvcnNcXC98bWFwc1xcLyguKiltb2R1bGVzXFwvL2dpLFxuICAgICcnXG4gICk7XG59O1xuXG4vKipcbiAqIFNhdmVzIHRoZSBwcm92aWRlZCBjb25maWd1cmF0aW9uIGFuZCBmZXRjaGVkIG1vZHVsZXMgdG8gdGhlIGNhY2hlIG1hbmlmZXN0XG4gKiBmaWxlLlxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBjb25maWcgLSBIaWdoY2hhcnRzLXJlbGF0ZWQgY29uZmlndXJhdGlvbiBvYmplY3QuXG4gKiBAcGFyYW0ge29iamVjdH0gZmV0Y2hlZE1vZHVsZXMgLSBBbiBvYmplY3QgdGhhdCBjb250YWlucyBtYXBwZWQgbmFtZXMgb2ZcbiAqIGZldGNoZWQgSGlnaGNoYXJ0cyBtb2R1bGVzIHRvIHVzZS5cbiAqXG4gKiBAdGhyb3dzIHtFeHBvcnRFcnJvcn0gVGhyb3dzIGFuIEV4cG9ydEVycm9yIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSB3cml0aW5nXG4gKiB0aGUgY2FjaGUgbWFuaWZlc3QuXG4gKi9cbmV4cG9ydCBjb25zdCBzYXZlQ29uZmlnVG9NYW5pZmVzdCA9IGFzeW5jIChjb25maWcsIGZldGNoZWRNb2R1bGVzKSA9PiB7XG4gIGNvbnN0IG5ld01hbmlmZXN0ID0ge1xuICAgIHZlcnNpb246IGNvbmZpZy52ZXJzaW9uLFxuICAgIG1vZHVsZXM6IGZldGNoZWRNb2R1bGVzIHx8IHt9XG4gIH07XG5cbiAgLy8gVXBkYXRlIGNhY2hlIG9iamVjdCB3aXRoIHRoZSBjdXJyZW50IG1vZHVsZXNcbiAgY2FjaGUuYWN0aXZlTWFuaWZlc3QgPSBuZXdNYW5pZmVzdDtcblxuICBsb2coMywgJ1tjYWNoZV0gV3JpdGluZyBhIG5ldyBtYW5pZmVzdC4nKTtcbiAgdHJ5IHtcbiAgICB3cml0ZUZpbGVTeW5jKFxuICAgICAgam9pbihfX2Rpcm5hbWUsIGNvbmZpZy5jYWNoZVBhdGgsICdtYW5pZmVzdC5qc29uJyksXG4gICAgICBKU09OLnN0cmluZ2lmeShuZXdNYW5pZmVzdCksXG4gICAgICAndXRmOCdcbiAgICApO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHRocm93IG5ldyBFeHBvcnRFcnJvcignW2NhY2hlXSBFcnJvciB3cml0aW5nIHRoZSBjYWNoZSBtYW5pZmVzdC4nKS5zZXRFcnJvcihcbiAgICAgIGVycm9yXG4gICAgKTtcbiAgfVxufTtcblxuLyoqXG4gKiBGZXRjaGVzIGEgc2luZ2xlIHNjcmlwdCBhbmQgdXBkYXRlcyB0aGUgZmV0Y2hlZE1vZHVsZXMgYWNjb3JkaW5nbHkuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHNjcmlwdCAtIEEgcGF0aCB0byBzY3JpcHQgdG8gZ2V0LlxuICogQHBhcmFtIHtPYmplY3R9IHJlcXVlc3RPcHRpb25zIC0gQWRkaXRpb25hbCBvcHRpb25zIGZvciB0aGUgcHJveHkgYWdlbnRcbiAqIHRvIHVzZSBmb3IgYSByZXF1ZXN0LlxuICogQHBhcmFtIHtPYmplY3R9IGZldGNoZWRNb2R1bGVzIC0gQW4gb2JqZWN0IHdoaWNoIHRyYWNrcyB3aGljaCBIaWdoY2hhcnRzXG4gKiBtb2R1bGVzIGhhdmUgYmVlbiBmZXRjaGVkLlxuICogQHBhcmFtIHtib29sZWFufSBzaG91bGRUaHJvd0Vycm9yIC0gQSBmbGFnIHRvIGluZGljYXRlIGlmIHRoZSBlcnJvciBzaG91bGQgYmVcbiAqIHRocm93bi4gVGhpcyBzaG91bGQgYmUgdXNlZCBvbmx5IGZvciB0aGUgY29yZSBzY3JpcHRzLlxuICpcbiAqIEByZXR1cm5zIHtQcm9taXNlPHN0cmluZz59IEEgUHJvbWlzZSByZXNvbHZpbmcgdG8gdGhlIHRleHQgcmVwcmVzZW50YXRpb25cbiAqIG9mIHRoZSBmZXRjaGVkIHNjcmlwdC5cbiAqXG4gKiBAdGhyb3dzIHtFeHBvcnRFcnJvcn0gVGhyb3dzIGFuIEV4cG9ydEVycm9yIGlmIHRoZXJlIGlzIGEgcHJvYmxlbSB3aXRoXG4gKiBmZXRjaGluZyB0aGUgc2NyaXB0LlxuICovXG5leHBvcnQgY29uc3QgZmV0Y2hBbmRQcm9jZXNzU2NyaXB0ID0gYXN5bmMgKFxuICBzY3JpcHQsXG4gIHJlcXVlc3RPcHRpb25zLFxuICBmZXRjaGVkTW9kdWxlcyxcbiAgc2hvdWxkVGhyb3dFcnJvciA9IGZhbHNlXG4pID0+IHtcbiAgLy8gR2V0IHJpZCBvZiB0aGUgLmpzIGZyb20gdGhlIGN1c3RvbSBzdHJpbmdzXG4gIGlmIChzY3JpcHQuZW5kc1dpdGgoJy5qcycpKSB7XG4gICAgc2NyaXB0ID0gc2NyaXB0LnN1YnN0cmluZygwLCBzY3JpcHQubGVuZ3RoIC0gMyk7XG4gIH1cblxuICBsb2coNCwgYFtjYWNoZV0gRmV0Y2hpbmcgc2NyaXB0IC0gJHtzY3JpcHR9LmpzYCk7XG5cbiAgLy8gRmV0Y2ggdGhlIHNjcmlwdFxuICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKGAke3NjcmlwdH0uanNgLCByZXF1ZXN0T3B0aW9ucyk7XG5cbiAgLy8gSWYgT0ssIHJldHVybiBpdHMgdGV4dCByZXByZXNlbnRhdGlvblxuICBpZiAocmVzcG9uc2Uuc3RhdHVzQ29kZSA9PT0gMjAwICYmIHR5cGVvZiByZXNwb25zZS50ZXh0ID09ICdzdHJpbmcnKSB7XG4gICAgaWYgKGZldGNoZWRNb2R1bGVzKSB7XG4gICAgICBjb25zdCBtb2R1bGVOYW1lID0gZXh0cmFjdE1vZHVsZU5hbWUoc2NyaXB0KTtcbiAgICAgIGZldGNoZWRNb2R1bGVzW21vZHVsZU5hbWVdID0gMTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzcG9uc2UudGV4dDtcbiAgfVxuXG4gIGlmIChzaG91bGRUaHJvd0Vycm9yKSB7XG4gICAgdGhyb3cgbmV3IEV4cG9ydEVycm9yKFxuICAgICAgYENvdWxkIG5vdCBmZXRjaCB0aGUgJHtzY3JpcHR9LmpzLiBUaGUgc2NyaXB0IG1pZ2h0IG5vdCBleGlzdCBpbiB0aGUgcmVxdWVzdGVkIHZlcnNpb24gKHN0YXR1cyBjb2RlOiAke3Jlc3BvbnNlLnN0YXR1c0NvZGV9KS5gXG4gICAgKS5zZXRFcnJvcihyZXNwb25zZSk7XG4gIH0gZWxzZSB7XG4gICAgbG9nKFxuICAgICAgMixcbiAgICAgIGBbY2FjaGVdIENvdWxkIG5vdCBmZXRjaCB0aGUgJHtzY3JpcHR9LmpzLiBUaGUgc2NyaXB0IG1pZ2h0IG5vdCBleGlzdCBpbiB0aGUgcmVxdWVzdGVkIHZlcnNpb24uYFxuICAgICk7XG4gIH1cblxuICByZXR1cm4gJyc7XG59O1xuXG4vKipcbiAqIEZldGNoZXMgSGlnaGNoYXJ0cyBzY3JpcHRzIGFuZCBjdXN0b21TY3JpcHRzIGZyb20gdGhlIGdpdmVuIENETnMuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGNvcmVTY3JpcHRzIC0gQXJyYXkgb2YgSGlnaGNoYXJ0cyBjb3JlIHNjcmlwdHMgdG8gZmV0Y2guXG4gKiBAcGFyYW0ge3N0cmluZ30gbW9kdWxlU2NyaXB0cyAtIEFycmF5IG9mIEhpZ2hjaGFydHMgbW9kdWxlcyB0byBmZXRjaC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBjdXN0b21TY3JpcHRzIC0gQXJyYXkgb2YgY3VzdG9tIHNjcmlwdCBwYXRocyB0byBmZXRjaFxuICogKGZ1bGwgVVJMcykuXG4gKiBAcGFyYW0ge29iamVjdH0gcHJveHlPcHRpb25zIC0gT3B0aW9ucyBmb3IgdGhlIHByb3h5IGFnZW50IHRvIHVzZSBmb3JcbiAqIGEgcmVxdWVzdC5cbiAqIEBwYXJhbSB7b2JqZWN0fSBmZXRjaGVkTW9kdWxlcyAtIEFuIG9iamVjdCB3aGljaCB0cmFja3Mgd2hpY2ggSGlnaGNoYXJ0c1xuICogbW9kdWxlcyBoYXZlIGJlZW4gZmV0Y2hlZC5cbiAqXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxzdHJpbmc+fSBUaGUgZmV0Y2hlZCBzY3JpcHRzIGNvbnRlbnQgam9pbmVkLlxuICovXG5leHBvcnQgY29uc3QgZmV0Y2hTY3JpcHRzID0gYXN5bmMgKFxuICBjb3JlU2NyaXB0cyxcbiAgbW9kdWxlU2NyaXB0cyxcbiAgY3VzdG9tU2NyaXB0cyxcbiAgcHJveHlPcHRpb25zLFxuICBmZXRjaGVkTW9kdWxlc1xuKSA9PiB7XG4gIC8vIENvbmZpZ3VyZSBwcm94eSBpZiBleGlzdHNcbiAgbGV0IHByb3h5QWdlbnQ7XG4gIGNvbnN0IHsgaG9zdCwgcG9ydCwgdXNlcm5hbWUsIHBhc3N3b3JkIH0gPSBwcm94eU9wdGlvbnM7XG5cbiAgLy8gVHJ5IHRvIGNyZWF0ZSBhIFByb3h5IEFnZW50XG4gIGlmIChob3N0ICYmIHBvcnQpIHtcbiAgICB0cnkge1xuICAgICAgcHJveHlBZ2VudCA9IG5ldyBIdHRwc1Byb3h5QWdlbnQoe1xuICAgICAgICBob3N0LFxuICAgICAgICBwb3J0LFxuICAgICAgICAuLi4odXNlcm5hbWUgJiYgcGFzc3dvcmQgPyB7IHVzZXJuYW1lLCBwYXNzd29yZCB9IDoge30pXG4gICAgICB9KTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhyb3cgbmV3IEV4cG9ydEVycm9yKCdbY2FjaGVdIENvdWxkIG5vdCBjcmVhdGUgYSBQcm94eSBBZ2VudC4nKS5zZXRFcnJvcihcbiAgICAgICAgZXJyb3JcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLy8gSWYgZXhpc3RzLCBhZGQgcHJveHkgYWdlbnQgdG8gcmVxdWVzdCBvcHRpb25zXG4gIGNvbnN0IHJlcXVlc3RPcHRpb25zID0gcHJveHlBZ2VudFxuICAgID8ge1xuICAgICAgICBhZ2VudDogcHJveHlBZ2VudCxcbiAgICAgICAgdGltZW91dDogZW52cy5TRVJWRVJfUFJPWFlfVElNRU9VVFxuICAgICAgfVxuICAgIDoge307XG5cbiAgY29uc3QgYWxsRmV0Y2hQcm9taXNlcyA9IFtcbiAgICAuLi5jb3JlU2NyaXB0cy5tYXAoKHNjcmlwdCkgPT5cbiAgICAgIGZldGNoQW5kUHJvY2Vzc1NjcmlwdChgJHtzY3JpcHR9YCwgcmVxdWVzdE9wdGlvbnMsIGZldGNoZWRNb2R1bGVzLCB0cnVlKVxuICAgICksXG4gICAgLi4ubW9kdWxlU2NyaXB0cy5tYXAoKHNjcmlwdCkgPT5cbiAgICAgIGZldGNoQW5kUHJvY2Vzc1NjcmlwdChgJHtzY3JpcHR9YCwgcmVxdWVzdE9wdGlvbnMsIGZldGNoZWRNb2R1bGVzKVxuICAgICksXG4gICAgLi4uY3VzdG9tU2NyaXB0cy5tYXAoKHNjcmlwdCkgPT5cbiAgICAgIGZldGNoQW5kUHJvY2Vzc1NjcmlwdChgJHtzY3JpcHR9YCwgcmVxdWVzdE9wdGlvbnMpXG4gICAgKVxuICBdO1xuXG4gIGNvbnN0IGZldGNoZWRTY3JpcHRzID0gYXdhaXQgUHJvbWlzZS5hbGwoYWxsRmV0Y2hQcm9taXNlcyk7XG4gIHJldHVybiBmZXRjaGVkU2NyaXB0cy5qb2luKCc7XFxuJyk7XG59O1xuXG4vKipcbiAqIFVwZGF0ZXMgdGhlIGxvY2FsIGNhY2hlIHdpdGggSGlnaGNoYXJ0cyBzY3JpcHRzIGFuZCB0aGVpciB2ZXJzaW9ucy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIE9iamVjdCBjb250YWluaW5nIGFsbCBvcHRpb25zLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZVBhdGggLSBUaGUgcGF0aCB0byB0aGUgc291cmNlIGZpbGUgaW4gdGhlIGNhY2hlLlxuICpcbiAqIEByZXR1cm5zIHtQcm9taXNlPG9iamVjdD59IEEgUHJvbWlzZSByZXNvbHZpbmcgdG8gYW4gb2JqZWN0IHJlcHJlc2VudGluZ1xuICogdGhlIGZldGNoZWQgbW9kdWxlcy5cbiAqXG4gKiBAdGhyb3dzIHtFeHBvcnRFcnJvcn0gVGhyb3dzIGFuIEV4cG9ydEVycm9yIGlmIHRoZXJlIGlzIGFuIGlzc3VlIHVwZGF0aW5nXG4gKiB0aGUgbG9jYWwgSGlnaGNoYXJ0cyBjYWNoZS5cbiAqL1xuZXhwb3J0IGNvbnN0IHVwZGF0ZUNhY2hlID0gYXN5bmMgKFxuICBoaWdoY2hhcnRzT3B0aW9ucyxcbiAgcHJveHlPcHRpb25zLFxuICBzb3VyY2VQYXRoXG4pID0+IHtcbiAgY29uc3QgdmVyc2lvbiA9IGhpZ2hjaGFydHNPcHRpb25zLnZlcnNpb247XG4gIGNvbnN0IGhjVmVyc2lvbiA9IHZlcnNpb24gPT09ICdsYXRlc3QnIHx8ICF2ZXJzaW9uID8gJycgOiBgJHt2ZXJzaW9ufS9gO1xuICBjb25zdCBjZG5VUkwgPSBoaWdoY2hhcnRzT3B0aW9ucy5jZG5VUkwgfHwgY2FjaGUuY2RuVVJMO1xuXG4gIGxvZyhcbiAgICAzLFxuICAgIGBbY2FjaGVdIFVwZGF0aW5nIGNhY2hlIHZlcnNpb24gdG8gSGlnaGNoYXJ0czogJHtoY1ZlcnNpb24gfHwgJ2xhdGVzdCd9LmBcbiAgKTtcblxuICBjb25zdCBmZXRjaGVkTW9kdWxlcyA9IHt9O1xuICB0cnkge1xuICAgIGNhY2hlLnNvdXJjZXMgPSBhd2FpdCBmZXRjaFNjcmlwdHMoXG4gICAgICBbXG4gICAgICAgIC4uLmhpZ2hjaGFydHNPcHRpb25zLmNvcmVTY3JpcHRzLm1hcCgoYykgPT4gYCR7Y2RuVVJMfSR7aGNWZXJzaW9ufSR7Y31gKVxuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgLi4uaGlnaGNoYXJ0c09wdGlvbnMubW9kdWxlU2NyaXB0cy5tYXAoKG0pID0+XG4gICAgICAgICAgbSA9PT0gJ21hcCdcbiAgICAgICAgICAgID8gYCR7Y2RuVVJMfW1hcHMvJHtoY1ZlcnNpb259bW9kdWxlcy8ke219YFxuICAgICAgICAgICAgOiBgJHtjZG5VUkx9JHtoY1ZlcnNpb259bW9kdWxlcy8ke219YFxuICAgICAgICApLFxuICAgICAgICAuLi5oaWdoY2hhcnRzT3B0aW9ucy5pbmRpY2F0b3JTY3JpcHRzLm1hcChcbiAgICAgICAgICAoaSkgPT4gYCR7Y2RuVVJMfXN0b2NrLyR7aGNWZXJzaW9ufWluZGljYXRvcnMvJHtpfWBcbiAgICAgICAgKVxuICAgICAgXSxcbiAgICAgIGhpZ2hjaGFydHNPcHRpb25zLmN1c3RvbVNjcmlwdHMsXG4gICAgICBwcm94eU9wdGlvbnMsXG4gICAgICBmZXRjaGVkTW9kdWxlc1xuICAgICk7XG5cbiAgICBjYWNoZS5oY1ZlcnNpb24gPSBleHRyYWN0VmVyc2lvbihjYWNoZSk7XG5cbiAgICAvLyBTYXZlIHRoZSBmZXRjaGVkIG1vZHVsZXMgaW50byBjYWNoZXMnIHNvdXJjZSBKU09OXG4gICAgd3JpdGVGaWxlU3luYyhzb3VyY2VQYXRoLCBjYWNoZS5zb3VyY2VzKTtcbiAgICByZXR1cm4gZmV0Y2hlZE1vZHVsZXM7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgdGhyb3cgbmV3IEV4cG9ydEVycm9yKFxuICAgICAgJ1tjYWNoZV0gVW5hYmxlIHRvIHVwZGF0ZSB0aGUgbG9jYWwgSGlnaGNoYXJ0cyBjYWNoZS4nXG4gICAgKS5zZXRFcnJvcihlcnJvcik7XG4gIH1cbn07XG5cbi8qKlxuICogVXBkYXRlcyB0aGUgSGlnaGNoYXJ0cyB2ZXJzaW9uIGluIHRoZSBhcHBsaWVkIGNvbmZpZ3VyYXRpb24gYW5kIGNoZWNrc1xuICogdGhlIGNhY2hlIGZvciB0aGUgbmV3IHZlcnNpb24uXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IG5ld1ZlcnNpb24gLSBUaGUgbmV3IEhpZ2hjaGFydHMgdmVyc2lvbiB0byBiZSBhcHBsaWVkLlxuICpcbiAqIEByZXR1cm5zIHtQcm9taXNlPChvYmplY3R8Ym9vbGVhbik+fSBBIFByb21pc2UgcmVzb2x2aW5nIHRvIHRoZSB1cGRhdGVkXG4gKiBjb25maWd1cmF0aW9uIHdpdGggdGhlIG5ldyB2ZXJzaW9uLCBvciBmYWxzZSBpZiBubyBhcHBsaWVkIGNvbmZpZ3VyYXRpb25cbiAqIGV4aXN0cy5cbiAqL1xuZXhwb3J0IGNvbnN0IHVwZGF0ZVZlcnNpb24gPSBhc3luYyAobmV3VmVyc2lvbikgPT4ge1xuICBjb25zdCBvcHRpb25zID0gZ2V0T3B0aW9ucygpO1xuICBpZiAob3B0aW9ucz8uaGlnaGNoYXJ0cykge1xuICAgIG9wdGlvbnMuaGlnaGNoYXJ0cy52ZXJzaW9uID0gbmV3VmVyc2lvbjtcbiAgfVxuICBhd2FpdCBjaGVja0FuZFVwZGF0ZUNhY2hlKG9wdGlvbnMpO1xufTtcblxuLyoqXG4gKiBDaGVja3MgdGhlIGNhY2hlIGZvciBIaWdoY2hhcnRzIGRlcGVuZGVuY2llcywgdXBkYXRlcyB0aGUgY2FjaGUgaWYgbmVlZGVkLFxuICogYW5kIGxvYWRzIHRoZSBzb3VyY2VzLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gT2JqZWN0IGNvbnRhaW5pbmcgYWxsIG9wdGlvbnMuXG4gKlxuICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IEEgUHJvbWlzZSB0aGF0IHJlc29sdmVzIG9uY2UgdGhlIGNhY2hlIGlzIGNoZWNrZWRcbiAqIGFuZCB1cGRhdGVkLlxuICpcbiAqIEB0aHJvd3Mge0V4cG9ydEVycm9yfSBUaHJvd3MgYW4gRXhwb3J0RXJyb3IgaWYgdGhlcmUgaXMgYW4gaXNzdWUgdXBkYXRpbmdcbiAqIG9yIHJlYWRpbmcgdGhlIGNhY2hlLlxuICovXG5leHBvcnQgY29uc3QgY2hlY2tBbmRVcGRhdGVDYWNoZSA9IGFzeW5jIChvcHRpb25zKSA9PiB7XG4gIGNvbnN0IHsgaGlnaGNoYXJ0cywgc2VydmVyIH0gPSBvcHRpb25zO1xuICBjb25zdCBjYWNoZVBhdGggPSBqb2luKF9fZGlybmFtZSwgaGlnaGNoYXJ0cy5jYWNoZVBhdGgpO1xuXG4gIGxldCBmZXRjaGVkTW9kdWxlcztcbiAgLy8gUHJlcGFyZSBwYXRocyB0byBtYW5pZmVzdCBhbmQgc291cmNlcyBmcm9tIHRoZSAuY2FjaGUgZm9sZGVyXG4gIGNvbnN0IG1hbmlmZXN0UGF0aCA9IGpvaW4oY2FjaGVQYXRoLCAnbWFuaWZlc3QuanNvbicpO1xuICBjb25zdCBzb3VyY2VQYXRoID0gam9pbihjYWNoZVBhdGgsICdzb3VyY2VzLmpzJyk7XG5cbiAgLy8gQ3JlYXRlIHRoZSBjYWNoZSBkZXN0aW5hdGlvbiBpZiBpdCBkb2Vzbid0IGV4aXN0IGFscmVhZHlcbiAgIWV4aXN0c1N5bmMoY2FjaGVQYXRoKSAmJiBta2RpclN5bmMoY2FjaGVQYXRoKTtcblxuICAvLyBGZXRjaCBhbGwgdGhlIHNjcmlwdHMgZWl0aGVyIGlmIG1hbmlmZXN0Lmpzb24gZG9lcyBub3QgZXhpc3RcbiAgLy8gb3IgaWYgdGhlIGZvcmNlRmV0Y2ggb3B0aW9uIGlzIGVuYWJsZWRcbiAgaWYgKCFleGlzdHNTeW5jKG1hbmlmZXN0UGF0aCkgfHwgaGlnaGNoYXJ0cy5mb3JjZUZldGNoKSB7XG4gICAgbG9nKDMsICdbY2FjaGVdIEZldGNoaW5nIGFuZCBjYWNoaW5nIEhpZ2hjaGFydHMgZGVwZW5kZW5jaWVzLicpO1xuICAgIGZldGNoZWRNb2R1bGVzID0gYXdhaXQgdXBkYXRlQ2FjaGUoaGlnaGNoYXJ0cywgc2VydmVyLnByb3h5LCBzb3VyY2VQYXRoKTtcbiAgfSBlbHNlIHtcbiAgICBsZXQgcmVxdWVzdFVwZGF0ZSA9IGZhbHNlO1xuXG4gICAgLy8gUmVhZCB0aGUgbWFuaWZlc3QgSlNPTlxuICAgIGNvbnN0IG1hbmlmZXN0ID0gSlNPTi5wYXJzZShyZWFkRmlsZVN5bmMobWFuaWZlc3RQYXRoKSk7XG5cbiAgICAvLyBDaGVjayBpZiB0aGUgbW9kdWxlcyBpcyBhbiBhcnJheSwgaWYgc28sIHdlIHJld3JpdGUgaXQgdG8gYSBtYXAgdG8gbWFrZVxuICAgIC8vIGl0IGVhc2llciB0byByZXNvbHZlIG1vZHVsZXMuXG4gICAgaWYgKG1hbmlmZXN0Lm1vZHVsZXMgJiYgQXJyYXkuaXNBcnJheShtYW5pZmVzdC5tb2R1bGVzKSkge1xuICAgICAgY29uc3QgbW9kdWxlTWFwID0ge307XG4gICAgICBtYW5pZmVzdC5tb2R1bGVzLmZvckVhY2goKG0pID0+IChtb2R1bGVNYXBbbV0gPSAxKSk7XG4gICAgICBtYW5pZmVzdC5tb2R1bGVzID0gbW9kdWxlTWFwO1xuICAgIH1cblxuICAgIGNvbnN0IHsgY29yZVNjcmlwdHMsIG1vZHVsZVNjcmlwdHMsIGluZGljYXRvclNjcmlwdHMgfSA9IGhpZ2hjaGFydHM7XG4gICAgY29uc3QgbnVtYmVyT2ZNb2R1bGVzID1cbiAgICAgIGNvcmVTY3JpcHRzLmxlbmd0aCArIG1vZHVsZVNjcmlwdHMubGVuZ3RoICsgaW5kaWNhdG9yU2NyaXB0cy5sZW5ndGg7XG5cbiAgICAvLyBDb21wYXJlIHRoZSBsb2FkZWQgaGlnaGNoYXJ0cyBjb25maWcgd2l0aCB0aGUgY29udGVudHMgaW4gY2FjaGUuXG4gICAgLy8gSWYgdGhlcmUgYXJlIGNoYW5nZXMsIGZldGNoIHJlcXVlc3RlZCBtb2R1bGVzIGFuZCBwcm9kdWN0cyxcbiAgICAvLyBhbmQgYmFrZSB0aGVtIGludG8gYSBnaWFudCBibG9iLiBTYXZlIHRoZSBibG9iLlxuICAgIGlmIChtYW5pZmVzdC52ZXJzaW9uICE9PSBoaWdoY2hhcnRzLnZlcnNpb24pIHtcbiAgICAgIGxvZyhcbiAgICAgICAgMixcbiAgICAgICAgJ1tjYWNoZV0gQSBIaWdoY2hhcnRzIHZlcnNpb24gbWlzbWF0Y2ggaW4gdGhlIGNhY2hlLCBuZWVkIHRvIHJlLWZldGNoLidcbiAgICAgICk7XG4gICAgICByZXF1ZXN0VXBkYXRlID0gdHJ1ZTtcbiAgICB9IGVsc2UgaWYgKE9iamVjdC5rZXlzKG1hbmlmZXN0Lm1vZHVsZXMgfHwge30pLmxlbmd0aCAhPT0gbnVtYmVyT2ZNb2R1bGVzKSB7XG4gICAgICBsb2coXG4gICAgICAgIDIsXG4gICAgICAgICdbY2FjaGVdIFRoZSBjYWNoZSBhbmQgdGhlIHJlcXVlc3RlZCBtb2R1bGVzIGRvIG5vdCBtYXRjaCwgbmVlZCB0byByZS1mZXRjaC4nXG4gICAgICApO1xuICAgICAgcmVxdWVzdFVwZGF0ZSA9IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIENoZWNrIGVhY2ggbW9kdWxlLCBpZiBhbnl0aGluZyBpcyBtaXNzaW5nIHJlZmV0Y2ggZXZlcnl0aGluZ1xuICAgICAgcmVxdWVzdFVwZGF0ZSA9IChtb2R1bGVTY3JpcHRzIHx8IFtdKS5zb21lKChtb2R1bGVOYW1lKSA9PiB7XG4gICAgICAgIGlmICghbWFuaWZlc3QubW9kdWxlc1ttb2R1bGVOYW1lXSkge1xuICAgICAgICAgIGxvZyhcbiAgICAgICAgICAgIDIsXG4gICAgICAgICAgICBgW2NhY2hlXSBUaGUgJHttb2R1bGVOYW1lfSBpcyBtaXNzaW5nIGluIHRoZSBjYWNoZSwgbmVlZCB0byByZS1mZXRjaC5gXG4gICAgICAgICAgKTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKHJlcXVlc3RVcGRhdGUpIHtcbiAgICAgIGZldGNoZWRNb2R1bGVzID0gYXdhaXQgdXBkYXRlQ2FjaGUoaGlnaGNoYXJ0cywgc2VydmVyLnByb3h5LCBzb3VyY2VQYXRoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbG9nKDMsICdbY2FjaGVdIERlcGVuZGVuY3kgY2FjaGUgaXMgdXAgdG8gZGF0ZSwgcHJvY2VlZGluZy4nKTtcblxuICAgICAgLy8gTG9hZCB0aGUgc291cmNlc1xuICAgICAgY2FjaGUuc291cmNlcyA9IHJlYWRGaWxlU3luYyhzb3VyY2VQYXRoLCAndXRmOCcpO1xuXG4gICAgICAvLyBHZXQgY3VycmVudCBtb2R1bGVzIG1hcFxuICAgICAgZmV0Y2hlZE1vZHVsZXMgPSBtYW5pZmVzdC5tb2R1bGVzO1xuXG4gICAgICBjYWNoZS5oY1ZlcnNpb24gPSBleHRyYWN0VmVyc2lvbihjYWNoZSk7XG4gICAgfVxuICB9XG5cbiAgLy8gRmluYWxseSwgc2F2ZSB0aGUgbmV3IG1hbmlmZXN0LCB3aGljaCBpcyBiYXNpY2FsbHkgb3VyIGN1cnJlbnQgY29uZmlnXG4gIC8vIGluIGEgc2xpZ2h0bHkgZGlmZmVyZW50IGZvcm1hdFxuICBhd2FpdCBzYXZlQ29uZmlnVG9NYW5pZmVzdChoaWdoY2hhcnRzLCBmZXRjaGVkTW9kdWxlcyk7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0Q2FjaGVQYXRoID0gKCkgPT5cbiAgam9pbihfX2Rpcm5hbWUsIGdldE9wdGlvbnMoKS5oaWdoY2hhcnRzLmNhY2hlUGF0aCk7XG5cbmV4cG9ydCBjb25zdCBnZXRDYWNoZSA9ICgpID0+IGNhY2hlO1xuXG5leHBvcnQgY29uc3QgaGlnaGNoYXJ0cyA9ICgpID0+IGNhY2hlLnNvdXJjZXM7XG5cbmV4cG9ydCBjb25zdCB2ZXJzaW9uID0gKCkgPT4gY2FjaGUuaGNWZXJzaW9uO1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIGNoZWNrQW5kVXBkYXRlQ2FjaGUsXG4gIGdldENhY2hlUGF0aCxcbiAgdXBkYXRlVmVyc2lvbixcbiAgZ2V0Q2FjaGUsXG4gIGhpZ2hjaGFydHMsXG4gIHZlcnNpb25cbn07XG4iLCIvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuXG5IaWdoY2hhcnRzIEV4cG9ydCBTZXJ2ZXJcblxuQ29weXJpZ2h0IChjKSAyMDE2LTIwMjQsIEhpZ2hzb2Z0XG5cbkxpY2VuY2VkIHVuZGVyIHRoZSBNSVQgbGljZW5jZS5cblxuQWRkaXRpb25hbGx5IGEgdmFsaWQgSGlnaGNoYXJ0cyBsaWNlbnNlIGlzIHJlcXVpcmVkIGZvciB1c2UuXG5cblNlZSBMSUNFTlNFIGZpbGUgaW4gcm9vdCBmb3IgZGV0YWlscy5cblxuKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuLyogZXNsaW50LWRpc2FibGUgbm8tdW5kZWYgKi9cblxuLyoqXG4gKiBTZXR0aW5nIHRoZSBhbmltT2JqZWN0LiBDYWxsZWQgd2hlbiBpbml0aW5nIHRoZSBwYWdlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc2V0dXBIaWdoY2hhcnRzKCkge1xuICBIaWdoY2hhcnRzLmFuaW1PYmplY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHsgZHVyYXRpb246IDAgfTtcbiAgfTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIHRoZSBhY3R1YWwgY2hhcnQuXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IGNoYXJ0T3B0aW9ucyAtIFRoZSBvcHRpb25zIGZvciB0aGUgSGlnaGNoYXJ0cyBjaGFydC5cbiAqIEBwYXJhbSB7b2JqZWN0fSBvcHRpb25zIC0gVGhlIGV4cG9ydCBvcHRpb25zLlxuICogQHBhcmFtIHtib29sZWFufSBkaXNwbGF5RXJyb3JzIC0gQSBmbGFnIGluZGljYXRpbmcgd2hldGhlciB0byBkaXNwbGF5IGVycm9ycy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHRyaWdnZXJFeHBvcnQoY2hhcnRPcHRpb25zLCBvcHRpb25zLCBkaXNwbGF5RXJyb3JzKSB7XG4gIC8vIERpc3BsYXkgZXJyb3JzIGZsYWcgdGFrZW4gZnJvbSBjaGFydCBvcHRpb25zIG5hZCBkZWJ1Z2dlciBtb2R1bGVcbiAgd2luZG93Ll9kaXNwbGF5RXJyb3JzID0gZGlzcGxheUVycm9ycztcblxuICAvLyBHZXQgcmVxdWlyZWQgZnVuY3Rpb25zXG4gIGNvbnN0IHsgZ2V0T3B0aW9ucywgbWVyZ2UsIHNldE9wdGlvbnMsIHdyYXAgfSA9IEhpZ2hjaGFydHM7XG5cbiAgLy8gQ3JlYXRlIGEgc2VwYXJhdGUgb2JqZWN0IGZvciBhIHBvdGVudGlhbCBzZXRPcHRpb25zIHVzYWdlcyBpbiBvcmRlciB0b1xuICAvLyBwcmV2ZW50IGZyb20gcG9sbHV0aW5nIG90aGVyIGV4cG9ydHMgdGhhdCBjYW4gaGFwcGVuIG9uIHRoZSBzYW1lIHBhZ2VcbiAgSGlnaGNoYXJ0cy5zZXRPcHRpb25zT2JqID0gbWVyZ2UoZmFsc2UsIHt9LCBnZXRPcHRpb25zKCkpO1xuXG4gIC8vIEJ5IGRlZmF1bHQgYW5pbWF0aW9uIGlzIGRpc2FibGVkXG4gIGNvbnN0IGNoYXJ0ID0ge1xuICAgIGFuaW1hdGlvbjogZmFsc2VcbiAgfTtcblxuICAvLyBXaGVuIHN0cmFpZ2h0IGluamVjdCwgdGhlIHNpemUgaXMgc2V0IHRocm91Z2ggQ1NTIG9ubHlcbiAgaWYgKG9wdGlvbnMuZXhwb3J0LnN0ckluaikge1xuICAgIGNoYXJ0LmhlaWdodCA9IGNoYXJ0T3B0aW9ucy5jaGFydC5oZWlnaHQ7XG4gICAgY2hhcnQud2lkdGggPSBjaGFydE9wdGlvbnMuY2hhcnQud2lkdGg7XG4gIH1cblxuICAvLyBOT1RFOiBJcyB0aGlzIHVzZWQgZm9yIGFueXRoaW5nIHVzZWZ1bD9cbiAgd2luZG93LmlzUmVuZGVyQ29tcGxldGUgPSBmYWxzZTtcbiAgd3JhcChIaWdoY2hhcnRzLkNoYXJ0LnByb3RvdHlwZSwgJ2luaXQnLCBmdW5jdGlvbiAocHJvY2VlZCwgdXNlck9wdGlvbnMsIGNiKSB7XG4gICAgLy8gT3ZlcnJpZGUgdXNlck9wdGlvbnMgd2l0aCBpbWFnZSBmcmllbmRseSBvcHRpb25zXG4gICAgdXNlck9wdGlvbnMgPSBtZXJnZSh1c2VyT3B0aW9ucywge1xuICAgICAgZXhwb3J0aW5nOiB7XG4gICAgICAgIGVuYWJsZWQ6IGZhbHNlXG4gICAgICB9LFxuICAgICAgcGxvdE9wdGlvbnM6IHtcbiAgICAgICAgc2VyaWVzOiB7XG4gICAgICAgICAgbGFiZWw6IHtcbiAgICAgICAgICAgIGVuYWJsZWQ6IGZhbHNlXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgLyogRXhwZWN0cyB0b29sdGlwIGluIHVzZXJPcHRpb25zIHdoZW4gZm9yRXhwb3J0IGlzIHRydWUuXG4gICAgICAgIGh0dHBzOi8vZ2l0aHViLmNvbS9oaWdoY2hhcnRzL2hpZ2hjaGFydHMvYmxvYi8zYWQ0MzBhMzUzYjgwNTZiOWU3NjRhYTRlNWNkNjgyOGFhNDc5ZGIyL2pzL3BhcnRzL0NoYXJ0LmpzI0wyNDFcbiAgICAgICAgKi9cbiAgICAgIHRvb2x0aXA6IHt9XG4gICAgfSk7XG5cbiAgICAodXNlck9wdGlvbnMuc2VyaWVzIHx8IFtdKS5mb3JFYWNoKGZ1bmN0aW9uIChzZXJpZXMpIHtcbiAgICAgIHNlcmllcy5hbmltYXRpb24gPSBmYWxzZTtcbiAgICB9KTtcblxuICAgIC8vIEFkZCBmbGFnIHRvIGtub3cgaWYgY2hhcnQgcmVuZGVyIGhhcyBiZWVuIGNhbGxlZC5cbiAgICBpZiAoIXdpbmRvdy5vbkhpZ2hjaGFydHNSZW5kZXIpIHtcbiAgICAgIHdpbmRvdy5vbkhpZ2hjaGFydHNSZW5kZXIgPSBIaWdoY2hhcnRzLmFkZEV2ZW50KHRoaXMsICdyZW5kZXInLCAoKSA9PiB7XG4gICAgICAgIHdpbmRvdy5pc1JlbmRlckNvbXBsZXRlID0gdHJ1ZTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHByb2NlZWQuYXBwbHkodGhpcywgW3VzZXJPcHRpb25zLCBjYl0pO1xuICB9KTtcblxuICB3cmFwKEhpZ2hjaGFydHMuU2VyaWVzLnByb3RvdHlwZSwgJ2luaXQnLCBmdW5jdGlvbiAocHJvY2VlZCwgY2hhcnQsIG9wdGlvbnMpIHtcbiAgICBwcm9jZWVkLmFwcGx5KHRoaXMsIFtjaGFydCwgb3B0aW9uc10pO1xuICB9KTtcblxuICAvLyBHZXQgdGhlIHVzZXIgb3B0aW9uc1xuICBjb25zdCB1c2VyT3B0aW9ucyA9IG9wdGlvbnMuZXhwb3J0LnN0cklualxuICAgID8gbmV3IEZ1bmN0aW9uKGByZXR1cm4gJHtvcHRpb25zLmV4cG9ydC5zdHJJbmp9YCkoKVxuICAgIDogY2hhcnRPcHRpb25zO1xuXG4gIC8vIFRyaWdnZXIgY3VzdG9tIGNvZGVcbiAgaWYgKG9wdGlvbnMuY3VzdG9tTG9naWMuY3VzdG9tQ29kZSkge1xuICAgIG5ldyBGdW5jdGlvbignb3B0aW9ucycsIG9wdGlvbnMuY3VzdG9tTG9naWMuY3VzdG9tQ29kZSkodXNlck9wdGlvbnMpO1xuICB9XG5cbiAgLy8gTWVyZ2UgdGhlIGdsb2JhbE9wdGlvbnMsIHRoZW1lT3B0aW9ucywgb3B0aW9ucyBmcm9tIHRoZSB3cmFwcGVkXG4gIC8vIHNldE9wdGlvbnMgZnVuY3Rpb24gYW5kIHVzZXIgb3B0aW9ucyB0byBjcmVhdGUgdGhlIGZpbmFsIG9wdGlvbnMgb2JqZWN0XG4gIGNvbnN0IGZpbmFsT3B0aW9ucyA9IG1lcmdlKFxuICAgIGZhbHNlLFxuICAgIEpTT04ucGFyc2Uob3B0aW9ucy5leHBvcnQudGhlbWVPcHRpb25zKSxcbiAgICB1c2VyT3B0aW9ucyxcbiAgICAvLyBQbGFjZWQgaXQgaGVyZSBpbnN0ZWFkIGluIHRoZSBpbml0IGJlY2F1c2Ugb2YgdGhlIHNpemUgaXNzdWVzXG4gICAgeyBjaGFydCB9XG4gICk7XG5cbiAgY29uc3QgZmluYWxDYWxsYmFjayA9IG9wdGlvbnMuY3VzdG9tTG9naWMuY2FsbGJhY2tcbiAgICA/IG5ldyBGdW5jdGlvbihgcmV0dXJuICR7b3B0aW9ucy5jdXN0b21Mb2dpYy5jYWxsYmFja31gKSgpXG4gICAgOiB1bmRlZmluZWQ7XG5cbiAgLy8gU2V0IHRoZSBnbG9iYWwgb3B0aW9ucyBpZiBleGlzdFxuICBjb25zdCBnbG9iYWxPcHRpb25zID0gSlNPTi5wYXJzZShvcHRpb25zLmV4cG9ydC5nbG9iYWxPcHRpb25zKTtcbiAgaWYgKGdsb2JhbE9wdGlvbnMpIHtcbiAgICBzZXRPcHRpb25zKGdsb2JhbE9wdGlvbnMpO1xuICB9XG5cbiAgbGV0IGNvbnN0ciA9IG9wdGlvbnMuZXhwb3J0LmNvbnN0ciB8fCAnY2hhcnQnO1xuICBjb25zdHIgPSB0eXBlb2YgSGlnaGNoYXJ0c1tjb25zdHJdICE9PSAndW5kZWZpbmVkJyA/IGNvbnN0ciA6ICdjaGFydCc7XG5cbiAgSGlnaGNoYXJ0c1tjb25zdHJdKCdjb250YWluZXInLCBmaW5hbE9wdGlvbnMsIGZpbmFsQ2FsbGJhY2spO1xuXG4gIC8vIEdldCB0aGUgY3VycmVudCBnbG9iYWwgb3B0aW9uc1xuICBjb25zdCBkZWZhdWx0T3B0aW9ucyA9IGdldE9wdGlvbnMoKTtcblxuICAvLyBDbGVhciBpdCBqdXN0IGluIGNhc2UgKGUuZy4gdGhlIHNldE9wdGlvbnMgd2FzIHVzZWQgaW4gdGhlIGN1c3RvbUNvZGUpXG4gIGZvciAoY29uc3QgcHJvcCBpbiBkZWZhdWx0T3B0aW9ucykge1xuICAgIGlmICh0eXBlb2YgZGVmYXVsdE9wdGlvbnNbcHJvcF0gIT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGRlbGV0ZSBkZWZhdWx0T3B0aW9uc1twcm9wXTtcbiAgICB9XG4gIH1cblxuICAvLyBTZXQgdGhlIGRlZmF1bHQgb3B0aW9ucyBiYWNrXG4gIHNldE9wdGlvbnMoSGlnaGNoYXJ0cy5zZXRPcHRpb25zT2JqKTtcblxuICAvLyBFbXB0eSB0aGUgY3VzdG9tIGdsb2JhbCBvcHRpb25zIG9iamVjdFxuICBIaWdoY2hhcnRzLnNldE9wdGlvbnNPYmogPSB7fTtcbn1cbiIsIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG5cbkhpZ2hjaGFydHMgRXhwb3J0IFNlcnZlclxuXG5Db3B5cmlnaHQgKGMpIDIwMTYtMjAyNCwgSGlnaHNvZnRcblxuTGljZW5jZWQgdW5kZXIgdGhlIE1JVCBsaWNlbmNlLlxuXG5BZGRpdGlvbmFsbHkgYSB2YWxpZCBIaWdoY2hhcnRzIGxpY2Vuc2UgaXMgcmVxdWlyZWQgZm9yIHVzZS5cblxuU2VlIExJQ0VOU0UgZmlsZSBpbiByb290IGZvciBkZXRhaWxzLlxuXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG5pbXBvcnQgeyByZWFkRmlsZVN5bmMgfSBmcm9tICdmcyc7XG5pbXBvcnQgcGF0aCBmcm9tICdwYXRoJztcblxuaW1wb3J0IHB1cHBldGVlciBmcm9tICdwdXBwZXRlZXInO1xuXG5pbXBvcnQgeyBnZXRDYWNoZVBhdGggfSBmcm9tICcuL2NhY2hlLmpzJztcbmltcG9ydCB7IGdldE9wdGlvbnMgfSBmcm9tICcuL2NvbmZpZy5qcyc7XG5pbXBvcnQgeyBzZXR1cEhpZ2hjaGFydHMgfSBmcm9tICcuL2hpZ2hjaGFydHMuanMnO1xuaW1wb3J0IHsgbG9nLCBsb2dXaXRoU3RhY2sgfSBmcm9tICcuL2xvZ2dlci5qcyc7XG5pbXBvcnQgeyBfX2Rpcm5hbWUgfSBmcm9tICcuL3V0aWxzLmpzJztcblxuaW1wb3J0IEV4cG9ydEVycm9yIGZyb20gJy4vZXJyb3JzL0V4cG9ydEVycm9yLmpzJztcblxuLy8gR2V0IHRoZSB0ZW1wbGF0ZSBmb3IgdGhlIHBhZ2VcbmNvbnN0IHRlbXBsYXRlID0gcmVhZEZpbGVTeW5jKF9fZGlybmFtZSArICcvdGVtcGxhdGVzL3RlbXBsYXRlLmh0bWwnLCAndXRmOCcpO1xuXG5sZXQgYnJvd3NlcjtcblxuLyoqXG4gKiBSZXRyaWV2ZXMgdGhlIGV4aXN0aW5nIFB1cHBldGVlciBicm93c2VyIGluc3RhbmNlLlxuICpcbiAqIEByZXR1cm5zIHtQcm9taXNlPG9iamVjdD59IEEgUHJvbWlzZSByZXNvbHZpbmcgdG8gdGhlIFB1cHBldGVlciBicm93c2VyXG4gKiBpbnN0YW5jZS5cbiAqXG4gKiBAdGhyb3dzIHtFeHBvcnRFcnJvcn0gVGhyb3dzIGFuIEV4cG9ydEVycm9yIGlmIG5vIHZhbGlkIGJyb3dzZXIgaGFzIGJlZW5cbiAqIGNyZWF0ZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXQoKSB7XG4gIGlmICghYnJvd3Nlcikge1xuICAgIHRocm93IG5ldyBFeHBvcnRFcnJvcignW2Jyb3dzZXJdIE5vIHZhbGlkIGJyb3dzZXIgaGFzIGJlZW4gY3JlYXRlZC4nKTtcbiAgfVxuICByZXR1cm4gYnJvd3Nlcjtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgUHVwcGV0ZWVyIGJyb3dzZXIgaW5zdGFuY2Ugd2l0aCB0aGUgc3BlY2lmaWVkIGFyZ3VtZW50cy5cbiAqXG4gKiBAcGFyYW0ge0FycmF5fSBwdXBwZXRlZXJBcmdzIC0gQWRkaXRpb25hbCBhcmd1bWVudHMgZm9yIFB1cHBldGVlciBsYXVuY2guXG4gKlxuICogQHJldHVybnMge1Byb21pc2U8b2JqZWN0Pn0gQSBQcm9taXNlIHJlc29sdmluZyB0byB0aGUgUHVwcGV0ZWVyIGJyb3dzZXJcbiAqIGluc3RhbmNlLlxuICpcbiAqIEB0aHJvd3Mge0V4cG9ydEVycm9yfSBUaHJvd3MgYW4gRXhwb3J0RXJyb3IgaWYgbWF4IHJldHJpZXMgdG8gb3BlbiBhIGJyb3dzZXJcbiAqIGluc3RhbmNlIGFyZSByZWFjaGVkLCBvciBpZiBubyBicm93c2VyIGluc3RhbmNlIGlzIGZvdW5kIGFmdGVyIHJldHJpZXMuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjcmVhdGUocHVwcGV0ZWVyQXJncykge1xuICAvLyBHZXQgZGVidWcgYW5kIG90aGVyIG9wdGlvbnNcbiAgY29uc3QgeyBwdXBwZXRlZXI6IHB1cHBldGVlck9wdGlvbnMsIGRlYnVnLCBvdGhlciB9ID0gZ2V0T3B0aW9ucygpO1xuXG4gIC8vIEdldCB0aGUgZGVidWcgb3B0aW9uc1xuICBjb25zdCB7IGVuYWJsZTogZW5hYmxlZERlYnVnLCAuLi5kZWJ1Z09wdGlvbnMgfSA9IGRlYnVnO1xuXG4gIGNvbnN0IGxhdW5jaE9wdGlvbnMgPSB7XG4gICAgaGVhZGxlc3M6IG90aGVyLmJyb3dzZXJTaGVsbE1vZGUgPyAnc2hlbGwnIDogdHJ1ZSxcbiAgICB1c2VyRGF0YURpcjogcHVwcGV0ZWVyT3B0aW9ucy50ZW1wRGlyIHx8ICcuL3RtcC8nLFxuICAgIGFyZ3M6IHB1cHBldGVlckFyZ3MsXG4gICAgaGFuZGxlU0lHSU5UOiBmYWxzZSxcbiAgICBoYW5kbGVTSUdURVJNOiBmYWxzZSxcbiAgICBoYW5kbGVTSUdIVVA6IGZhbHNlLFxuICAgIHdhaXRGb3JJbml0aWFsUGFnZTogZmFsc2UsXG4gICAgZGVmYXVsdFZpZXdwb3J0OiBudWxsLFxuICAgIC4uLihlbmFibGVkRGVidWcgJiYgZGVidWdPcHRpb25zKVxuICB9O1xuXG4gIC8vIENyZWF0ZSBhIGJyb3dzZXJcbiAgaWYgKCFicm93c2VyKSB7XG4gICAgY29uc3QgbWF4VHJpZXMgPSAyNTtcbiAgICBsZXQgdHJ5Q291bnQgPSAwO1xuXG4gICAgY29uc3Qgb3BlbiA9IGFzeW5jICgpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGxvZyhcbiAgICAgICAgICAzLFxuICAgICAgICAgIGBbYnJvd3Nlcl0gQXR0ZW1wdGluZyB0byBnZXQgYSBicm93c2VyIGluc3RhbmNlICh0cnkgJHsrK3RyeUNvdW50fSkuYFxuICAgICAgICApO1xuICAgICAgICBicm93c2VyID0gYXdhaXQgcHVwcGV0ZWVyLmxhdW5jaChsYXVuY2hPcHRpb25zKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIC8vIFRoaXMgaXNuJ3QgYSBmdWxsIGVycm9yIHlldCBhcyBwdXBwZXRlZXIgc29tZXRpbWVzIHRha2VzIHRpbWUgdG9cbiAgICAgICAgLy8gaW5pdGlhbGl6ZSBwcm9wZXJseS5cbiAgICAgICAgbG9nV2l0aFN0YWNrKFxuICAgICAgICAgIDIsXG4gICAgICAgICAgZXJyb3IsXG4gICAgICAgICAgYFticm93c2VyXSBGYWlsZWQgdG8gbGF1bmNoIGEgYnJvd3NlciBpbnN0YW5jZSAtIHJldHJ5aW5nIChhdHRlbXB0ICR7dHJ5Q291bnR9LyR7bWF4VHJpZXN9KS5gXG4gICAgICAgICk7XG5cbiAgICAgICAgLy8gUmV0cnkgdG8gbGF1bmNoIGJyb3dzZXIgdW50aWwgcmVhY2hpbmcgbWF4IGF0dGVtcHRzXG4gICAgICAgIGlmICh0cnlDb3VudCA8IDI1KSB7XG4gICAgICAgICAgbG9nKFxuICAgICAgICAgICAgMyxcbiAgICAgICAgICAgIGBbYnJvd3Nlcl0gUmV0cnkgdG8gb3BlbiBhIGJyb3dzZXIgKGF0dGVtcHQgJHt0cnlDb3VudH0vJHttYXhUcmllc30pLmBcbiAgICAgICAgICApO1xuICAgICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKChyZXNwb25zZSkgPT4gc2V0VGltZW91dChyZXNwb25zZSwgNDAwMCkpO1xuICAgICAgICAgIGF3YWl0IG9wZW4oKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLy4uLiBub3cgaXQncyBhbiBlcnJvciwgd2hpY2ggaXMgY2F1Z2h0IGJ5IHRoZSBjYWxsZXJcbiAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgb3BlbigpO1xuXG4gICAgICAvLyBTaGVsbCBtb2RlIGluZm9ybVxuICAgICAgaWYgKGxhdW5jaE9wdGlvbnMuaGVhZGxlc3MgPT09ICdzaGVsbCcpIHtcbiAgICAgICAgbG9nKDMsIGBbYnJvd3Nlcl0gTGF1bmNoZWQgYnJvd3NlciBpbiBzaGVsbCBtb2RlLmApO1xuICAgICAgfVxuXG4gICAgICAvLyBEZWJ1ZyBtb2RlIGluZm9ybVxuICAgICAgaWYgKGVuYWJsZWREZWJ1Zykge1xuICAgICAgICBsb2coMywgYFticm93c2VyXSBMYXVuY2hlZCBicm93c2VyIGluIGRlYnVnIG1vZGUuYCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRocm93IG5ldyBFeHBvcnRFcnJvcihcbiAgICAgICAgJ1ticm93c2VyXSBNYXhpbXVtIHJldHJpZXMgdG8gb3BlbiBhIGJyb3dzZXIgaW5zdGFuY2UgcmVhY2hlZC4nXG4gICAgICApLnNldEVycm9yKGVycm9yKTtcbiAgICB9XG5cbiAgICBpZiAoIWJyb3dzZXIpIHtcbiAgICAgIHRocm93IG5ldyBFeHBvcnRFcnJvcignW2Jyb3dzZXJdIENhbm5vdCBmaW5kIGEgYnJvd3NlciB0byBvcGVuLicpO1xuICAgIH1cbiAgfVxuXG4gIC8vIFJldHVybiBhIGJyb3dzZXIgcHJvbWlzZVxuICByZXR1cm4gYnJvd3Nlcjtcbn1cblxuLyoqXG4gKiBDbG9zZXMgdGhlIFB1cHBldGVlciBicm93c2VyIGluc3RhbmNlIGlmIGl0IGlzIGNvbm5lY3RlZC5cbiAqXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxib29sZWFuPn0gQSBQcm9taXNlIHJlc29sdmluZyB0byB0cnVlIGFmdGVyIHRoZSBicm93c2VyXG4gKiBpcyBjbG9zZWQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjbG9zZSgpIHtcbiAgLy8gQ2xvc2UgdGhlIGJyb3dzZXIgd2hlbiBjb25ubmVjdGVkXG4gIGlmIChicm93c2VyPy5jb25uZWN0ZWQpIHtcbiAgICBhd2FpdCBicm93c2VyLmNsb3NlKCk7XG4gIH1cbiAgbG9nKDQsICdbYnJvd3Nlcl0gQ2xvc2VkIHRoZSBicm93c2VyLicpO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgUHVwcGV0ZWVyIFBhZ2Ugd2l0aGluIGFuIGV4aXN0aW5nIGJyb3dzZXIgaW5zdGFuY2UuXG4gKlxuICogSWYgdGhlIGJyb3dzZXIgaW5zdGFuY2UgaXMgbm90IGF2YWlsYWJsZSwgcmV0dXJucyBmYWxzZS5cbiAqXG4gKiBUaGUgZnVuY3Rpb24gY3JlYXRlcyBhIG5ldyBwYWdlLCBkaXNhYmxlcyBjYWNoaW5nLCBzZXRzIGNvbnRlbnQgdXNpbmdcbiAqIHNldFBhZ2VDb250ZW50KCksIGFuZCByZXR1cm5zIHRoZSBjcmVhdGVkIFB1cHBldGVlciBQYWdlLlxuICpcbiAqIEByZXR1cm5zIHsoYm9vbGVhbnxvYmplY3QpfSBSZXR1cm5zIGZhbHNlIGlmIHRoZSBicm93c2VyIGluc3RhbmNlIGlzIG5vdFxuICogYXZhaWxhYmxlLCBvciBhIFB1cHBldGVlciBQYWdlIG9iamVjdCByZXByZXNlbnRpbmcgdGhlIG5ld2x5IGNyZWF0ZWQgcGFnZS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG5ld1BhZ2UoKSB7XG4gIGlmICghYnJvd3Nlcikge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIENyZWF0ZSBhIHBhZ2VcbiAgY29uc3QgcGFnZSA9IGF3YWl0IGJyb3dzZXIubmV3UGFnZSgpO1xuXG4gIC8vIERpc2FibGUgY2FjaGVcbiAgYXdhaXQgcGFnZS5zZXRDYWNoZUVuYWJsZWQoZmFsc2UpO1xuXG4gIC8vIFNldCB0aGUgY29udGVudFxuICBhd2FpdCBzZXRQYWdlQ29udGVudChwYWdlKTtcblxuICAvLyBTZXQgcGFnZSBldmVudHNcbiAgc2V0UGFnZUV2ZW50cyhwYWdlKTtcblxuICByZXR1cm4gcGFnZTtcbn1cblxuLyoqXG4gKiBDbGVhcnMgdGhlIGNvbnRlbnQgb2YgYSBQdXBwZXRlZXIgUGFnZSBiYXNlZCBvbiB0aGUgc3BlY2lmaWVkIG1vZGUuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHBhZ2UgLSBUaGUgUHVwcGV0ZWVyIFBhZ2Ugb2JqZWN0IHRvIGJlIGNsZWFyZWQuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGhhcmRSZXNldCAtIEEgZmxhZyBpbmRpY2F0aW5nIHRoZSB0eXBlIG9mIGNsZWFyaW5nXG4gKiB0byBiZSBwZXJmb3JtZWQuIElmIHRydWUsIG5hdmlnYXRlcyB0byAnYWJvdXQ6YmxhbmsnIGFuZCByZXNldHMgY29udGVudFxuICogYW5kIHNjcmlwdHMuIElmIGZhbHNlLCBjbGVhcnMgdGhlIGJvZHkgY29udGVudCBieSBzZXR0aW5nIGEgcHJlZGVmaW5lZCBIVE1MXG4gKiBzdHJ1Y3R1cmUuXG4gKlxuICogQHRocm93cyB7RXJyb3J9IExvZ3MgdGhyb3duIGVycm9yIGlmIGNsZWFyaW5nIHRoZSBwYWdlIGNvbnRlbnQgZmFpbHMuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjbGVhclBhZ2UocGFnZSwgaGFyZFJlc2V0ID0gZmFsc2UpIHtcbiAgdHJ5IHtcbiAgICBpZiAocGFnZSAmJiAhcGFnZS5pc0Nsb3NlZCgpKSB7XG4gICAgICBpZiAoaGFyZFJlc2V0KSB7XG4gICAgICAgIC8vIE5hdmlnYXRlIHRvIGFib3V0OmJsYW5rXG4gICAgICAgIGF3YWl0IHBhZ2UuZ290bygnYWJvdXQ6YmxhbmsnLCB7IHdhaXRVbnRpbDogJ2RvbWNvbnRlbnRsb2FkZWQnIH0pO1xuXG4gICAgICAgIC8vIFNldCB0aGUgY29udGVudCBhbmQgYW5kIHNjcmlwdHMgYWdhaW5cbiAgICAgICAgYXdhaXQgc2V0UGFnZUNvbnRlbnQocGFnZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBDbGVhciBib2R5IGNvbnRlbnRcbiAgICAgICAgYXdhaXQgcGFnZS5ldmFsdWF0ZSgoKSA9PiB7XG4gICAgICAgICAgZG9jdW1lbnQuYm9keS5pbm5lckhUTUwgPVxuICAgICAgICAgICAgJzxkaXYgaWQ9XCJjaGFydC1jb250YWluZXJcIj48ZGl2IGlkPVwiY29udGFpbmVyXCI+PC9kaXY+PC9kaXY+JztcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgbG9nV2l0aFN0YWNrKFxuICAgICAgMixcbiAgICAgIGVycm9yLFxuICAgICAgJ1ticm93c2VyXSBDb3VsZCBub3QgY2xlYXIgdGhlIGNvbnRlbnQgb2YgdGhlIHBhZ2UuJ1xuICAgICk7XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogQWRkcyBjdXN0b20gSlMgYW5kIENTUyByZXNvdXJjZXMgdG8gYSBQdXBwZXRlZXIgUGFnZSBiYXNlZCBvbiB0aGUgc3BlY2lmaWVkXG4gKiBvcHRpb25zLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYWdlIC0gVGhlIFB1cHBldGVlciBQYWdlIG9iamVjdCB0byB3aGljaCByZXNvdXJjZXMgd2lsbCBiZVxuICogYWRkZWQuXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIEFsbCBvcHRpb25zIGFuZCBjb25maWd1cmF0aW9uLlxuICpcbiAqIEByZXR1cm5zIHtQcm9taXNlPEFycmF5PE9iamVjdD4+fSAtIFByb21pc2UgcmVzb2x2aW5nIHRvIGFuIGFycmF5IG9mIGluamVjdGVkXG4gKiByZXNvdXJjZXMuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBhZGRQYWdlUmVzb3VyY2VzKHBhZ2UsIG9wdGlvbnMpIHtcbiAgLy8gSW5qZWN0ZWQgcmVzb3VyY2VzIGFycmF5XG4gIGNvbnN0IGluamVjdGVkUmVzb3VyY2VzID0gW107XG5cbiAgLy8gVXNlIHJlc291cmNlc1xuICBjb25zdCByZXNvdXJjZXMgPSBvcHRpb25zLmN1c3RvbUxvZ2ljLnJlc291cmNlcztcbiAgaWYgKHJlc291cmNlcykge1xuICAgIGNvbnN0IGluamVjdGVkSnMgPSBbXTtcblxuICAgIC8vIExvYWQgY3VzdG9tIEpTIGNvZGVcbiAgICBpZiAocmVzb3VyY2VzLmpzKSB7XG4gICAgICBpbmplY3RlZEpzLnB1c2goe1xuICAgICAgICBjb250ZW50OiByZXNvdXJjZXMuanNcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIExvYWQgc2NyaXB0cyBmcm9tIGFsbCBjdXN0b20gZmlsZXNcbiAgICBpZiAocmVzb3VyY2VzLmZpbGVzKSB7XG4gICAgICBmb3IgKGNvbnN0IGZpbGUgb2YgcmVzb3VyY2VzLmZpbGVzKSB7XG4gICAgICAgIGNvbnN0IGlzTG9jYWwgPSAhZmlsZS5zdGFydHNXaXRoKCdodHRwJykgPyB0cnVlIDogZmFsc2U7XG5cbiAgICAgICAgLy8gQWRkIGVhY2ggY3VzdG9tIHNjcmlwdCBmcm9tIHJlc291cmNlcycgZmlsZXNcbiAgICAgICAgaW5qZWN0ZWRKcy5wdXNoKFxuICAgICAgICAgIGlzTG9jYWxcbiAgICAgICAgICAgID8ge1xuICAgICAgICAgICAgICAgIGNvbnRlbnQ6IHJlYWRGaWxlU3luYyhmaWxlLCAndXRmOCcpXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDoge1xuICAgICAgICAgICAgICAgIHVybDogZmlsZVxuICAgICAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBqc1Jlc291cmNlIG9mIGluamVjdGVkSnMpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGluamVjdGVkUmVzb3VyY2VzLnB1c2goYXdhaXQgcGFnZS5hZGRTY3JpcHRUYWcoanNSZXNvdXJjZSkpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgbG9nV2l0aFN0YWNrKDIsIGVycm9yLCBgW2V4cG9ydF0gVGhlIEpTIHJlc291cmNlIGNhbm5vdCBiZSBsb2FkZWQuYCk7XG4gICAgICB9XG4gICAgfVxuICAgIGluamVjdGVkSnMubGVuZ3RoID0gMDtcblxuICAgIC8vIExvYWQgQ1NTXG4gICAgY29uc3QgaW5qZWN0ZWRDc3MgPSBbXTtcbiAgICBpZiAocmVzb3VyY2VzLmNzcykge1xuICAgICAgbGV0IGNzc0ltcG9ydHMgPSByZXNvdXJjZXMuY3NzLm1hdGNoKC9AaW1wb3J0XFxzKihbXjtdKik7L2cpO1xuICAgICAgaWYgKGNzc0ltcG9ydHMpIHtcbiAgICAgICAgLy8gSGFuZGxlIGNzcyBzZWN0aW9uXG4gICAgICAgIGZvciAobGV0IGNzc0ltcG9ydFBhdGggb2YgY3NzSW1wb3J0cykge1xuICAgICAgICAgIGlmIChjc3NJbXBvcnRQYXRoKSB7XG4gICAgICAgICAgICBjc3NJbXBvcnRQYXRoID0gY3NzSW1wb3J0UGF0aFxuICAgICAgICAgICAgICAucmVwbGFjZSgndXJsKCcsICcnKVxuICAgICAgICAgICAgICAucmVwbGFjZSgnQGltcG9ydCcsICcnKVxuICAgICAgICAgICAgICAucmVwbGFjZSgvXCIvZywgJycpXG4gICAgICAgICAgICAgIC5yZXBsYWNlKC8nL2csICcnKVxuICAgICAgICAgICAgICAucmVwbGFjZSgvOy8sICcnKVxuICAgICAgICAgICAgICAucmVwbGFjZSgvXFwpL2csICcnKVxuICAgICAgICAgICAgICAudHJpbSgpO1xuXG4gICAgICAgICAgICAvLyBBZGQgZWFjaCBjdXN0b20gY3NzIGZyb20gcmVzb3VyY2VzXG4gICAgICAgICAgICBpZiAoY3NzSW1wb3J0UGF0aC5zdGFydHNXaXRoKCdodHRwJykpIHtcbiAgICAgICAgICAgICAgaW5qZWN0ZWRDc3MucHVzaCh7XG4gICAgICAgICAgICAgICAgdXJsOiBjc3NJbXBvcnRQYXRoXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChvcHRpb25zLmN1c3RvbUxvZ2ljLmFsbG93RmlsZVJlc291cmNlcykge1xuICAgICAgICAgICAgICBpbmplY3RlZENzcy5wdXNoKHtcbiAgICAgICAgICAgICAgICBwYXRoOiBwYXRoLmpvaW4oX19kaXJuYW1lLCBjc3NJbXBvcnRQYXRoKVxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gVGhlIHJlc3Qgb2YgdGhlIENTUyBzZWN0aW9uIHdpbGwgYmUgY29udGVudCBieSBub3dcbiAgICAgIGluamVjdGVkQ3NzLnB1c2goe1xuICAgICAgICBjb250ZW50OiByZXNvdXJjZXMuY3NzLnJlcGxhY2UoL0BpbXBvcnRcXHMqKFteO10qKTsvZywgJycpIHx8ICcgJ1xuICAgICAgfSk7XG5cbiAgICAgIGZvciAoY29uc3QgY3NzUmVzb3VyY2Ugb2YgaW5qZWN0ZWRDc3MpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBpbmplY3RlZFJlc291cmNlcy5wdXNoKGF3YWl0IHBhZ2UuYWRkU3R5bGVUYWcoY3NzUmVzb3VyY2UpKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICBsb2dXaXRoU3RhY2soMiwgZXJyb3IsIGBbZXhwb3J0XSBUaGUgQ1NTIHJlc291cmNlIGNhbm5vdCBiZSBsb2FkZWQuYCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGluamVjdGVkQ3NzLmxlbmd0aCA9IDA7XG4gICAgfVxuICB9XG4gIHJldHVybiBpbmplY3RlZFJlc291cmNlcztcbn1cblxuLyoqXG4gKiBDbGVhcnMgb3V0IGFsbCBzdGF0ZSBzZXQgb24gdGhlIHBhZ2Ugd2l0aCBhZGRTY3JpcHRUYWcvYWRkU3R5bGVUYWcuIFJlbW92ZXNcbiAqIGluamVjdGVkIHJlc291cmNlcyBhbmQgcmVzZXRzIENTUyBhbmQgc2NyaXB0IHRhZ3Mgb24gdGhlIHBhZ2UuIEFkZGl0aW9uYWxseSxcbiAqIGl0IGRlc3Ryb3lzIHByZXZpb3VzbHkgZXhpc3RpbmcgY2hhcnRzLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYWdlIC0gVGhlIFB1cHBldGVlciBQYWdlIG9iamVjdCBmcm9tIHdoaWNoIHJlc291cmNlcyB3aWxsXG4gKiBiZSBjbGVhcmVkLlxuICogQHBhcmFtIHtBcnJheTxPYmplY3Q+fSBpbmplY3RlZFJlc291cmNlcyAtIEFycmF5IG9mIGluamVjdGVkIHJlc291cmNlc1xuICogdG8gYmUgY2xlYXJlZC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNsZWFyUGFnZVJlc291cmNlcyhwYWdlLCBpbmplY3RlZFJlc291cmNlcykge1xuICB0cnkge1xuICAgIGZvciAoY29uc3QgcmVzb3VyY2Ugb2YgaW5qZWN0ZWRSZXNvdXJjZXMpIHtcbiAgICAgIGF3YWl0IHJlc291cmNlLmRpc3Bvc2UoKTtcbiAgICB9XG5cbiAgICAvLyBEZXN0cm95IG9sZCBjaGFydHMgYWZ0ZXIgZXhwb3J0IGlzIGRvbmUgYW5kIHJlc2V0IGFsbCBDU1MgYW5kIHNjcmlwdCB0YWdzXG4gICAgYXdhaXQgcGFnZS5ldmFsdWF0ZSgoKSA9PiB7XG4gICAgICAvLyBXZSBhcmUgbm90IGd1YXJhbnRlZWQgdGhhdCBIaWdoY2hhcnRzIGlzIGxvYWRlZCwgZSxnLCB3aGVuIGRvaW5nIFNWR1xuICAgICAgLy8gZXhwb3J0c1xuICAgICAgaWYgKHR5cGVvZiBIaWdoY2hhcnRzICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW5kZWZcbiAgICAgICAgY29uc3Qgb2xkQ2hhcnRzID0gSGlnaGNoYXJ0cy5jaGFydHM7XG5cbiAgICAgICAgLy8gQ2hlY2sgaW4gYW55IGFscmVhZHkgZXhpc3RpbmcgY2hhcnRzXG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KG9sZENoYXJ0cykgJiYgb2xkQ2hhcnRzLmxlbmd0aCkge1xuICAgICAgICAgIC8vIERlc3Ryb3kgb2xkIGNoYXJ0c1xuICAgICAgICAgIGZvciAoY29uc3Qgb2xkQ2hhcnQgb2Ygb2xkQ2hhcnRzKSB7XG4gICAgICAgICAgICBvbGRDaGFydCAmJiBvbGRDaGFydC5kZXN0cm95KCk7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW5kZWZcbiAgICAgICAgICAgIEhpZ2hjaGFydHMuY2hhcnRzLnNoaWZ0KCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bmRlZlxuICAgICAgY29uc3QgWy4uLnNjcmlwdHNUb1JlbW92ZV0gPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnc2NyaXB0Jyk7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW5kZWZcbiAgICAgIGNvbnN0IFssIC4uLnN0eWxlc1RvUmVtb3ZlXSA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdzdHlsZScpO1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVuZGVmXG4gICAgICBjb25zdCBbLi4ubGlua3NUb1JlbW92ZV0gPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnbGluaycpO1xuXG4gICAgICAvLyBSZW1vdmUgdGFnc1xuICAgICAgZm9yIChjb25zdCBlbGVtZW50IG9mIFtcbiAgICAgICAgLi4uc2NyaXB0c1RvUmVtb3ZlLFxuICAgICAgICAuLi5zdHlsZXNUb1JlbW92ZSxcbiAgICAgICAgLi4ubGlua3NUb1JlbW92ZVxuICAgICAgXSkge1xuICAgICAgICBlbGVtZW50LnJlbW92ZSgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGxvZ1dpdGhTdGFjaygyLCBlcnJvciwgYFticm93c2VyXSBDb3VsZCBub3QgY2xlYXIgcGFnZSdzIHJlc291cmNlcy5gKTtcbiAgfVxufVxuXG4vKipcbiAqIFNldHMgdGhlIGNvbnRlbnQgZm9yIGEgUHVwcGV0ZWVyIFBhZ2UgdXNpbmcgYSBwcmVkZWZpbmVkIHRlbXBsYXRlXG4gKiBhbmQgYWRkaXRpb25hbCBzY3JpcHRzLiBBbHNvLCBzZXRzIHRoZSBwYWdlZXJyb3IgaW4gb3JkZXIgdG8gY2F0Y2hcbiAqIGFuZCBkaXNwbGF5IGVycm9ycyBmcm9tIHRoZSB3aW5kb3cgY29udGV4dC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gcGFnZSAtIFRoZSBQdXBwZXRlZXIgUGFnZSBvYmplY3QgZm9yIHdoaWNoIHRoZSBjb250ZW50XG4gKiBpcyBiZWluZyBzZXQuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHNldFBhZ2VDb250ZW50KHBhZ2UpIHtcbiAgYXdhaXQgcGFnZS5zZXRDb250ZW50KHRlbXBsYXRlLCB7IHdhaXRVbnRpbDogJ2RvbWNvbnRlbnRsb2FkZWQnIH0pO1xuXG4gIC8vIEFkZCBhbGwgcmVnaXN0ZXJlZCBIaWdjaGFydHMgc2NyaXB0cywgcXVpdGUgZGVtYW5kaW5nXG4gIGF3YWl0IHBhZ2UuYWRkU2NyaXB0VGFnKHsgcGF0aDogYCR7Z2V0Q2FjaGVQYXRoKCl9L3NvdXJjZXMuanNgIH0pO1xuXG4gIC8vIFNldCB0aGUgaW5pdGlhbCBhbmltT2JqZWN0XG4gIGF3YWl0IHBhZ2UuZXZhbHVhdGUoc2V0dXBIaWdoY2hhcnRzKTtcbn1cblxuLyoqXG4gKiBTZXQgZXZlbnRzIGZvciBhIFB1cHBldGVlciBQYWdlLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYWdlIC0gVGhlIFB1cHBldGVlciBQYWdlIG9iamVjdCB0byBzZXQgZXZlbnRzIHRvLlxuICovXG5mdW5jdGlvbiBzZXRQYWdlRXZlbnRzKHBhZ2UpIHtcbiAgLy8gR2V0IGRlYnVnIG9wdGlvbnNcbiAgY29uc3QgeyBkZWJ1ZyB9ID0gZ2V0T3B0aW9ucygpO1xuXG4gIC8vIFNldCB0aGUgY29uc29sZSBsaXN0ZW5lciwgaWYgbmVlZGVkXG4gIGlmIChkZWJ1Zy5lbmFibGUgJiYgZGVidWcubGlzdGVuVG9Db25zb2xlKSB7XG4gICAgcGFnZS5vbignY29uc29sZScsIChtZXNzYWdlKSA9PiB7XG4gICAgICBjb25zb2xlLmxvZyhgW2RlYnVnXSAke21lc3NhZ2UudGV4dCgpfWApO1xuICAgIH0pO1xuICB9XG5cbiAgLy8gU2V0IHRoZSBwYWdlZXJyb3IgbGlzdGVuZXJcbiAgcGFnZS5vbigncGFnZWVycm9yJywgYXN5bmMgKGVycm9yKSA9PiB7XG4gICAgLy8gSXQgd291bGQgc2VlbSBsaWtlIHRoaXMgbWF5IGZpcmUgYXQgdGhlIHNhbWUgdGltZSBvciBzaG9ydGx5IGJlZm9yZVxuICAgIC8vIGEgcGFnZSBpcyBjbG9zZWQuXG4gICAgaWYgKHBhZ2UuaXNDbG9zZWQoKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFRPRE86IENvbnNpZGVyIGFkZGluZyBhIHN3aXRjaCBoZXJlIHRoYXQgdHVybnMgb24gbG9nKDApIGxvZ2dpbmdcbiAgICAvLyBvbiBwYWdlIGVycm9ycy5cbiAgICBhd2FpdCBwYWdlLiRldmFsKFxuICAgICAgJyNjb250YWluZXInLFxuICAgICAgKGVsZW1lbnQsIGVycm9yTWVzc2FnZSkgPT4ge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW5kZWZcbiAgICAgICAgaWYgKHdpbmRvdy5fZGlzcGxheUVycm9ycykge1xuICAgICAgICAgIGVsZW1lbnQuaW5uZXJIVE1MID0gZXJyb3JNZXNzYWdlO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgYDxoMT5DaGFydCBpbnB1dCBkYXRhIGVycm9yOiA8L2gxPiR7ZXJyb3IudG9TdHJpbmcoKX1gXG4gICAgKTtcbiAgfSk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgZ2V0LFxuICBjcmVhdGUsXG4gIGNsb3NlLFxuICBuZXdQYWdlLFxuICBjbGVhclBhZ2UsXG4gIGFkZFBhZ2VSZXNvdXJjZXMsXG4gIGNsZWFyUGFnZVJlc291cmNlc1xufTtcbiIsIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG5cbkhpZ2hjaGFydHMgRXhwb3J0IFNlcnZlclxuXG5Db3B5cmlnaHQgKGMpIDIwMTYtMjAyNCwgSGlnaHNvZnRcblxuTGljZW5jZWQgdW5kZXIgdGhlIE1JVCBsaWNlbmNlLlxuXG5BZGRpdGlvbmFsbHkgYSB2YWxpZCBIaWdoY2hhcnRzIGxpY2Vuc2UgaXMgcmVxdWlyZWQgZm9yIHVzZS5cblxuU2VlIExJQ0VOU0UgZmlsZSBpbiByb290IGZvciBkZXRhaWxzLlxuXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG5pbXBvcnQgeyBhZGRQYWdlUmVzb3VyY2VzLCBjbGVhclBhZ2VSZXNvdXJjZXMgfSBmcm9tICcuL2Jyb3dzZXIuanMnO1xuaW1wb3J0IHsgZ2V0Q2FjaGUgfSBmcm9tICcuL2NhY2hlLmpzJztcbmltcG9ydCB7IHRyaWdnZXJFeHBvcnQgfSBmcm9tICcuL2hpZ2hjaGFydHMuanMnO1xuaW1wb3J0IHsgbG9nIH0gZnJvbSAnLi9sb2dnZXIuanMnO1xuXG5pbXBvcnQgc3ZnVGVtcGxhdGUgZnJvbSAnLi8uLi90ZW1wbGF0ZXMvc3ZnX2V4cG9ydC9zdmdfZXhwb3J0LmpzJztcblxuaW1wb3J0IEV4cG9ydEVycm9yIGZyb20gJy4vZXJyb3JzL0V4cG9ydEVycm9yLmpzJztcblxuLyoqXG4gKiBSZXRyaWV2ZXMgdGhlIGNsaXBwaW5nIHJlZ2lvbiBjb29yZGluYXRlcyBvZiB0aGUgc3BlY2lmaWVkIHBhZ2UgZWxlbWVudCB3aXRoXG4gKiB0aGUgaWQgJ2NoYXJ0LWNvbnRhaW5lcicuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHBhZ2UgLSBQdXBwZXRlZXIgcGFnZSBvYmplY3QuXG4gKlxuICogQHJldHVybnMge1Byb21pc2U8T2JqZWN0Pn0gUHJvbWlzZSByZXNvbHZpbmcgdG8gYW4gb2JqZWN0IGNvbnRhaW5pbmdcbiAqIHgsIHksIHdpZHRoLCBhbmQgaGVpZ2h0IHByb3BlcnRpZXMuXG4gKi9cbmNvbnN0IGdldENsaXBSZWdpb24gPSAocGFnZSkgPT5cbiAgcGFnZS4kZXZhbCgnI2NoYXJ0LWNvbnRhaW5lcicsIChlbGVtZW50KSA9PiB7XG4gICAgY29uc3QgeyB4LCB5LCB3aWR0aCwgaGVpZ2h0IH0gPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIHJldHVybiB7XG4gICAgICB4LFxuICAgICAgeSxcbiAgICAgIHdpZHRoLFxuICAgICAgaGVpZ2h0OiBNYXRoLnRydW5jKGhlaWdodCA+IDEgPyBoZWlnaHQgOiA1MDApXG4gICAgfTtcbiAgfSk7XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBpbWFnZSB1c2luZyBQdXBwZXRlZXIncyBwYWdlIHNjcmVlbnNob3QgZnVuY3Rpb25hbGl0eSB3aXRoXG4gKiBzcGVjaWZpZWQgb3B0aW9ucy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gcGFnZSAtIFB1cHBldGVlciBwYWdlIG9iamVjdC5cbiAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIC0gSW1hZ2UgdHlwZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBlbmNvZGluZyAtIEltYWdlIGVuY29kaW5nLlxuICogQHBhcmFtIHtPYmplY3R9IGNsaXAgLSBDbGlwcGluZyByZWdpb24gY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gcmFzdGVyaXphdGlvblRpbWVvdXQgLSBUaW1lb3V0IGZvciByYXN0ZXJpemF0aW9uXG4gKiBpbiBtaWxsaXNlY29uZHMuXG4gKlxuICogQHJldHVybnMge1Byb21pc2U8QnVmZmVyPn0gUHJvbWlzZSByZXNvbHZpbmcgdG8gdGhlIGltYWdlIGJ1ZmZlciBvciByZWplY3RpbmdcbiAqIHdpdGggYW4gRXhwb3J0RXJyb3IgZm9yIHRpbWVvdXQuXG4gKi9cbmNvbnN0IGNyZWF0ZUltYWdlID0gKHBhZ2UsIHR5cGUsIGVuY29kaW5nLCBjbGlwLCByYXN0ZXJpemF0aW9uVGltZW91dCkgPT5cbiAgUHJvbWlzZS5yYWNlKFtcbiAgICBwYWdlLnNjcmVlbnNob3Qoe1xuICAgICAgdHlwZSxcbiAgICAgIGVuY29kaW5nLFxuICAgICAgY2xpcCxcbiAgICAgIGNhcHR1cmVCZXlvbmRWaWV3cG9ydDogdHJ1ZSxcbiAgICAgIGZ1bGxQYWdlOiBmYWxzZSxcbiAgICAgIG9wdGltaXplRm9yU3BlZWQ6IHRydWUsXG4gICAgICAuLi4odHlwZSAhPT0gJ3BuZycgPyB7IHF1YWxpdHk6IDgwIH0gOiB7fSksXG5cbiAgICAgIC8vICM0NDcsICM0NjMgLSBhbHdheXMgcmVuZGVyIG9uIGEgdHJhbnNwYXJlbnQgcGFnZSBpZiB0aGUgZXhwZWN0ZWQgdHlwZVxuICAgICAgLy8gZm9ybWF0IGlzIFBOR1xuICAgICAgb21pdEJhY2tncm91bmQ6IHR5cGUgPT0gJ3BuZydcbiAgICB9KSxcbiAgICBuZXcgUHJvbWlzZSgoX3Jlc29sdmUsIHJlamVjdCkgPT5cbiAgICAgIHNldFRpbWVvdXQoXG4gICAgICAgICgpID0+IHJlamVjdChuZXcgRXhwb3J0RXJyb3IoJ1Jhc3Rlcml6YXRpb24gdGltZW91dCcpKSxcbiAgICAgICAgcmFzdGVyaXphdGlvblRpbWVvdXQgfHwgMTUwMFxuICAgICAgKVxuICAgIClcbiAgXSk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIFBERiB1c2luZyBQdXBwZXRlZXIncyBwYWdlIHBkZiBmdW5jdGlvbmFsaXR5IHdpdGggc3BlY2lmaWVkXG4gKiBvcHRpb25zLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYWdlIC0gUHVwcGV0ZWVyIHBhZ2Ugb2JqZWN0LlxuICogQHBhcmFtIHtudW1iZXJ9IGhlaWdodCAtIFBERiBoZWlnaHQuXG4gKiBAcGFyYW0ge251bWJlcn0gd2lkdGggLSBQREYgd2lkdGguXG4gKiBAcGFyYW0ge3N0cmluZ30gZW5jb2RpbmcgLSBQREYgZW5jb2RpbmcuXG4gKlxuICogQHJldHVybnMge1Byb21pc2U8QnVmZmVyPn0gUHJvbWlzZSByZXNvbHZpbmcgdG8gdGhlIFBERiBidWZmZXIuXG4gKi9cbmNvbnN0IGNyZWF0ZVBERiA9IGFzeW5jIChcbiAgcGFnZSxcbiAgaGVpZ2h0LFxuICB3aWR0aCxcbiAgZW5jb2RpbmcsXG4gIHJhc3Rlcml6YXRpb25UaW1lb3V0XG4pID0+IHtcbiAgYXdhaXQgcGFnZS5lbXVsYXRlTWVkaWFUeXBlKCdzY3JlZW4nKTtcblxuICByZXR1cm4gcGFnZS5wZGYoe1xuICAgIC8vIFRoaXMgd2lsbCByZW1vdmUgYW4gZXh0cmEgZW1wdHkgcGFnZSBpbiBQREYgZXhwb3J0c1xuICAgIGhlaWdodDogaGVpZ2h0ICsgMSxcbiAgICB3aWR0aCxcbiAgICBlbmNvZGluZyxcbiAgICB0aW1lb3V0OiByYXN0ZXJpemF0aW9uVGltZW91dCB8fCAxNTAwXG4gIH0pO1xufTtcblxuLyoqXG4gKiBDcmVhdGVzIGFuIFNWRyBzdHJpbmcgYnkgZXZhbHVhdGluZyB0aGUgb3V0ZXJIVE1MIG9mIHRoZSBmaXJzdCAnc3ZnJyBlbGVtZW50XG4gKiBpbnNpZGUgYW4gZWxlbWVudCB3aXRoIHRoZSBpZCAnY29udGFpbmVyJy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gcGFnZSAtIFB1cHBldGVlciBwYWdlIG9iamVjdC5cbiAqXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxzdHJpbmc+fSBQcm9taXNlIHJlc29sdmluZyB0byB0aGUgU1ZHIHN0cmluZy5cbiAqL1xuY29uc3QgY3JlYXRlU1ZHID0gKHBhZ2UpID0+XG4gIHBhZ2UuJGV2YWwoJyNjb250YWluZXIgc3ZnOmZpcnN0LW9mLXR5cGUnLCAoZWxlbWVudCkgPT4gZWxlbWVudC5vdXRlckhUTUwpO1xuXG4vKipcbiAqIFNldHMgdGhlIHNwZWNpZmllZCBjaGFydCBhbmQgb3B0aW9ucyBhcyBjb25maWd1cmF0aW9uIGludG8gdGhlIHRyaWdnZXJFeHBvcnRcbiAqIGZ1bmN0aW9uIHdpdGhpbiB0aGUgd2luZG93IGNvbnRleHQgdXNpbmcgcGFnZS5ldmFsdWF0ZS5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gcGFnZSAtIFB1cHBldGVlciBwYWdlIG9iamVjdC5cbiAqIEBwYXJhbSB7YW55fSBjaGFydCAtIFRoZSBjaGFydCBvYmplY3QgdG8gYmUgY29uZmlndXJlZC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gQ29uZmlndXJhdGlvbiBvcHRpb25zIGZvciB0aGUgY2hhcnQuXG4gKlxuICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IFByb21pc2UgcmVzb2x2aW5nIGFmdGVyIHRoZSBjb25maWd1cmF0aW9uIGlzIHNldC5cbiAqL1xuY29uc3Qgc2V0QXNDb25maWcgPSBhc3luYyAocGFnZSwgY2hhcnQsIG9wdGlvbnMsIGRpc3BsYXlFcnJvcnMpID0+IHtcbiAgLy8gR2V0IHJpZCBvZiB0aGUgcmVkdW5hbnQgc3RyaW5nIGRhdGFcbiAgb3B0aW9ucy5leHBvcnQuaW5zdHIgPSBudWxsO1xuICBvcHRpb25zLmV4cG9ydC5pbmZpbGUgPSBudWxsO1xuXG4gIC8vIEdldCB0aGUgc2l6ZSBvZiB0aGUgZXhwb3J0IGlucHV0XG4gIGNvbnN0IHRvdGFsU2l6ZSA9IEJ1ZmZlci5ieXRlTGVuZ3RoKFxuICAgIG9wdGlvbnMuZXhwb3J0Py5zdHJJbmogPyBvcHRpb25zLmV4cG9ydD8uc3RySW5qIDogSlNPTi5zdHJpbmdpZnkoY2hhcnQpLFxuICAgICd1dGYtOCdcbiAgKTtcblxuICAvLyBMb2cgdGhlIHNpemUgaW4gTUJcbiAgbG9nKFxuICAgIDQsXG4gICAgYFtleHBvcnRdIFRoZSBjdXJyZW50IHRvdGFsIHNpemUgb2YgZGF0YSBwYXNzZWQgdG8gYSBwYWdlIGlzIGFyb3VuZCAkeyhcbiAgICAgIHRvdGFsU2l6ZSAvXG4gICAgICAoMTAyNCAqIDEwMjQpXG4gICAgKS50b0ZpeGVkKDIpfSBNQmBcbiAgKTtcblxuICAvLyBDaGVjayB0aGUgc2l6ZSBvZiBkYXRhIHBhc3NlZCB0byB0aGUgcGFnZVxuICBpZiAodG90YWxTaXplID49IDEwMCAqIDEwMjQgKiAxMDI0KSB7XG4gICAgdGhyb3cgbmV3IEV4cG9ydEVycm9yKGBbZXhwb3J0XSBUaGUgZGF0YSBwYXNzZWQgdG8gYSBwYWdlIGV4Y2VlZGVkIDEwME1CLmApO1xuICB9XG5cbiAgLy8gVHJpZ2dlciB0aGUgSGlnaGNoYXJ0cyBjaGFydCBjcmVhdGlvblxuICByZXR1cm4gcGFnZS5ldmFsdWF0ZSh0cmlnZ2VyRXhwb3J0LCBjaGFydCwgb3B0aW9ucywgZGlzcGxheUVycm9ycyk7XG59O1xuXG4vKipcbiAqIEV4cG9ydHMgdG8gYSBjaGFydCBmcm9tIGEgcGFnZSB1c2luZyBQdXBwZXRlZXIuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHBhZ2UgLSBQdXBwZXRlZXIgcGFnZSBvYmplY3QuXG4gKiBAcGFyYW0ge2FueX0gY2hhcnQgLSBUaGUgY2hhcnQgb2JqZWN0IG9yIFNWRyBjb25maWd1cmF0aW9uIHRvIGJlIGV4cG9ydGVkLlxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgLSBFeHBvcnQgb3B0aW9ucyBhbmQgY29uZmlndXJhdGlvbi5cbiAqXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxzdHJpbmcgfCBCdWZmZXIgfCBFeHBvcnRFcnJvcj59IFByb21pc2UgcmVzb2x2aW5nIHRvXG4gKiB0aGUgZXhwb3J0ZWQgZGF0YSBvciByZWplY3Rpbmcgd2l0aCBhbiBFeHBvcnRFcnJvci5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgYXN5bmMgKHBhZ2UsIGNoYXJ0LCBvcHRpb25zKSA9PiB7XG4gIC8vIEluamVjdGVkIHJlc291cmNlcyBhcnJheSAoYWRkaXRpb25hbCBKUyBhbmQgQ1NTKVxuICBsZXQgaW5qZWN0ZWRSZXNvdXJjZXMgPSBbXTtcblxuICB0cnkge1xuICAgIGxvZyg0LCAnW2V4cG9ydF0gRGV0ZXJtaW5pbmcgZXhwb3J0IHBhdGguJyk7XG5cbiAgICBjb25zdCBleHBvcnRPcHRpb25zID0gb3B0aW9ucy5leHBvcnQ7XG5cbiAgICAvLyBEZWNpZGUgd2hldGhlciBkaXNwbGF5IGVycm9yIG9yIGRlYmJ1Z2VyIHdyYXBwZXIgYXJvdW5kIGl0XG4gICAgY29uc3QgZGlzcGxheUVycm9ycyA9XG4gICAgICBleHBvcnRPcHRpb25zPy5vcHRpb25zPy5jaGFydD8uZGlzcGxheUVycm9ycyAmJlxuICAgICAgZ2V0Q2FjaGUoKS5hY3RpdmVNYW5pZmVzdC5tb2R1bGVzLmRlYnVnZ2VyO1xuXG4gICAgbGV0IGlzU1ZHO1xuICAgIGlmIChcbiAgICAgIGNoYXJ0LmluZGV4T2YgJiZcbiAgICAgIChjaGFydC5pbmRleE9mKCc8c3ZnJykgPj0gMCB8fCBjaGFydC5pbmRleE9mKCc8P3htbCcpID49IDApXG4gICAgKSB7XG4gICAgICAvLyBTVkcgaW5wdXQgaGFuZGxpbmdcbiAgICAgIGxvZyg0LCAnW2V4cG9ydF0gVHJlYXRpbmcgYXMgU1ZHLicpO1xuXG4gICAgICAvLyBJZiBpbnB1dCBpcyBhbHNvIFNWRywganVzdCByZXR1cm4gaXRcbiAgICAgIGlmIChleHBvcnRPcHRpb25zLnR5cGUgPT09ICdzdmcnKSB7XG4gICAgICAgIHJldHVybiBjaGFydDtcbiAgICAgIH1cblxuICAgICAgaXNTVkcgPSB0cnVlO1xuICAgICAgYXdhaXQgcGFnZS5zZXRDb250ZW50KHN2Z1RlbXBsYXRlKGNoYXJ0KSwge1xuICAgICAgICB3YWl0VW50aWw6ICdkb21jb250ZW50bG9hZGVkJ1xuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEpTT04gY29uZmlnIGhhbmRsaW5nXG4gICAgICBsb2coNCwgJ1tleHBvcnRdIFRyZWF0aW5nIGFzIGNvbmZpZy4nKTtcblxuICAgICAgLy8gTmVlZCB0byBwZXJmb3JtIHN0cmFpZ2h0IGluamVjdFxuICAgICAgaWYgKGV4cG9ydE9wdGlvbnMuc3RySW5qKSB7XG4gICAgICAgIC8vIEluamVjdGlvbiBiYXNlZCBjb25maWd1cmF0aW9uIGV4cG9ydFxuICAgICAgICBhd2FpdCBzZXRBc0NvbmZpZyhcbiAgICAgICAgICBwYWdlLFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGNoYXJ0OiB7XG4gICAgICAgICAgICAgIGhlaWdodDogZXhwb3J0T3B0aW9ucy5oZWlnaHQsXG4gICAgICAgICAgICAgIHdpZHRoOiBleHBvcnRPcHRpb25zLndpZHRoXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgICBvcHRpb25zLFxuICAgICAgICAgIGRpc3BsYXlFcnJvcnNcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIEJhc2ljIGNvbmZpZ3VyYXRpb24gZXhwb3J0XG4gICAgICAgIGNoYXJ0LmNoYXJ0LmhlaWdodCA9IGV4cG9ydE9wdGlvbnMuaGVpZ2h0O1xuICAgICAgICBjaGFydC5jaGFydC53aWR0aCA9IGV4cG9ydE9wdGlvbnMud2lkdGg7XG5cbiAgICAgICAgYXdhaXQgc2V0QXNDb25maWcocGFnZSwgY2hhcnQsIG9wdGlvbnMsIGRpc3BsYXlFcnJvcnMpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEtlZXBzIHRyYWNrIG9mIGFsbCByZXNvdXJjZXMgYWRkZWQgb24gdGhlIHBhZ2Ugd2l0aCBhZGRYWFhUYWcuIGV0Y1xuICAgIC8vIEl0J3MgVklUQUwgdGhhdCBhbGwgYWRkZWQgcmVzb3VyY2VzIGVuZHMgdXAgaGVyZSBzbyB3ZSBjYW4gY2xlYXIgdGhpbmdzXG4gICAgLy8gb3V0IHdoZW4gZG9pbmcgYSBuZXcgZXhwb3J0IGluIHRoZSBzYW1lIHBhZ2UhXG4gICAgaW5qZWN0ZWRSZXNvdXJjZXMgPSBhd2FpdCBhZGRQYWdlUmVzb3VyY2VzKHBhZ2UsIG9wdGlvbnMpO1xuXG4gICAgLy8gR2V0IHRoZSByZWFsIGNoYXJ0IHNpemUgYW5kIHNldCB0aGUgem9vbSBhY2NvcmRpbmdseVxuICAgIGNvbnN0IHNpemUgPSBpc1NWR1xuICAgICAgPyBhd2FpdCBwYWdlLmV2YWx1YXRlKChzY2FsZSkgPT4ge1xuICAgICAgICAgIGNvbnN0IHN2Z0VsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFxuICAgICAgICAgICAgJyNjaGFydC1jb250YWluZXIgc3ZnOmZpcnN0LW9mLXR5cGUnXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIC8vIEdldCB0aGUgdmFsdWVzIGNvcnJlY3RseSBzY2FsZWRcbiAgICAgICAgICBjb25zdCBjaGFydEhlaWdodCA9IHN2Z0VsZW1lbnQuaGVpZ2h0LmJhc2VWYWwudmFsdWUgKiBzY2FsZTtcbiAgICAgICAgICBjb25zdCBjaGFydFdpZHRoID0gc3ZnRWxlbWVudC53aWR0aC5iYXNlVmFsLnZhbHVlICogc2NhbGU7XG5cbiAgICAgICAgICAvLyBJbiBjYXNlIG9mIFNWRyB0aGUgem9vbSBtdXN0IGJlIHNldCBkaXJlY3RseSBmb3IgYm9keVxuICAgICAgICAgIC8vIFNldCB0aGUgem9vbSBhcyBzY2FsZVxuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bmRlZlxuICAgICAgICAgIGRvY3VtZW50LmJvZHkuc3R5bGUuem9vbSA9IHNjYWxlO1xuXG4gICAgICAgICAgLy8gU2V0IHRoZSBtYXJnaW4gdG8gMHB4XG4gICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVuZGVmXG4gICAgICAgICAgZG9jdW1lbnQuYm9keS5zdHlsZS5tYXJnaW4gPSAnMHB4JztcblxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjaGFydEhlaWdodCxcbiAgICAgICAgICAgIGNoYXJ0V2lkdGhcbiAgICAgICAgICB9O1xuICAgICAgICB9LCBwYXJzZUZsb2F0KGV4cG9ydE9wdGlvbnMuc2NhbGUpKVxuICAgICAgOiBhd2FpdCBwYWdlLmV2YWx1YXRlKCgpID0+IHtcbiAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW5kZWZcbiAgICAgICAgICBjb25zdCB7IGNoYXJ0SGVpZ2h0LCBjaGFydFdpZHRoIH0gPSB3aW5kb3cuSGlnaGNoYXJ0cy5jaGFydHNbMF07XG5cbiAgICAgICAgICAvLyBObyBuZWVkIGZvciBzdWNoIHNjYWxlIG1hbmlwdWxhdGlvbiBpbiBjYXNlIG9mIG90aGVyIHR5cGVzIG9mIGV4cG9ydHNcbiAgICAgICAgICAvLyBSZXNldCB0aGUgem9vbSBmb3Igb3RoZXIgZXhwb3J0cyB0aGFuIHRvIFNWR3NcbiAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW5kZWZcbiAgICAgICAgICBkb2N1bWVudC5ib2R5LnN0eWxlLnpvb20gPSAxO1xuXG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNoYXJ0SGVpZ2h0LFxuICAgICAgICAgICAgY2hhcnRXaWR0aFxuICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuXG4gICAgLy8gU2V0IGZpbmFsIGhlaWdodCBhbmQgd2lkdGggZm9yIHZpZXdwb3J0XG4gICAgY29uc3Qgdmlld3BvcnRIZWlnaHQgPSBNYXRoLmFicyhcbiAgICAgIE1hdGguY2VpbChzaXplLmNoYXJ0SGVpZ2h0IHx8IGV4cG9ydE9wdGlvbnMuaGVpZ2h0KVxuICAgICk7XG4gICAgY29uc3Qgdmlld3BvcnRXaWR0aCA9IE1hdGguYWJzKFxuICAgICAgTWF0aC5jZWlsKHNpemUuY2hhcnRXaWR0aCB8fCBleHBvcnRPcHRpb25zLndpZHRoKVxuICAgICk7XG5cbiAgICAvLyBHZXQgdGhlIGNsaXAgcmVnaW9uIGZvciB0aGUgcGFnZVxuICAgIGNvbnN0IHsgeCwgeSB9ID0gYXdhaXQgZ2V0Q2xpcFJlZ2lvbihwYWdlKTtcblxuICAgIC8vIFNldCB0aGUgZmluYWwgdmlld3BvcnQgbm93IHRoYXQgd2UgaGF2ZSB0aGUgcmVhbCBoZWlnaHRcbiAgICBhd2FpdCBwYWdlLnNldFZpZXdwb3J0KHtcbiAgICAgIGhlaWdodDogdmlld3BvcnRIZWlnaHQsXG4gICAgICB3aWR0aDogdmlld3BvcnRXaWR0aCxcbiAgICAgIGRldmljZVNjYWxlRmFjdG9yOiBpc1NWRyA/IDEgOiBwYXJzZUZsb2F0KGV4cG9ydE9wdGlvbnMuc2NhbGUpXG4gICAgfSk7XG5cbiAgICBsZXQgZGF0YTtcbiAgICAvLyBSYXN0ZXJpemF0aW9uIHByb2Nlc3NcbiAgICBpZiAoZXhwb3J0T3B0aW9ucy50eXBlID09PSAnc3ZnJykge1xuICAgICAgLy8gU1ZHXG4gICAgICBkYXRhID0gYXdhaXQgY3JlYXRlU1ZHKHBhZ2UpO1xuICAgIH0gZWxzZSBpZiAoWydwbmcnLCAnanBlZyddLmluY2x1ZGVzKGV4cG9ydE9wdGlvbnMudHlwZSkpIHtcbiAgICAgIC8vIFBORyBvciBKUEVHXG4gICAgICBkYXRhID0gYXdhaXQgY3JlYXRlSW1hZ2UoXG4gICAgICAgIHBhZ2UsXG4gICAgICAgIGV4cG9ydE9wdGlvbnMudHlwZSxcbiAgICAgICAgJ2Jhc2U2NCcsXG4gICAgICAgIHtcbiAgICAgICAgICB3aWR0aDogdmlld3BvcnRXaWR0aCxcbiAgICAgICAgICBoZWlnaHQ6IHZpZXdwb3J0SGVpZ2h0LFxuICAgICAgICAgIHgsXG4gICAgICAgICAgeVxuICAgICAgICB9LFxuICAgICAgICBleHBvcnRPcHRpb25zLnJhc3Rlcml6YXRpb25UaW1lb3V0XG4gICAgICApO1xuICAgIH0gZWxzZSBpZiAoZXhwb3J0T3B0aW9ucy50eXBlID09PSAncGRmJykge1xuICAgICAgLy8gUERGXG4gICAgICBkYXRhID0gYXdhaXQgY3JlYXRlUERGKFxuICAgICAgICBwYWdlLFxuICAgICAgICB2aWV3cG9ydEhlaWdodCxcbiAgICAgICAgdmlld3BvcnRXaWR0aCxcbiAgICAgICAgJ2Jhc2U2NCcsXG4gICAgICAgIGV4cG9ydE9wdGlvbnMucmFzdGVyaXphdGlvblRpbWVvdXRcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFeHBvcnRFcnJvcihcbiAgICAgICAgYFtleHBvcnRdIFVuc3VwcG9ydGVkIG91dHB1dCBmb3JtYXQgJHtleHBvcnRPcHRpb25zLnR5cGV9LmBcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gQ2xlYXIgcHJldmlvdXNseSBpbmplY3RlZCBKUyBhbmQgQ1NTIHJlc291cmNlc1xuICAgIGF3YWl0IGNsZWFyUGFnZVJlc291cmNlcyhwYWdlLCBpbmplY3RlZFJlc291cmNlcyk7XG4gICAgcmV0dXJuIGRhdGE7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgYXdhaXQgY2xlYXJQYWdlUmVzb3VyY2VzKHBhZ2UsIGluamVjdGVkUmVzb3VyY2VzKTtcbiAgICByZXR1cm4gZXJyb3I7XG4gIH1cbn07XG4iLCIvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuXG5IaWdoY2hhcnRzIEV4cG9ydCBTZXJ2ZXJcblxuQ29weXJpZ2h0IChjKSAyMDE2LTIwMjQsIEhpZ2hzb2Z0XG5cbkxpY2VuY2VkIHVuZGVyIHRoZSBNSVQgbGljZW5jZS5cblxuQWRkaXRpb25hbGx5IGEgdmFsaWQgSGlnaGNoYXJ0cyBsaWNlbnNlIGlzIHJlcXVpcmVkIGZvciB1c2UuXG5cblNlZSBMSUNFTlNFIGZpbGUgaW4gcm9vdCBmb3IgZGV0YWlscy5cblxuKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuaW1wb3J0IGNzc1RlbXBsYXRlIGZyb20gJy4vY3NzLmpzJztcblxuZXhwb3J0IGRlZmF1bHQgKGNoYXJ0KSA9PiBgXG48IURPQ1RZUEUgaHRtbD5cbjxodG1sIGxhbmc9J2VuLVVTJz5cbiAgPGhlYWQ+XG4gICAgPG1ldGEgaHR0cC1lcXVpdj1cIkNvbnRlbnQtVHlwZVwiIGNvbnRlbnQ9XCJ0ZXh0L2h0bWw7IGNoYXJzZXQ9dXRmLThcIj5cbiAgICA8dGl0bGU+SGlnaGNoYXJ0cyBFeHBvcnQ8L3RpdGxlPlxuICA8L2hlYWQ+XG4gIDxzdHlsZT5cbiAgICAke2Nzc1RlbXBsYXRlKCl9XG4gIDwvc3R5bGU+XG4gIDxib2R5PlxuICAgIDxkaXYgaWQ9XCJjaGFydC1jb250YWluZXJcIj5cbiAgICAgICR7Y2hhcnR9XG4gICAgPC9kaXY+XG4gIDwvYm9keT5cbjwvaHRtbD5cblxuYDtcbiIsIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG5cbkhpZ2hjaGFydHMgRXhwb3J0IFNlcnZlclxuXG5Db3B5cmlnaHQgKGMpIDIwMTYtMjAyNCwgSGlnaHNvZnRcblxuTGljZW5jZWQgdW5kZXIgdGhlIE1JVCBsaWNlbmNlLlxuXG5BZGRpdGlvbmFsbHkgYSB2YWxpZCBIaWdoY2hhcnRzIGxpY2Vuc2UgaXMgcmVxdWlyZWQgZm9yIHVzZS5cblxuU2VlIExJQ0VOU0UgZmlsZSBpbiByb290IGZvciBkZXRhaWxzLlxuXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG5pbXBvcnQgeyBQb29sIH0gZnJvbSAndGFybic7XG5pbXBvcnQgeyB2NCBhcyB1dWlkIH0gZnJvbSAndXVpZCc7XG5cbmltcG9ydCB7XG4gIGNyZWF0ZSBhcyBjcmVhdGVCcm93c2VyLFxuICBjbG9zZSBhcyBjbG9zZUJyb3dzZXIsXG4gIG5ld1BhZ2UsXG4gIGNsZWFyUGFnZVxufSBmcm9tICcuL2Jyb3dzZXIuanMnO1xuaW1wb3J0IHB1cHBldGVlckV4cG9ydCBmcm9tICcuL2V4cG9ydC5qcyc7XG5pbXBvcnQgeyBsb2csIGxvZ1dpdGhTdGFjayB9IGZyb20gJy4vbG9nZ2VyLmpzJztcbmltcG9ydCB7IG1lYXN1cmVUaW1lIH0gZnJvbSAnLi91dGlscy5qcyc7XG5cbmltcG9ydCBFeHBvcnRFcnJvciBmcm9tICcuL2Vycm9ycy9FeHBvcnRFcnJvci5qcyc7XG5cbi8vIFRoZSBwb29sIGluc3RhbmNlXG5sZXQgcG9vbCA9IGZhbHNlO1xuXG4vLyBQb29sIHN0YXRpc3RpY3NcbmV4cG9ydCBjb25zdCBzdGF0cyA9IHtcbiAgcGVyZm9ybWVkRXhwb3J0czogMCxcbiAgZXhwb3J0QXR0ZW1wdHM6IDAsXG4gIGV4cG9ydEZyb21TdmdBdHRlbXB0czogMCxcbiAgdGltZVNwZW50OiAwLFxuICBkcm9wcGVkRXhwb3J0czogMCxcbiAgc3BlbnRBdmVyYWdlOiAwXG59O1xuXG5sZXQgcG9vbENvbmZpZyA9IHt9O1xuXG5jb25zdCBmYWN0b3J5ID0ge1xuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyB3b3JrZXIgcGFnZSBmb3IgdGhlIGV4cG9ydCBwb29sLlxuICAgKlxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSAtIEFuIG9iamVjdCBjb250YWluaW5nIHRoZSB3b3JrZXIgSUQsIGEgcmVmZXJlbmNlIHRvIHRoZVxuICAgKiBicm93c2VyIHBhZ2UsIGFuZCBpbml0aWFsIHdvcmsgY291bnQuXG4gICAqXG4gICAqIEB0aHJvd3Mge0V4cG9ydEVycm9yfSAtIElmIHRoZXJlJ3MgYW4gZXJyb3IgZHVyaW5nIHRoZSBjcmVhdGlvbiBvZiB0aGUgbmV3XG4gICAqIHBhZ2UuXG4gICAqL1xuICBjcmVhdGU6IGFzeW5jICgpID0+IHtcbiAgICBsZXQgcGFnZSA9IGZhbHNlO1xuXG4gICAgY29uc3QgaWQgPSB1dWlkKCk7XG4gICAgY29uc3Qgc3RhcnREYXRlID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG5cbiAgICB0cnkge1xuICAgICAgcGFnZSA9IGF3YWl0IG5ld1BhZ2UoKTtcblxuICAgICAgaWYgKCFwYWdlIHx8IHBhZ2UuaXNDbG9zZWQoKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXhwb3J0RXJyb3IoJ1RoZSBwYWdlIGlzIGludmFsaWQgb3IgY2xvc2VkLicpO1xuICAgICAgfVxuXG4gICAgICBsb2coXG4gICAgICAgIDMsXG4gICAgICAgIGBbcG9vbF0gU3VjY2Vzc2Z1bGx5IGNyZWF0ZWQgYSB3b3JrZXIgJHtpZH0gLSB0b29rICR7XG4gICAgICAgICAgbmV3IERhdGUoKS5nZXRUaW1lKCkgLSBzdGFydERhdGVcbiAgICAgICAgfSBtcy5gXG4gICAgICApO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aHJvdyBuZXcgRXhwb3J0RXJyb3IoXG4gICAgICAgICdFcnJvciBlbmNvdW50ZXJlZCB3aGVuIGNyZWF0aW5nIGEgbmV3IHBhZ2UuJ1xuICAgICAgKS5zZXRFcnJvcihlcnJvcik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGlkLFxuICAgICAgcGFnZSxcbiAgICAgIC8vIFRyeSB0byBkaXN0cmlidXRlIHRoZSBpbml0aWFsIHdvcmsgY291bnRcbiAgICAgIHdvcmtDb3VudDogTWF0aC5yb3VuZChNYXRoLnJhbmRvbSgpICogKHBvb2xDb25maWcud29ya0xpbWl0IC8gMikpXG4gICAgfTtcbiAgfSxcblxuICAvKipcbiAgICogVmFsaWRhdGVzIGEgd29ya2VyIHBhZ2UgaW4gdGhlIGV4cG9ydCBwb29sLCBjaGVja2luZyBpZiBpdCBoYXMgZXhjZWVkZWRcbiAgICogdGhlIHdvcmsgbGltaXQuXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSB3b3JrZXJIYW5kbGUgLSBUaGUgaGFuZGxlIHRvIHRoZSB3b3JrZXIsIGNvbnRhaW5pbmcgdGhlXG4gICAqIHdvcmtlcidzIElELCBhIHJlZmVyZW5jZSB0byB0aGUgYnJvd3NlciBwYWdlLCBhbmQgd29yayBjb3VudC5cbiAgICpcbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gUmV0dXJucyB0cnVlIGlmIHRoZSB3b3JrZXIgaXMgdmFsaWQgYW5kIHdpdGhpblxuICAgKiB0aGUgd29yayBsaW1pdDsgb3RoZXJ3aXNlLCByZXR1cm5zIGZhbHNlLlxuICAgKi9cbiAgdmFsaWRhdGU6IGFzeW5jICh3b3JrZXJIYW5kbGUpID0+IHtcbiAgICAvLyBOT1RFOiBJbiBjZXJ0YWluIGNhc2VzIGFjcXVpcmluZyB0aHJvd3MgYSBUYXJnZXRDbG9zZUVycm9yLCB3aGljaCBtYXlcbiAgICAvLyAgICAgICBiZSBjYXVzZWQgYnkgdHdvIHRoaW5nczpcbiAgICAvLyAgICAgICAgIC0gVGhlIHBhZ2UgaXMgY2xvc2VkIGFuZCBhdHRlbXB0ZWQgdG8gYmUgcmV1c2VkLlxuICAgIC8vICAgICAgICAgLSBMb3N0IGNvbnRhY3Qgd2l0aCB0aGUgYnJvd3NlclxuICAgIC8vICAgICAgIFdoYXQgd2UncmUgc2VlaW5nIGluIGxvZ3MgaXMgdGhhdCBzdWNjZXNzaXZlIGV4cG9ydHMgdHlwaWNhbGx5XG4gICAgLy8gICAgICAgc3VjY2VlZHMsIGFuZCB0aGUgc2VydmVyIHJlY292ZXJzLCBpbmRpY2F0aW5nIHRoYXQgaXQncyBsaWtlbHlcbiAgICAvLyAgICAgICB0aGUgZmlyc3QgY2FzZS4gVGhpcyBpcyBhbiBhdHRlbXB0IGF0IGFsbGlldmF0aW5nIHRoZSBpc3N1ZSBieVxuICAgIC8vICAgICAgIHNpbXBseSBub3QgdmFsaWRhdGluZyB0aGUgd29ya2VyIGlmIHRoZSBwYWdlIGlzIG51bGwgb3IgY2xvc2VkLlxuICAgIC8vXG4gICAgLy8gICAgICAgVGhlIGFjdHVhbCByZXN1bHQgZnJvbSB3aGVuIHRoaXMgaGFwcGVuZWQsIHdhcyB0aGF0IGEgd29ya2VyIHdvdWxkXG4gICAgLy8gICAgICAgYmUgY29tcGxldGVseSBsb2NrZWQsIHN0b3BwaW5nIGl0IGZyb20gYmVpbmcgYWNxdWlyZWQgdW50aWxcbiAgICAvLyAgICAgICBpdHMgd29yayBjb3VudCByZWFjaGVkIHRoZSBsaW1pdC5cbiAgICBpZiAoIXdvcmtlckhhbmRsZS5wYWdlIHx8IHdvcmtlckhhbmRsZS5wYWdlPy5pc0Nsb3NlZCgpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgcG9vbENvbmZpZy53b3JrTGltaXQgJiZcbiAgICAgICsrd29ya2VySGFuZGxlLndvcmtDb3VudCA+IHBvb2xDb25maWcud29ya0xpbWl0XG4gICAgKSB7XG4gICAgICBsb2coXG4gICAgICAgIDMsXG4gICAgICAgIGBbcG9vbF0gV29ya2VyIGZhaWxlZCB2YWxpZGF0aW9uOiBleGNlZWRlZCB3b3JrIGxpbWl0IChsaW1pdCBpcyAke3Bvb2xDb25maWcud29ya0xpbWl0fSkuYFxuICAgICAgKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH0sXG5cbiAgLyoqXG4gICAqIERlc3Ryb3lzIGEgd29ya2VyIGVudHJ5IGluIHRoZSBleHBvcnQgcG9vbCwgY2xvc2luZyBpdHMgYXNzb2NpYXRlZCBwYWdlLlxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gd29ya2VySGFuZGxlIC0gVGhlIGhhbmRsZSB0byB0aGUgd29ya2VyLCBjb250YWluaW5nXG4gICAqIHRoZSB3b3JrZXIncyBJRCBhbmQgYSByZWZlcmVuY2UgdG8gdGhlIGJyb3dzZXIgcGFnZS5cbiAgICovXG4gIGRlc3Ryb3k6IGFzeW5jICh3b3JrZXJIYW5kbGUpID0+IHtcbiAgICBsb2coMywgYFtwb29sXSBEZXN0cm95aW5nIHBvb2wgZW50cnkgJHt3b3JrZXJIYW5kbGUuaWR9LmApO1xuXG4gICAgaWYgKHdvcmtlckhhbmRsZS5wYWdlICYmICF3b3JrZXJIYW5kbGUucGFnZS5pc0Nsb3NlZCgpKSB7XG4gICAgICBhd2FpdCB3b3JrZXJIYW5kbGUucGFnZS5jbG9zZSgpO1xuICAgIH1cbiAgfVxuXG4gIC8vIGxvZzogKG1lc3NhZ2UsIGxldmVsKSA9PiBsb2coMSwgJ1t0YXJuXSAnICsgIG1lc3NhZ2UpXG59O1xuXG4vKipcbiAqIEluaXRpYWxpemVzIHRoZSBleHBvcnQgcG9vbCB3aXRoIHRoZSBwcm92aWRlZCBjb25maWd1cmF0aW9uLCBjcmVhdGluZ1xuICogYSBicm93c2VyIGluc3RhbmNlIGFuZCBzZXR0aW5nIHVwIHdvcmtlciByZXNvdXJjZXMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZyAtIENvbmZpZ3VyYXRpb24gb3B0aW9ucyBmb3IgdGhlIGV4cG9ydCBwb29sIGFsb25nXG4gKiB3aXRoIGN1c3RvbSBwdXBwZXRlZXIgYXJndW1lbnRzIGZvciB0aGUgcHVwcGV0ZWVyLmxhdW5jaCBmdW5jdGlvbi5cbiAqL1xuZXhwb3J0IGNvbnN0IGluaXRQb29sID0gYXN5bmMgKGNvbmZpZykgPT4ge1xuICAvLyBGb3IgdGhlIG1vZHVsZSBzY29wZSB1c2FnZVxuICBwb29sQ29uZmlnID0gY29uZmlnICYmIGNvbmZpZy5wb29sID8geyAuLi5jb25maWcucG9vbCB9IDoge307XG5cbiAgLy8gQ3JlYXRlIGEgYnJvd3NlciBpbnN0YW5jZSB3aXRoIHRoZSBwdXBwZXRlZXIgYXJndW1lbnRzXG4gIGF3YWl0IGNyZWF0ZUJyb3dzZXIoY29uZmlnLnB1cHBldGVlckFyZ3MpO1xuXG4gIGxvZyhcbiAgICAzLFxuICAgIGBbcG9vbF0gSW5pdGlhbGl6aW5nIHBvb2wgd2l0aCB3b3JrZXJzOiBtaW4gJHtwb29sQ29uZmlnLm1pbldvcmtlcnN9LCBtYXggJHtwb29sQ29uZmlnLm1heFdvcmtlcnN9LmBcbiAgKTtcblxuICBpZiAocG9vbCkge1xuICAgIHJldHVybiBsb2coXG4gICAgICA0LFxuICAgICAgJ1twb29sXSBBbHJlYWR5IGluaXRpYWxpemVkLCBwbGVhc2Uga2lsbCBpdCBiZWZvcmUgY3JlYXRpbmcgYSBuZXcgb25lLidcbiAgICApO1xuICB9XG5cbiAgaWYgKHBhcnNlSW50KHBvb2xDb25maWcubWluV29ya2VycykgPiBwYXJzZUludChwb29sQ29uZmlnLm1heFdvcmtlcnMpKSB7XG4gICAgcG9vbENvbmZpZy5taW5Xb3JrZXJzID0gcG9vbENvbmZpZy5tYXhXb3JrZXJzO1xuICB9XG5cbiAgdHJ5IHtcbiAgICAvLyBDcmVhdGUgYSBwb29sIGFsb25nIHdpdGggYSBtaW5pbWFsIG51bWJlciBvZiByZXNvdXJjZXNcbiAgICBwb29sID0gbmV3IFBvb2woe1xuICAgICAgLy8gR2V0IHRoZSBjcmVhdGUvdmFsaWRhdGUvZGVzdHJveS9sb2cgZnVuY3Rpb25zXG4gICAgICAuLi5mYWN0b3J5LFxuICAgICAgbWluOiBwYXJzZUludChwb29sQ29uZmlnLm1pbldvcmtlcnMpLFxuICAgICAgbWF4OiBwYXJzZUludChwb29sQ29uZmlnLm1heFdvcmtlcnMpLFxuICAgICAgYWNxdWlyZVRpbWVvdXRNaWxsaXM6IHBvb2xDb25maWcuYWNxdWlyZVRpbWVvdXQsXG4gICAgICBjcmVhdGVUaW1lb3V0TWlsbGlzOiBwb29sQ29uZmlnLmNyZWF0ZVRpbWVvdXQsXG4gICAgICBkZXN0cm95VGltZW91dE1pbGxpczogcG9vbENvbmZpZy5kZXN0cm95VGltZW91dCxcbiAgICAgIGlkbGVUaW1lb3V0TWlsbGlzOiBwb29sQ29uZmlnLmlkbGVUaW1lb3V0LFxuICAgICAgY3JlYXRlUmV0cnlJbnRlcnZhbE1pbGxpczogcG9vbENvbmZpZy5jcmVhdGVSZXRyeUludGVydmFsLFxuICAgICAgcmVhcEludGVydmFsTWlsbGlzOiBwb29sQ29uZmlnLnJlYXBlckludGVydmFsLFxuICAgICAgcHJvcGFnYXRlQ3JlYXRlRXJyb3I6IGZhbHNlXG4gICAgfSk7XG5cbiAgICAvLyBTZXQgZXZlbnRzXG4gICAgcG9vbC5vbigncmVsZWFzZScsIGFzeW5jIChyZXNvdXJjZSkgPT4ge1xuICAgICAgLy8gQ2xlYXIgcGFnZVxuICAgICAgY29uc3QgciA9IGF3YWl0IGNsZWFyUGFnZShyZXNvdXJjZS5wYWdlLCBmYWxzZSk7XG4gICAgICBsb2coXG4gICAgICAgIDQsXG4gICAgICAgIGBbcG9vbF0gUmVsZWFzaW5nIGEgd29ya2VyIHdpdGggSUQgJHtyZXNvdXJjZS5pZH0uIENsZWFyIHBhZ2Ugc3RhdHVzOiAke3J9LmBcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBwb29sLm9uKCdkZXN0cm95U3VjY2VzcycsIChldmVudElkLCByZXNvdXJjZSkgPT4ge1xuICAgICAgbG9nKDQsIGBbcG9vbF0gRGVzdHJveWVkIGEgd29ya2VyIHdpdGggSUQgJHtyZXNvdXJjZS5pZH0uYCk7XG4gICAgICByZXNvdXJjZS5wYWdlID0gbnVsbDtcbiAgICB9KTtcblxuICAgIGNvbnN0IGluaXRpYWxSZXNvdXJjZXMgPSBbXTtcbiAgICAvLyBDcmVhdGUgYW4gaW5pdGlhbCBudW1iZXIgb2YgcmVzb3VyY2VzXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwb29sQ29uZmlnLm1pbldvcmtlcnM7IGkrKykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVzb3VyY2UgPSBhd2FpdCBwb29sLmFjcXVpcmUoKS5wcm9taXNlO1xuICAgICAgICBpbml0aWFsUmVzb3VyY2VzLnB1c2gocmVzb3VyY2UpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgbG9nV2l0aFN0YWNrKDIsIGVycm9yLCAnW3Bvb2xdIENvdWxkIG5vdCBjcmVhdGUgYW4gaW5pdGlhbCByZXNvdXJjZS4nKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBSZWxlYXNlIHRoZSBpbml0aWFsIG51bWJlciBvZiByZXNvdXJjZXMgYmFjayB0byB0aGUgcG9vbFxuICAgIGluaXRpYWxSZXNvdXJjZXMuZm9yRWFjaCgocmVzb3VyY2UpID0+IHtcbiAgICAgIHBvb2wucmVsZWFzZShyZXNvdXJjZSk7XG4gICAgfSk7XG5cbiAgICBsb2coXG4gICAgICAzLFxuICAgICAgYFtwb29sXSBUaGUgcG9vbCBpcyByZWFkeSR7aW5pdGlhbFJlc291cmNlcy5sZW5ndGggPyBgIHdpdGggJHtpbml0aWFsUmVzb3VyY2VzLmxlbmd0aH0gaW5pdGlhbCByZXNvdXJjZXMgd2FpdGluZy5gIDogJy4nfWBcbiAgICApO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHRocm93IG5ldyBFeHBvcnRFcnJvcihcbiAgICAgICdbcG9vbF0gQ291bGQgbm90IGNyZWF0ZSB0aGUgcG9vbCBvZiB3b3JrZXJzLidcbiAgICApLnNldEVycm9yKGVycm9yKTtcbiAgfVxufTtcblxuLyoqXG4gKiBLaWxscyBhbGwgd29ya2VycyBpbiB0aGUgcG9vbCwgZGVzdHJveXMgdGhlIHBvb2wsIGFuZCBjbG9zZXMgdGhlIGJyb3dzZXJcbiAqIGluc3RhbmNlLlxuICpcbiAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyBhZnRlciB0aGUgd29ya2VycyBhcmVcbiAqIGtpbGxlZCwgdGhlIHBvb2wgaXMgZGVzdHJveWVkLCBhbmQgdGhlIGJyb3dzZXIgaXMgY2xvc2VkLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24ga2lsbFBvb2woKSB7XG4gIGxvZygzLCAnW3Bvb2xdIEtpbGxpbmcgcG9vbCB3aXRoIGFsbCB3b3JrZXJzIGFuZCBjbG9zaW5nIGJyb3dzZXIuJyk7XG5cbiAgLy8gSWYgc3RpbGwgYWxpdmUsIGRlc3Ryb3kgdGhlIHBvb2wgb2YgcGFnZXMgYmVmb3JlIGNsb3NpbmcgYSBicm93c2VyXG4gIGlmIChwb29sKSB7XG4gICAgLy8gRnJlZSB1cCBub3QgcmVsZWFzZWQgd29ya2Vyc1xuICAgIGZvciAoY29uc3Qgd29ya2VyIG9mIHBvb2wudXNlZCkge1xuICAgICAgcG9vbC5yZWxlYXNlKHdvcmtlci5yZXNvdXJjZSk7XG4gICAgfVxuXG4gICAgLy8gRGVzdHJveSB0aGUgcG9vbCBpZiBpdCBpcyBzdGlsbCBhdmFpbGFibGVcbiAgICBpZiAoIXBvb2wuZGVzdHJveWVkKSB7XG4gICAgICBhd2FpdCBwb29sLmRlc3Ryb3koKTtcbiAgICAgIGxvZyg0LCAnW2Jyb3dzZXJdIERlc3Ryb3llZCB0aGUgcG9vbCBvZiByZXNvdXJjZXMuJyk7XG4gICAgfVxuICB9XG5cbiAgLy8gQ2xvc2UgdGhlIGJyb3dzZXIgaW5zdGFuY2VcbiAgYXdhaXQgY2xvc2VCcm93c2VyKCk7XG59XG5cbi8qKlxuICogUHJvY2Vzc2VzIHRoZSBleHBvcnQgd29yayB1c2luZyBhIHdvcmtlciBmcm9tIHRoZSBwb29sLiBBY3F1aXJlcyBhIHdvcmtlclxuICogaGFuZGxlIGZyb20gdGhlIHBvb2wsIHBlcmZvcm1zIHRoZSBleHBvcnQgdXNpbmcgcHVwcGV0ZWVyLCBhbmQgcmVsZWFzZXNcbiAqIHRoZSB3b3JrZXIgaGFuZGxlIGJhY2sgdG8gdGhlIHBvb2wuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGNoYXJ0IC0gVGhlIGNoYXJ0IGRhdGEgb3IgY29uZmlndXJhdGlvbiB0byBiZSBleHBvcnRlZC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gRXhwb3J0IG9wdGlvbnMgYW5kIGNvbmZpZ3VyYXRpb24uXG4gKlxuICogQHJldHVybnMge1Byb21pc2U8T2JqZWN0Pn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2l0aCB0aGUgZXhwb3J0IHJlc3VsdGFuZFxuICogb3B0aW9ucy5cbiAqXG4gKiBAdGhyb3dzIHtFeHBvcnRFcnJvcn0gSWYgYW4gZXJyb3Igb2NjdXJzIGR1cmluZyB0aGUgZXhwb3J0IHByb2Nlc3MuXG4gKi9cbmV4cG9ydCBjb25zdCBwb3N0V29yayA9IGFzeW5jIChjaGFydCwgb3B0aW9ucykgPT4ge1xuICBsZXQgd29ya2VySGFuZGxlO1xuXG4gIHRyeSB7XG4gICAgbG9nKDQsICdbcG9vbF0gV29yayByZWNlaXZlZCwgc3RhcnRpbmcgdG8gcHJvY2Vzcy4nKTtcblxuICAgICsrc3RhdHMuZXhwb3J0QXR0ZW1wdHM7XG4gICAgaWYgKHBvb2xDb25maWcuYmVuY2htYXJraW5nKSB7XG4gICAgICBnZXRQb29sSW5mbygpO1xuICAgIH1cblxuICAgIGlmICghcG9vbCkge1xuICAgICAgdGhyb3cgbmV3IEV4cG9ydEVycm9yKCdXb3JrIHJlY2VpdmVkLCBidXQgcG9vbCBoYXMgbm90IGJlZW4gc3RhcnRlZC4nKTtcbiAgICB9XG5cbiAgICAvLyBBY3F1aXJlIHRoZSB3b3JrZXIgYWxvbmcgd2l0aCB0aGUgaWQgb2YgcmVzb3VyY2UgYW5kIHdvcmsgY291bnRcbiAgICBjb25zdCBhY3F1aXJlQ291bnRlciA9IG1lYXN1cmVUaW1lKCk7XG4gICAgdHJ5IHtcbiAgICAgIGxvZyg0LCAnW3Bvb2xdIEFjcXVpcmluZyBhIHdvcmtlciBoYW5kbGUuJyk7XG4gICAgICB3b3JrZXJIYW5kbGUgPSBhd2FpdCBwb29sLmFjcXVpcmUoKS5wcm9taXNlO1xuXG4gICAgICAvLyBDaGVjayB0aGUgcGFnZSBhY3F1aXJlIHRpbWVcbiAgICAgIGlmIChvcHRpb25zLnNlcnZlci5iZW5jaG1hcmtpbmcpIHtcbiAgICAgICAgbG9nKFxuICAgICAgICAgIDUsXG4gICAgICAgICAgb3B0aW9ucy5wYXlsb2FkPy5yZXF1ZXN0SWRcbiAgICAgICAgICAgID8gYFtiZW5jaG1hcmtdIFJlcXVlc3Qgd2l0aCBJRCAke29wdGlvbnMucGF5bG9hZD8ucmVxdWVzdElkfSAtYFxuICAgICAgICAgICAgOiAnW2JlbmNobWFya10nLFxuICAgICAgICAgIGBBY3F1aXJlZCBhIHdvcmtlciBoYW5kbGU6ICR7YWNxdWlyZUNvdW50ZXIoKX1tcy5gXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRocm93IG5ldyBFeHBvcnRFcnJvcihcbiAgICAgICAgKG9wdGlvbnMucGF5bG9hZD8ucmVxdWVzdElkXG4gICAgICAgICAgPyBgRm9yIHJlcXVlc3Qgd2l0aCBJRCAke29wdGlvbnMucGF5bG9hZD8ucmVxdWVzdElkfSAtIGBcbiAgICAgICAgICA6ICcnKSArXG4gICAgICAgICAgYEVycm9yIGVuY291bnRlcmVkIHdoZW4gYWNxdWlyaW5nIGFuIGF2YWlsYWJsZSBlbnRyeTogJHthY3F1aXJlQ291bnRlcigpfW1zLmBcbiAgICAgICkuc2V0RXJyb3IoZXJyb3IpO1xuICAgIH1cbiAgICBsb2coNCwgJ1twb29sXSBBY3F1aXJlZCBhIHdvcmtlciBoYW5kbGUuJyk7XG5cbiAgICBpZiAoIXdvcmtlckhhbmRsZS5wYWdlKSB7XG4gICAgICB0aHJvdyBuZXcgRXhwb3J0RXJyb3IoXG4gICAgICAgICdSZXNvbHZlZCB3b3JrZXIgcGFnZSBpcyBpbnZhbGlkOiB0aGUgcG9vbCBzZXR1cCBpcyB3b25reS4nXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIFNhdmUgdGhlIHN0YXJ0IHRpbWVcbiAgICBsZXQgd29ya1N0YXJ0ID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG5cbiAgICBsb2coNCwgYFtwb29sXSBTdGFydGluZyB3b3JrIG9uIHBvb2wgZW50cnkgd2l0aCBJRCAke3dvcmtlckhhbmRsZS5pZH0uYCk7XG5cbiAgICAvLyBQZXJmb3JtIGFuIGV4cG9ydCBvbiBhIHB1cHBldGVlciBsZXZlbFxuICAgIGNvbnN0IGV4cG9ydENvdW50ZXIgPSBtZWFzdXJlVGltZSgpO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHB1cHBldGVlckV4cG9ydCh3b3JrZXJIYW5kbGUucGFnZSwgY2hhcnQsIG9wdGlvbnMpO1xuXG4gICAgLy8gQ2hlY2sgaWYgaXQncyBhbiBlcnJvclxuICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgLy8gTk9URTogSWYgdGhlcmUncyBhIHJhc3Rlcml6YXRpb24gdGltZW91dCwgd2Ugd2FudCBuZWVkIHRvIGZsdXNoIHRoZSBwYWdlLlxuICAgICAgLy8gICAgICAgVGhpcyBpcyBiZWNhdXNlIHRoZSBwYWdlIG1heSBiZSBpbiBhIHN0YXRlIHdoZXJlIGl0J3Mgd2FpdGluZyBmb3JcbiAgICAgIC8vICAgICAgIHRoZSBzY3JlZW5zaG90IHRvIGZpbmlzaCBldmVuIHRob3VnaCB0aGUgdGltZW91dCBoYXMgb2NjdXJlZC5cbiAgICAgIC8vICAgICAgIFdoaWNoIG9mIGNvdXJzZSBjYXVzZXMgYSBsb3Qgb2YgaXNzdWVzIHdpdGggdGhlIGV2ZW50IHN5c3RlbSxcbiAgICAgIC8vICAgICAgIGFuZCBwYWdlIGNvbnNpc3RlbmN5LlxuICAgICAgLy9cbiAgICAgIC8vIE5PVEU6IE9ubHkgcGFnZS5zY3JlZW5zaG90IHdpbGwgdGhyb3cgdGhpcywgdGltZW91dHMgZm9yIFBERidzIGFyZVxuICAgICAgLy8gICAgICAgaGFuZGxlZCBieSB0aGUgcGFnZS5wZGYgZnVuY3Rpb24gaXRzZWxmLlxuICAgICAgLy9cbiAgICAgIC8vICAgICAgIC4uLnllcywgdGhpcyBpcyB1Z2x5LlxuICAgICAgaWYgKHJlc3VsdC5tZXNzYWdlID09PSAnUmFzdGVyaXphdGlvbiB0aW1lb3V0Jykge1xuICAgICAgICB3b3JrZXJIYW5kbGUud29ya0NvdW50ID0gcG9vbENvbmZpZy53b3JrTGltaXQgKyAxO1xuICAgICAgICB3b3JrZXJIYW5kbGUucGFnZSA9IG51bGw7XG4gICAgICB9XG5cbiAgICAgIGlmIChcbiAgICAgICAgcmVzdWx0Lm5hbWUgPT09ICdUaW1lb3V0RXJyb3InIHx8XG4gICAgICAgIHJlc3VsdC5tZXNzYWdlID09PSAnUmFzdGVyaXphdGlvbiB0aW1lb3V0J1xuICAgICAgKSB7XG4gICAgICAgIHRocm93IG5ldyBFeHBvcnRFcnJvcihcbiAgICAgICAgICAnUmFzdGVyaXphdGlvbiB0aW1lb3V0OiB5b3VyIGNoYXJ0IG1heSBiZSB0b28gY29tcGxleCBvciBsYXJnZSwgYW5kIGZhaWxlZCB0byByZW5kZXIgd2l0aGluIHRoZSBhbGxvdHRlZCB0aW1lLidcbiAgICAgICAgKS5zZXRFcnJvcihyZXN1bHQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEV4cG9ydEVycm9yKFxuICAgICAgICAgIChvcHRpb25zLnBheWxvYWQ/LnJlcXVlc3RJZFxuICAgICAgICAgICAgPyBgRm9yIHJlcXVlc3Qgd2l0aCBJRCAke29wdGlvbnMucGF5bG9hZD8ucmVxdWVzdElkfSAtIGBcbiAgICAgICAgICAgIDogJycpICsgYEVycm9yIGVuY291bnRlcmVkIGR1cmluZyBleHBvcnQ6ICR7ZXhwb3J0Q291bnRlcigpfW1zLmBcbiAgICAgICAgKS5zZXRFcnJvcihyZXN1bHQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIENoZWNrIHRoZSBQdXBwZXRlZXIgZXhwb3J0IHRpbWVcbiAgICBpZiAob3B0aW9ucy5zZXJ2ZXIuYmVuY2htYXJraW5nKSB7XG4gICAgICBsb2coXG4gICAgICAgIDUsXG4gICAgICAgIG9wdGlvbnMucGF5bG9hZD8ucmVxdWVzdElkXG4gICAgICAgICAgPyBgW2JlbmNobWFya10gUmVxdWVzdCB3aXRoIElEICR7b3B0aW9ucy5wYXlsb2FkPy5yZXF1ZXN0SWR9IC1gXG4gICAgICAgICAgOiAnW2JlbmNobWFya10nLFxuICAgICAgICBgRXhwb3J0ZWQgYSBjaGFydCBzdWNlc3NmdWxseTogJHtleHBvcnRDb3VudGVyKCl9bXMuYFxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBSZWxlYXNlIHRoZSByZXNvdXJjZSBiYWNrIHRvIHRoZSBwb29sXG4gICAgcG9vbC5yZWxlYXNlKHdvcmtlckhhbmRsZSk7XG5cbiAgICAvLyBVc2VkIGZvciBzdGF0aXN0aWNzIGluIGF2ZXJhZ2VUaW1lIGFuZCBwcm9jZXNzZWRXb3JrQ291bnQsIHdoaWNoXG4gICAgLy8gaW4gdHVybiBpcyB1c2VkIGJ5IHRoZSAvaGVhbHRoIHJvdXRlLlxuICAgIGNvbnN0IHdvcmtFbmQgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgICBjb25zdCBleHBvcnRUaW1lID0gd29ya0VuZCAtIHdvcmtTdGFydDtcbiAgICBzdGF0cy50aW1lU3BlbnQgKz0gZXhwb3J0VGltZTtcbiAgICBzdGF0cy5zcGVudEF2ZXJhZ2UgPSBzdGF0cy50aW1lU3BlbnQgLyArK3N0YXRzLnBlcmZvcm1lZEV4cG9ydHM7XG5cbiAgICBsb2coNCwgYFtwb29sXSBXb3JrIGNvbXBsZXRlZCBpbiAke2V4cG9ydFRpbWV9IG1zLmApO1xuXG4gICAgLy8gT3RoZXJ3aXNlIHJldHVybiB0aGUgcmVzdWx0XG4gICAgcmV0dXJuIHtcbiAgICAgIHJlc3VsdCxcbiAgICAgIG9wdGlvbnNcbiAgICB9O1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgICsrc3RhdHMuZHJvcHBlZEV4cG9ydHM7XG5cbiAgICBpZiAod29ya2VySGFuZGxlKSB7XG4gICAgICBwb29sLnJlbGVhc2Uod29ya2VySGFuZGxlKTtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgRXhwb3J0RXJyb3IoYFtwb29sXSBJbiBwb29sLnBvc3RXb3JrOiAke2Vycm9yLm1lc3NhZ2V9YCkuc2V0RXJyb3IoXG4gICAgICBlcnJvclxuICAgICk7XG4gIH1cbn07XG5cbi8qKlxuICogUmV0cmlldmVzIHRoZSBjdXJyZW50IHBvb2wgaW5zdGFuY2UuXG4gKlxuICogQHJldHVybnMge09iamVjdHxudWxsfSBUaGUgY3VycmVudCBwb29sIGluc3RhbmNlIGlmIGluaXRpYWxpemVkLCBvciBudWxsXG4gKiBpZiB0aGUgcG9vbCBoYXMgbm90IGJlZW4gY3JlYXRlZC5cbiAqL1xuZXhwb3J0IGNvbnN0IGdldFBvb2wgPSAoKSA9PiBwb29sO1xuXG4vKipcbiAqIFJldHJpZXZlcyBwb29sIGluZm9ybWF0aW9uIGluIEpTT04gZm9ybWF0LCBpbmNsdWRpbmcgbWluaW11bSBhbmQgbWF4aW11bVxuICogd29ya2VycywgYXZhaWxhYmxlIHdvcmtlcnMsIHdvcmtlcnMgaW4gdXNlLCBhbmQgcGVuZGluZyBhY3F1aXJlIHJlcXVlc3RzLlxuICpcbiAqIEByZXR1cm5zIHtPYmplY3R9IFBvb2wgaW5mb3JtYXRpb24gaW4gSlNPTiBmb3JtYXQuXG4gKi9cbmV4cG9ydCBjb25zdCBnZXRQb29sSW5mb0pTT04gPSAoKSA9PiAoe1xuICBtaW46IHBvb2wubWluLFxuICBtYXg6IHBvb2wubWF4LFxuICBhbGw6IHBvb2wubnVtRnJlZSgpICsgcG9vbC5udW1Vc2VkKCksXG4gIGF2YWlsYWJsZTogcG9vbC5udW1GcmVlKCksXG4gIHVzZWQ6IHBvb2wubnVtVXNlZCgpLFxuICBwZW5kaW5nOiBwb29sLm51bVBlbmRpbmdBY3F1aXJlcygpXG59KTtcblxuLyoqXG4gKiBMb2dzIGluZm9ybWF0aW9uIGFib3V0IHRoZSBjdXJyZW50IHN0YXRlIG9mIHRoZSBwb29sLCBpbmNsdWRpbmcgdGhlIG1pbmltdW1cbiAqIGFuZCBtYXhpbXVtIHdvcmtlcnMsIGF2YWlsYWJsZSB3b3JrZXJzLCB3b3JrZXJzIGluIHVzZSwgYW5kIHBlbmRpbmcgYWNxdWlyZVxuICogcmVxdWVzdHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRQb29sSW5mbygpIHtcbiAgY29uc3QgeyBtaW4sIG1heCwgYWxsLCBhdmFpbGFibGUsIHVzZWQsIHBlbmRpbmcgfSA9IGdldFBvb2xJbmZvSlNPTigpO1xuXG4gIGxvZyg1LCBgW3Bvb2xdIFRoZSBtaW5pbXVtIG51bWJlciBvZiByZXNvdXJjZXMgYWxsb3dlZCBieSBwb29sOiAke21pbn0uYCk7XG4gIGxvZyg1LCBgW3Bvb2xdIFRoZSBtYXhpbXVtIG51bWJlciBvZiByZXNvdXJjZXMgYWxsb3dlZCBieSBwb29sOiAke21heH0uYCk7XG4gIGxvZyg1LCBgW3Bvb2xdIFRoZSBudW1iZXIgb2YgYWxsIGNyZWF0ZWQgcmVzb3VyY2VzOiAke2FsbH0uYCk7XG4gIGxvZyg1LCBgW3Bvb2xdIFRoZSBudW1iZXIgb2YgYXZhaWxhYmxlIHJlc291cmNlczogJHthdmFpbGFibGV9LmApO1xuICBsb2coNSwgYFtwb29sXSBUaGUgbnVtYmVyIG9mIGFjcXVpcmVkIHJlc291cmNlczogJHt1c2VkfS5gKTtcbiAgbG9nKDUsIGBbcG9vbF0gVGhlIG51bWJlciBvZiByZXNvdXJjZXMgd2FpdGluZyB0byBiZSBhY3F1aXJlZDogJHtwZW5kaW5nfS5gKTtcbn1cblxuZXhwb3J0IGRlZmF1bHQge1xuICBpbml0UG9vbCxcbiAga2lsbFBvb2wsXG4gIHBvc3RXb3JrLFxuICBnZXRQb29sLFxuICBnZXRQb29sSW5mbyxcbiAgZ2V0UG9vbEluZm9KU09OLFxuICBnZXRTdGF0czogKCkgPT4gc3RhdHNcbn07XG4iLCIvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuXG5IaWdoY2hhcnRzIEV4cG9ydCBTZXJ2ZXJcblxuQ29weXJpZ2h0IChjKSAyMDE2LTIwMjQsIEhpZ2hzb2Z0XG5cbkxpY2VuY2VkIHVuZGVyIHRoZSBNSVQgbGljZW5jZS5cblxuQWRkaXRpb25hbGx5IGEgdmFsaWQgSGlnaGNoYXJ0cyBsaWNlbnNlIGlzIHJlcXVpcmVkIGZvciB1c2UuXG5cblNlZSBMSUNFTlNFIGZpbGUgaW4gcm9vdCBmb3IgZGV0YWlscy5cblxuKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuaW1wb3J0IHsgcmVhZEZpbGVTeW5jLCB3cml0ZUZpbGVTeW5jIH0gZnJvbSAnZnMnO1xuXG5pbXBvcnQgeyBnZXRPcHRpb25zLCBpbml0RXhwb3J0U2V0dGluZ3MgfSBmcm9tICcuL2NvbmZpZy5qcyc7XG5pbXBvcnQgeyBsb2csIGxvZ1dpdGhTdGFjayB9IGZyb20gJy4vbG9nZ2VyLmpzJztcbmltcG9ydCB7IGtpbGxQb29sLCBwb3N0V29yaywgc3RhdHMgfSBmcm9tICcuL3Bvb2wuanMnO1xuaW1wb3J0IHtcbiAgZml4VHlwZSxcbiAgaGFuZGxlUmVzb3VyY2VzLFxuICBpc0NvcnJlY3RKU09OLFxuICBvcHRpb25zU3RyaW5naWZ5LFxuICByb3VuZE51bWJlcixcbiAgdG9Cb29sZWFuLFxuICB3cmFwQXJvdW5kXG59IGZyb20gJy4vdXRpbHMuanMnO1xuaW1wb3J0IHsgc2FuaXRpemUgfSBmcm9tICcuL3Nhbml0aXplLmpzJztcbmltcG9ydCBFeHBvcnRFcnJvciBmcm9tICcuL2Vycm9ycy9FeHBvcnRFcnJvci5qcyc7XG5cbmxldCBhbGxvd0NvZGVFeGVjdXRpb24gPSBmYWxzZTtcblxuLyoqXG4gKiBTdGFydHMgYW4gZXhwb3J0IHByb2Nlc3MuIFRoZSBgc2V0dGluZ3NgIGNvbnRhaW5zIGZpbmFsIG9wdGlvbnMgZ2F0aGVyZWRcbiAqIGZyb20gYWxsIHBvc3NpYmxlIHNvdXJjZXMgKGNvbmZpZywgZW52LCBjbGksIGpzb24pLiBUaGUgYGVuZENhbGxiYWNrYCBpc1xuICogY2FsbGVkIHdoZW4gdGhlIGV4cG9ydCBpcyBjb21wbGV0ZWQsIHdpdGggYW4gZXJyb3Igb2JqZWN0IGFzIHRoZSBmaXJzdFxuICogYXJndW1lbnQgYW5kIHRoZSBzZWNvbmQgY29udGFpbmluZyB0aGUgYmFzZTY0IHJlc3ByZXNlbnRhdGlvbiBvZiBhIGNoYXJ0LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBzZXR0aW5ncyAtIFRoZSBzZXR0aW5ncyBvYmplY3QgY29udGFpbmluZyBleHBvcnRcbiAqIGNvbmZpZ3VyYXRpb24uXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBlbmRDYWxsYmFjayAtIFRoZSBjYWxsYmFjayBmdW5jdGlvbiB0byBiZSBpbnZva2VkIHVwb25cbiAqIGZpbmFsaXppbmcgd29yayBvciB1cG9uIGVycm9yIG9jY3VyYW5jZSBvZiB0aGUgZXhwb3J0aW5nIHByb2Nlc3MuXG4gKlxuICogQHJldHVybnMge3ZvaWR9IFRoaXMgZnVuY3Rpb24gZG9lcyBub3QgcmV0dXJuIGEgdmFsdWUgZGlyZWN0bHk7IGluc3RlYWQsXG4gKiBpdCBjb21tdW5pY2F0ZXMgcmVzdWx0cyB2aWEgdGhlIGVuZENhbGxiYWNrLlxuICovXG5leHBvcnQgY29uc3Qgc3RhcnRFeHBvcnQgPSBhc3luYyAoc2V0dGluZ3MsIGVuZENhbGxiYWNrKSA9PiB7XG4gIC8vIFN0YXJ0aW5nIGV4cG9ydGluZyBwcm9jZXNzIG1lc3NhZ2VcbiAgbG9nKDQsICdbY2hhcnRdIFN0YXJ0aW5nIHRoZSBleHBvcnRpbmcgcHJvY2Vzcy4nKTtcblxuICAvLyBJbml0aWFsaXplIG9wdGlvbnNcbiAgY29uc3Qgb3B0aW9ucyA9IGluaXRFeHBvcnRTZXR0aW5ncyhzZXR0aW5ncywgZ2V0T3B0aW9ucygpKTtcblxuICAvLyBHZXQgdGhlIGV4cG9ydCBvcHRpb25zXG4gIGNvbnN0IGV4cG9ydE9wdGlvbnMgPSBvcHRpb25zLmV4cG9ydDtcblxuICAvLyBJZiBTVkcgaXMgYW4gaW5wdXQgKGFyZ3VtZW50IGNhbiBiZSBzZW50IG9ubHkgYnkgdGhlIHJlcXVlc3QpXG4gIGlmIChvcHRpb25zLnBheWxvYWQ/LnN2ZyAmJiBvcHRpb25zLnBheWxvYWQuc3ZnICE9PSAnJykge1xuICAgIHRyeSB7XG4gICAgICBsb2coNCwgJ1tjaGFydF0gQXR0ZW1wdGluZyB0byBleHBvcnQgZnJvbSBhIFNWRyBpbnB1dC4nKTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gZXhwb3J0QXNTdHJpbmcoXG4gICAgICAgIHNhbml0aXplKG9wdGlvbnMucGF5bG9hZC5zdmcpLCAvLyAjMjA5XG4gICAgICAgIG9wdGlvbnMsXG4gICAgICAgIGVuZENhbGxiYWNrXG4gICAgICApO1xuXG4gICAgICArK3N0YXRzLmV4cG9ydEZyb21TdmdBdHRlbXB0cztcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHJldHVybiBlbmRDYWxsYmFjayhcbiAgICAgICAgbmV3IEV4cG9ydEVycm9yKCdbY2hhcnRdIEVycm9yIGxvYWRpbmcgU1ZHIGlucHV0LicpLnNldEVycm9yKGVycm9yKVxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvLyBFeHBvcnQgdXNpbmcgb3B0aW9ucyBmcm9tIHRoZSBmaWxlXG4gIGlmIChleHBvcnRPcHRpb25zLmluZmlsZSAmJiBleHBvcnRPcHRpb25zLmluZmlsZS5sZW5ndGgpIHtcbiAgICAvLyBUcnkgdG8gcmVhZCB0aGUgZmlsZSB0byBnZXQgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvblxuICAgIHRyeSB7XG4gICAgICBsb2coNCwgJ1tjaGFydF0gQXR0ZW1wdGluZyB0byBleHBvcnQgZnJvbSBhbiBpbnB1dCBmaWxlLicpO1xuICAgICAgb3B0aW9ucy5leHBvcnQuaW5zdHIgPSByZWFkRmlsZVN5bmMoZXhwb3J0T3B0aW9ucy5pbmZpbGUsICd1dGY4Jyk7XG4gICAgICByZXR1cm4gZXhwb3J0QXNTdHJpbmcob3B0aW9ucy5leHBvcnQuaW5zdHIudHJpbSgpLCBvcHRpb25zLCBlbmRDYWxsYmFjayk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHJldHVybiBlbmRDYWxsYmFjayhcbiAgICAgICAgbmV3IEV4cG9ydEVycm9yKCdbY2hhcnRdIEVycm9yIGxvYWRpbmcgaW5wdXQgZmlsZS4nKS5zZXRFcnJvcihlcnJvcilcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLy8gRXhwb3J0IHdpdGggb3B0aW9ucyBmcm9tIHRoZSByYXcgcmVwcmVzZW50YXRpb25cbiAgaWYgKFxuICAgIChleHBvcnRPcHRpb25zLmluc3RyICYmIGV4cG9ydE9wdGlvbnMuaW5zdHIgIT09ICcnKSB8fFxuICAgIChleHBvcnRPcHRpb25zLm9wdGlvbnMgJiYgZXhwb3J0T3B0aW9ucy5vcHRpb25zICE9PSAnJylcbiAgKSB7XG4gICAgdHJ5IHtcbiAgICAgIGxvZyg0LCAnW2NoYXJ0XSBBdHRlbXB0aW5nIHRvIGV4cG9ydCBmcm9tIGEgcmF3IGlucHV0LicpO1xuXG4gICAgICAvLyBVc2Ugd2hpY2hldmVyIG9uZSBpcyBhdmFpbGFibGVcbiAgICAgIGV4cG9ydE9wdGlvbnMuaW5zdHIgPSBleHBvcnRPcHRpb25zLmluc3RyIHx8IGV4cG9ydE9wdGlvbnMub3B0aW9ucztcblxuICAgICAgLy8gUGVyZm9ybSBhIGRpcmVjdCBpbmplY3Qgd2hlbiBmb3JjZWRcbiAgICAgIGlmICh0b0Jvb2xlYW4ob3B0aW9ucy5jdXN0b21Mb2dpYz8uYWxsb3dDb2RlRXhlY3V0aW9uKSkge1xuICAgICAgICByZXR1cm4gZG9TdHJhaWdodEluamVjdChvcHRpb25zLCBlbmRDYWxsYmFjayk7XG4gICAgICB9XG5cbiAgICAgIC8vIEVpdGhlciB0cnkgdG8gcGFyc2UgdG8gSlNPTiBmaXJzdCBvciBkbyB0aGUgZGlyZWN0IGV4cG9ydFxuICAgICAgcmV0dXJuIHR5cGVvZiBleHBvcnRPcHRpb25zLmluc3RyID09PSAnc3RyaW5nJ1xuICAgICAgICA/IGV4cG9ydEFzU3RyaW5nKGV4cG9ydE9wdGlvbnMuaW5zdHIudHJpbSgpLCBvcHRpb25zLCBlbmRDYWxsYmFjaylcbiAgICAgICAgOiBkb0V4cG9ydChcbiAgICAgICAgICAgIG9wdGlvbnMsXG4gICAgICAgICAgICBleHBvcnRPcHRpb25zLmluc3RyIHx8IGV4cG9ydE9wdGlvbnMub3B0aW9ucyxcbiAgICAgICAgICAgIGVuZENhbGxiYWNrXG4gICAgICAgICAgKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcmV0dXJuIGVuZENhbGxiYWNrKFxuICAgICAgICBuZXcgRXhwb3J0RXJyb3IoJ1tjaGFydF0gRXJyb3IgbG9hZGluZyByYXcgaW5wdXQuJykuc2V0RXJyb3IoZXJyb3IpXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8vIE5vIGlucHV0IHNwZWNpZmllZCwgcGFzcyBhbiBlcnJvciBtZXNzYWdlIHRvIHRoZSBjYWxsYmFja1xuICByZXR1cm4gZW5kQ2FsbGJhY2soXG4gICAgbmV3IEV4cG9ydEVycm9yKFxuICAgICAgYFtjaGFydF0gTm8gdmFsaWQgaW5wdXQgc3BlY2lmaWVkLiBDaGVjayBpZiBhdCBsZWFzdCBvbmUgb2YgdGhlIGZvbGxvd2luZyBwYXJhbWV0ZXJzIGlzIGNvcnJlY3RseSBzZXQ6ICdpbmZpbGUnLCAnaW5zdHInLCAnb3B0aW9ucycsIG9yICdzdmcnLmBcbiAgICApXG4gICk7XG59O1xuXG4vKipcbiAqIFN0YXJ0cyBhIGJhdGNoIGV4cG9ydCBwcm9jZXNzIGZvciBtdWx0aXBsZSBjaGFydHMgYmFzZWQgb24gdGhlIGluZm9ybWF0aW9uXG4gKiBpbiB0aGUgYmF0Y2ggb3B0aW9uLiBUaGUgYmF0Y2ggaXMgYSBzdHJpbmcgaW4gdGhlIGZvbGxvd2luZyBmb3JtYXQ6XG4gKiBcImluZmlsZTEuanNvbj1vdXRmaWxlMS5wbmc7aW5maWxlMi5qc29uPW91dGZpbGUyLnBuZzsuLi5cIlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gVGhlIG9wdGlvbnMgb2JqZWN0IGNvbnRhaW5pbmcgY29uZmlndXJhdGlvbiBmb3JcbiAqIGEgYmF0Y2ggZXhwb3J0LlxuICpcbiAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSBBIFByb21pc2UgdGhhdCByZXNvbHZlcyBvbmNlIHRoZSBiYXRjaCBleHBvcnRcbiAqIHByb2Nlc3MgaXMgY29tcGxldGVkLlxuICpcbiAqIEB0aHJvd3Mge0V4cG9ydEVycm9yfSBUaHJvd3MgYW4gRXhwb3J0RXJyb3IgaWYgYW4gZXJyb3Igb2NjdXJzIGR1cmluZ1xuICogYW55IG9mIHRoZSBiYXRjaCBleHBvcnQgcHJvY2Vzcy5cbiAqL1xuZXhwb3J0IGNvbnN0IGJhdGNoRXhwb3J0ID0gYXN5bmMgKG9wdGlvbnMpID0+IHtcbiAgY29uc3QgYmF0Y2hGdW5jdGlvbnMgPSBbXTtcblxuICAvLyBTcGxpdCBhbmQgcGFpciB0aGUgLS1iYXRjaCBhcmd1bWVudHNcbiAgZm9yIChsZXQgcGFpciBvZiBvcHRpb25zLmV4cG9ydC5iYXRjaC5zcGxpdCgnOycpKSB7XG4gICAgcGFpciA9IHBhaXIuc3BsaXQoJz0nKTtcbiAgICBpZiAocGFpci5sZW5ndGggPT09IDIpIHtcbiAgICAgIGJhdGNoRnVuY3Rpb25zLnB1c2goXG4gICAgICAgIHN0YXJ0RXhwb3J0KFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIC4uLm9wdGlvbnMsXG4gICAgICAgICAgICBleHBvcnQ6IHtcbiAgICAgICAgICAgICAgLi4ub3B0aW9ucy5leHBvcnQsXG4gICAgICAgICAgICAgIGluZmlsZTogcGFpclswXSxcbiAgICAgICAgICAgICAgb3V0ZmlsZTogcGFpclsxXVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgICAgKGVycm9yLCBpbmZvKSA9PiB7XG4gICAgICAgICAgICAvLyBUaHJvdyBhbiBlcnJvclxuICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBTYXZlIHRoZSBiYXNlNjQgZnJvbSBhIGJ1ZmZlciB0byBhIGNvcnJlY3QgaW1hZ2UgZmlsZVxuICAgICAgICAgICAgd3JpdGVGaWxlU3luYyhcbiAgICAgICAgICAgICAgaW5mby5vcHRpb25zLmV4cG9ydC5vdXRmaWxlLFxuICAgICAgICAgICAgICBpbmZvLm9wdGlvbnMuZXhwb3J0LnR5cGUgIT09ICdzdmcnXG4gICAgICAgICAgICAgICAgPyBCdWZmZXIuZnJvbShpbmZvLnJlc3VsdCwgJ2Jhc2U2NCcpXG4gICAgICAgICAgICAgICAgOiBpbmZvLnJlc3VsdFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIClcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgdHJ5IHtcbiAgICAvLyBBd2FpdCBhbGwgZXhwb3J0cyBhcmUgZG9uZVxuICAgIGF3YWl0IFByb21pc2UuYWxsKGJhdGNoRnVuY3Rpb25zKTtcblxuICAgIC8vIEtpbGwgcG9vbCBhbmQgY2xvc2UgYnJvd3NlciBhZnRlciBmaW5pc2hpbmcgYmF0Y2ggZXhwb3J0XG4gICAgYXdhaXQga2lsbFBvb2woKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICB0aHJvdyBuZXcgRXhwb3J0RXJyb3IoXG4gICAgICAnW2NoYXJ0XSBFcnJvciBlbmNvdW50ZXJlZCBkdXJpbmcgYmF0Y2ggZXhwb3J0LidcbiAgICApLnNldEVycm9yKGVycm9yKTtcbiAgfVxufTtcblxuLyoqXG4gKiBTdGFydHMgYSBzaW5nbGUgZXhwb3J0IHByb2Nlc3MgYmFzZWQgb24gdGhlIHNwZWNpZmllZCBvcHRpb25zLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gVGhlIG9wdGlvbnMgb2JqZWN0IGNvbnRhaW5pbmcgY29uZmlndXJhdGlvbiBmb3JcbiAqIGEgc2luZ2xlIGV4cG9ydC5cbiAqXG4gKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gQSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgb25jZSB0aGUgc2luZ2xlIGV4cG9ydFxuICogcHJvY2VzcyBpcyBjb21wbGV0ZWQuXG4gKlxuICogQHRocm93cyB7RXhwb3J0RXJyb3J9IFRocm93cyBhbiBFeHBvcnRFcnJvciBpZiBhbiBlcnJvciBvY2N1cnMgZHVyaW5nXG4gKiB0aGUgc2luZ2xlIGV4cG9ydCBwcm9jZXNzLlxuICovXG5leHBvcnQgY29uc3Qgc2luZ2xlRXhwb3J0ID0gYXN5bmMgKG9wdGlvbnMpID0+IHtcbiAgLy8gVXNlIGluc3RyIG9yIGl0cyBhbGlhcywgb3B0aW9uc1xuICBvcHRpb25zLmV4cG9ydC5pbnN0ciA9IG9wdGlvbnMuZXhwb3J0Lmluc3RyIHx8IG9wdGlvbnMuZXhwb3J0Lm9wdGlvbnM7XG5cbiAgLy8gUGVyZm9ybSBhbiBleHBvcnRcbiAgYXdhaXQgc3RhcnRFeHBvcnQob3B0aW9ucywgYXN5bmMgKGVycm9yLCBpbmZvKSA9PiB7XG4gICAgLy8gRXhpdCBwcm9jZXNzIHdoZW4gZXJyb3JcbiAgICBpZiAoZXJyb3IpIHtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cblxuICAgIGNvbnN0IHsgb3V0ZmlsZSwgdHlwZSB9ID0gaW5mby5vcHRpb25zLmV4cG9ydDtcblxuICAgIC8vIFNhdmUgdGhlIGJhc2U2NCBmcm9tIGEgYnVmZmVyIHRvIGEgY29ycmVjdCBpbWFnZSBmaWxlXG4gICAgd3JpdGVGaWxlU3luYyhcbiAgICAgIG91dGZpbGUgfHwgYGNoYXJ0LiR7dHlwZX1gLFxuICAgICAgdHlwZSAhPT0gJ3N2ZycgPyBCdWZmZXIuZnJvbShpbmZvLnJlc3VsdCwgJ2Jhc2U2NCcpIDogaW5mby5yZXN1bHRcbiAgICApO1xuXG4gICAgLy8gS2lsbCBwb29sIGFuZCBjbG9zZSBicm93c2VyIGFmdGVyIGZpbmlzaGluZyBzaW5nbGUgZXhwb3J0XG4gICAgYXdhaXQga2lsbFBvb2woKTtcbiAgfSk7XG59O1xuXG4vKipcbiAqIERldGVybWluZXMgdGhlIHNpemUgYW5kIHNjYWxlIGZvciBjaGFydCBleHBvcnQgYmFzZWQgb24gdGhlIHByb3ZpZGVkIG9wdGlvbnMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgLSBUaGUgb3B0aW9ucyBvYmplY3QgY29udGFpbmluZyBjb25maWd1cmF0aW9uIGZvclxuICogY2hhcnQgZXhwb3J0LlxuICpcbiAqIEByZXR1cm5zIHtPYmplY3R9IEFuIG9iamVjdCBjb250YWluaW5nIHRoZSBjYWxjdWxhdGVkIGhlaWdodCwgd2lkdGgsXG4gKiBhbmQgc2NhbGUgZm9yIHRoZSBjaGFydCBleHBvcnQuXG4gKi9cbmV4cG9ydCBjb25zdCBmaW5kQ2hhcnRTaXplID0gKG9wdGlvbnMpID0+IHtcbiAgY29uc3QgeyBjaGFydCwgZXhwb3J0aW5nIH0gPVxuICAgIG9wdGlvbnMuZXhwb3J0Py5vcHRpb25zIHx8IGlzQ29ycmVjdEpTT04ob3B0aW9ucy5leHBvcnQ/Lmluc3RyKTtcblxuICAvLyBTZWUgaWYgZ2xvYmFsT3B0aW9ucyBob2xkcyBjaGFydCBvciBleHBvcnRpbmcgc2l6ZVxuICBjb25zdCBnbG9iYWxPcHRpb25zID0gaXNDb3JyZWN0SlNPTihvcHRpb25zLmV4cG9ydD8uZ2xvYmFsT3B0aW9ucyk7XG5cbiAgLy8gU2VjdXJlIHNjYWxlIHZhbHVlXG4gIGxldCBzY2FsZSA9XG4gICAgb3B0aW9ucy5leHBvcnQ/LnNjYWxlIHx8XG4gICAgZXhwb3J0aW5nPy5zY2FsZSB8fFxuICAgIGdsb2JhbE9wdGlvbnM/LmV4cG9ydGluZz8uc2NhbGUgfHxcbiAgICBvcHRpb25zLmV4cG9ydD8uZGVmYXVsdFNjYWxlIHx8XG4gICAgMTtcblxuICAvLyB0aGUgc2NhbGUgY2Fubm90IGJlIGxvd2VyIHRoYW4gMC4xIGFuZCBjYW5ub3QgYmUgaGlnaGVyIHRoYW4gNS4wXG4gIHNjYWxlID0gTWF0aC5tYXgoMC4xLCBNYXRoLm1pbihzY2FsZSwgNS4wKSk7XG5cbiAgLy8gd2Ugd2FudCB0byByb3VuZCB0aGUgbnVtYmVycyBsaWtlIDAuMjMyMzQgLT4gMC4yM1xuICBzY2FsZSA9IHJvdW5kTnVtYmVyKHNjYWxlLCAyKTtcblxuICAvLyBGaW5kIGNoYXJ0IHNpemUgYW5kIHNjYWxlXG4gIGNvbnN0IHNpemUgPSB7XG4gICAgaGVpZ2h0OlxuICAgICAgb3B0aW9ucy5leHBvcnQ/LmhlaWdodCB8fFxuICAgICAgZXhwb3J0aW5nPy5zb3VyY2VIZWlnaHQgfHxcbiAgICAgIGNoYXJ0Py5oZWlnaHQgfHxcbiAgICAgIGdsb2JhbE9wdGlvbnM/LmV4cG9ydGluZz8uc291cmNlSGVpZ2h0IHx8XG4gICAgICBnbG9iYWxPcHRpb25zPy5jaGFydD8uaGVpZ2h0IHx8XG4gICAgICBvcHRpb25zLmV4cG9ydD8uZGVmYXVsdEhlaWdodCB8fFxuICAgICAgNDAwLFxuICAgIHdpZHRoOlxuICAgICAgb3B0aW9ucy5leHBvcnQ/LndpZHRoIHx8XG4gICAgICBleHBvcnRpbmc/LnNvdXJjZVdpZHRoIHx8XG4gICAgICBjaGFydD8ud2lkdGggfHxcbiAgICAgIGdsb2JhbE9wdGlvbnM/LmV4cG9ydGluZz8uc291cmNlV2lkdGggfHxcbiAgICAgIGdsb2JhbE9wdGlvbnM/LmNoYXJ0Py53aWR0aCB8fFxuICAgICAgb3B0aW9ucy5leHBvcnQ/LmRlZmF1bHRXaWR0aCB8fFxuICAgICAgNjAwLFxuICAgIHNjYWxlXG4gIH07XG5cbiAgLy8gR2V0IHJpZCBvZiBwb3RlbnRpYWwgcHggYW5kICVcbiAgZm9yIChsZXQgW3BhcmFtLCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoc2l6ZSkpIHtcbiAgICBzaXplW3BhcmFtXSA9XG4gICAgICB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnID8gK3ZhbHVlLnJlcGxhY2UoL3B4fCUvZ2ksICcnKSA6IHZhbHVlO1xuICB9XG4gIHJldHVybiBzaXplO1xufTtcblxuLyoqXG4gKiBGdW5jdGlvbiBmb3IgZmluYWxpemluZyBvcHRpb25zIGJlZm9yZSBleHBvcnQuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgLSBUaGUgb3B0aW9ucyBvYmplY3QgY29udGFpbmluZyBjb25maWd1cmF0aW9uIGZvclxuICogdGhlIGV4cG9ydCBwcm9jZXNzLlxuICogQHBhcmFtIHtPYmplY3R9IGNoYXJ0SnNvbiAtIFRoZSBKU09OIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBjaGFydC5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGVuZENhbGxiYWNrIC0gVGhlIGNhbGxiYWNrIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZCB1cG9uXG4gKiBjb21wbGV0aW9uIG9yIGVycm9yLlxuICogQHBhcmFtIHtzdHJpbmd9IHN2ZyAtIFRoZSBTVkcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGNoYXJ0LlxuICpcbiAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSBBIFByb21pc2UgdGhhdCByZXNvbHZlcyBvbmNlIHRoZSBleHBvcnQgcHJvY2Vzc1xuICogaXMgY29tcGxldGVkLlxuICovXG5jb25zdCBkb0V4cG9ydCA9IGFzeW5jIChvcHRpb25zLCBjaGFydEpzb24sIGVuZENhbGxiYWNrLCBzdmcpID0+IHtcbiAgbGV0IHsgZXhwb3J0OiBleHBvcnRPcHRpb25zLCBjdXN0b21Mb2dpYzogY3VzdG9tTG9naWNPcHRpb25zIH0gPSBvcHRpb25zO1xuXG4gIGNvbnN0IGFsbG93Q29kZUV4ZWN1dGlvblNjb3BlZCA9XG4gICAgdHlwZW9mIGN1c3RvbUxvZ2ljT3B0aW9ucy5hbGxvd0NvZGVFeGVjdXRpb24gPT09ICdib29sZWFuJ1xuICAgICAgPyBjdXN0b21Mb2dpY09wdGlvbnMuYWxsb3dDb2RlRXhlY3V0aW9uXG4gICAgICA6IGFsbG93Q29kZUV4ZWN1dGlvbjtcblxuICBpZiAoIWN1c3RvbUxvZ2ljT3B0aW9ucykge1xuICAgIGN1c3RvbUxvZ2ljT3B0aW9ucyA9IG9wdGlvbnMuY3VzdG9tTG9naWMgPSB7fTtcbiAgfSBlbHNlIGlmIChhbGxvd0NvZGVFeGVjdXRpb25TY29wZWQpIHtcbiAgICBpZiAodHlwZW9mIG9wdGlvbnMuY3VzdG9tTG9naWMucmVzb3VyY2VzID09PSAnc3RyaW5nJykge1xuICAgICAgLy8gUHJvY2VzcyByZXNvdXJjZXNcbiAgICAgIG9wdGlvbnMuY3VzdG9tTG9naWMucmVzb3VyY2VzID0gaGFuZGxlUmVzb3VyY2VzKFxuICAgICAgICBvcHRpb25zLmN1c3RvbUxvZ2ljLnJlc291cmNlcyxcbiAgICAgICAgdG9Cb29sZWFuKG9wdGlvbnMuY3VzdG9tTG9naWMuYWxsb3dGaWxlUmVzb3VyY2VzKVxuICAgICAgKTtcbiAgICB9IGVsc2UgaWYgKCFvcHRpb25zLmN1c3RvbUxvZ2ljLnJlc291cmNlcykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVzb3VyY2VzID0gcmVhZEZpbGVTeW5jKCdyZXNvdXJjZXMuanNvbicsICd1dGY4Jyk7XG4gICAgICAgIG9wdGlvbnMuY3VzdG9tTG9naWMucmVzb3VyY2VzID0gaGFuZGxlUmVzb3VyY2VzKFxuICAgICAgICAgIHJlc291cmNlcyxcbiAgICAgICAgICB0b0Jvb2xlYW4ob3B0aW9ucy5jdXN0b21Mb2dpYy5hbGxvd0ZpbGVSZXNvdXJjZXMpXG4gICAgICAgICk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBsb2coMiwgYFtjaGFydF0gVW5hYmxlIHRvIGxvYWQgdGhlIGRlZmF1bHQgcmVzb3VyY2VzLmpzb24gZmlsZS5gKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBJZiB0aGUgYWxsb3dDb2RlRXhlY3V0aW9uIGZsYWcgaXNuJ3Qgc2V0LCB3ZSBzaG91bGQgcmVmdXNlIHRoZSB1c2FnZVxuICAvLyBvZiBjYWxsYmFjaywgcmVzb3VyY2VzLCBhbmQgY3VzdG9tIGNvZGUuIEFkZGl0aW9uYWxseSwgdGhlIHdvcmtlciB3aWxsXG4gIC8vIHJlZnVzZSB0byBydW4gYXJiaXRyYXJ5IEphdmFTY3JpcHQuIFByaW9yaXRpemVkIHNob3VsZCBiZSB0aGUgc2NvcGVkXG4gIC8vIG9wdGlvbiwgdGhlbiB3ZSBzaG91bGQgdGFrZSBhIGxvb2sgYXQgdGhlIG92ZXJhbGwgcG9vbCBvcHRpb24uXG4gIGlmICghYWxsb3dDb2RlRXhlY3V0aW9uU2NvcGVkICYmIGN1c3RvbUxvZ2ljT3B0aW9ucykge1xuICAgIGlmIChcbiAgICAgIGN1c3RvbUxvZ2ljT3B0aW9ucy5jYWxsYmFjayB8fFxuICAgICAgY3VzdG9tTG9naWNPcHRpb25zLnJlc291cmNlcyB8fFxuICAgICAgY3VzdG9tTG9naWNPcHRpb25zLmN1c3RvbUNvZGVcbiAgICApIHtcbiAgICAgIC8vIFNlbmQgYmFjayBhIGZyaWVuZGx5IG1lc3NhZ2Ugc2F5aW5nIHRoYXQgdGhlIGV4cG9ydGVyIGRvZXMgbm90IHN1cHBvcnRcbiAgICAgIC8vIHRoZXNlIHNldHRpbmdzLlxuICAgICAgcmV0dXJuIGVuZENhbGxiYWNrKFxuICAgICAgICBuZXcgRXhwb3J0RXJyb3IoXG4gICAgICAgICAgYFtjaGFydF0gVGhlICdjYWxsYmFjaycsICdyZXNvdXJjZXMnIGFuZCAnY3VzdG9tQ29kZScgb3B0aW9ucyBoYXZlIGJlZW4gZGlzYWJsZWQgZm9yIHRoaXMgc2VydmVyLmBcbiAgICAgICAgKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBSZXNldCBhbGwgYWRkaXRpb25hbCBjdXN0b20gY29kZVxuICAgIGN1c3RvbUxvZ2ljT3B0aW9ucy5jYWxsYmFjayA9IGZhbHNlO1xuICAgIGN1c3RvbUxvZ2ljT3B0aW9ucy5yZXNvdXJjZXMgPSBmYWxzZTtcbiAgICBjdXN0b21Mb2dpY09wdGlvbnMuY3VzdG9tQ29kZSA9IGZhbHNlO1xuICB9XG5cbiAgLy8gQ2xlYW4gcHJvcGVydGllcyB0byBrZWVwIGl0IGxlYW4gYW5kIG1lYW5cbiAgaWYgKGNoYXJ0SnNvbikge1xuICAgIGNoYXJ0SnNvbi5jaGFydCA9IGNoYXJ0SnNvbi5jaGFydCB8fCB7fTtcbiAgICBjaGFydEpzb24uZXhwb3J0aW5nID0gY2hhcnRKc29uLmV4cG9ydGluZyB8fCB7fTtcbiAgICBjaGFydEpzb24uZXhwb3J0aW5nLmVuYWJsZWQgPSBmYWxzZTtcbiAgfVxuXG4gIGV4cG9ydE9wdGlvbnMuY29uc3RyID0gZXhwb3J0T3B0aW9ucy5jb25zdHIgfHwgJ2NoYXJ0JztcbiAgZXhwb3J0T3B0aW9ucy50eXBlID0gZml4VHlwZShleHBvcnRPcHRpb25zLnR5cGUsIGV4cG9ydE9wdGlvbnMub3V0ZmlsZSk7XG4gIGlmIChleHBvcnRPcHRpb25zLnR5cGUgPT09ICdzdmcnKSB7XG4gICAgZXhwb3J0T3B0aW9ucy53aWR0aCA9IGZhbHNlO1xuICB9XG5cbiAgLy8gUHJlcGFyZSBnbG9iYWwgYW5kIHRoZW1lIG9wdGlvbnNcbiAgWydnbG9iYWxPcHRpb25zJywgJ3RoZW1lT3B0aW9ucyddLmZvckVhY2goKG9wdGlvbnNOYW1lKSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGlmIChleHBvcnRPcHRpb25zICYmIGV4cG9ydE9wdGlvbnNbb3B0aW9uc05hbWVdKSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICB0eXBlb2YgZXhwb3J0T3B0aW9uc1tvcHRpb25zTmFtZV0gPT09ICdzdHJpbmcnICYmXG4gICAgICAgICAgZXhwb3J0T3B0aW9uc1tvcHRpb25zTmFtZV0uZW5kc1dpdGgoJy5qc29uJylcbiAgICAgICAgKSB7XG4gICAgICAgICAgZXhwb3J0T3B0aW9uc1tvcHRpb25zTmFtZV0gPSBpc0NvcnJlY3RKU09OKFxuICAgICAgICAgICAgcmVhZEZpbGVTeW5jKGV4cG9ydE9wdGlvbnNbb3B0aW9uc05hbWVdLCAndXRmOCcpLFxuICAgICAgICAgICAgdHJ1ZVxuICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZXhwb3J0T3B0aW9uc1tvcHRpb25zTmFtZV0gPSBpc0NvcnJlY3RKU09OKFxuICAgICAgICAgICAgZXhwb3J0T3B0aW9uc1tvcHRpb25zTmFtZV0sXG4gICAgICAgICAgICB0cnVlXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBleHBvcnRPcHRpb25zW29wdGlvbnNOYW1lXSA9IHt9O1xuICAgICAgbG9nV2l0aFN0YWNrKDIsIGVycm9yLCBgW2NoYXJ0XSBUaGUgJyR7b3B0aW9uc05hbWV9JyBjYW5ub3QgYmUgbG9hZGVkLmApO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gUHJlcGFyZSB0aGUgY3VzdG9tQ29kZVxuICBpZiAoY3VzdG9tTG9naWNPcHRpb25zLmFsbG93Q29kZUV4ZWN1dGlvbikge1xuICAgIHRyeSB7XG4gICAgICBjdXN0b21Mb2dpY09wdGlvbnMuY3VzdG9tQ29kZSA9IHdyYXBBcm91bmQoXG4gICAgICAgIGN1c3RvbUxvZ2ljT3B0aW9ucy5jdXN0b21Db2RlLFxuICAgICAgICBjdXN0b21Mb2dpY09wdGlvbnMuYWxsb3dGaWxlUmVzb3VyY2VzXG4gICAgICApO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dXaXRoU3RhY2soMiwgZXJyb3IsIGBbY2hhcnRdIFRoZSAnY3VzdG9tQ29kZScgY2Fubm90IGJlIGxvYWRlZC5gKTtcbiAgICB9XG4gIH1cblxuICAvLyBHZXQgdGhlIGNhbGxiYWNrXG4gIGlmIChcbiAgICBjdXN0b21Mb2dpY09wdGlvbnMgJiZcbiAgICBjdXN0b21Mb2dpY09wdGlvbnMuY2FsbGJhY2sgJiZcbiAgICBjdXN0b21Mb2dpY09wdGlvbnMuY2FsbGJhY2s/LmluZGV4T2YoJ3snKSA8IDBcbiAgKSB7XG4gICAgLy8gVGhlIGFsbG93RmlsZVJlc291cmNlcyBpcyBhbHdheXMgc2V0IHRvIGZhbHNlIGZvciBIVFRQIHJlcXVlc3RzIHRvIGF2b2lkXG4gICAgLy8gaW5qZWN0aW5nIGFyYml0cmFyeSBmaWxlcyBmcm9tIHRoZSBmc1xuICAgIGlmIChjdXN0b21Mb2dpY09wdGlvbnMuYWxsb3dGaWxlUmVzb3VyY2VzKSB7XG4gICAgICB0cnkge1xuICAgICAgICBjdXN0b21Mb2dpY09wdGlvbnMuY2FsbGJhY2sgPSByZWFkRmlsZVN5bmMoXG4gICAgICAgICAgY3VzdG9tTG9naWNPcHRpb25zLmNhbGxiYWNrLFxuICAgICAgICAgICd1dGY4J1xuICAgICAgICApO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgY3VzdG9tTG9naWNPcHRpb25zLmNhbGxiYWNrID0gZmFsc2U7XG4gICAgICAgIGxvZ1dpdGhTdGFjaygyLCBlcnJvciwgYFtjaGFydF0gVGhlICdjYWxsYmFjaycgY2Fubm90IGJlIGxvYWRlZC5gKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgY3VzdG9tTG9naWNPcHRpb25zLmNhbGxiYWNrID0gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgLy8gU2l6ZSBzZWFyY2hcbiAgb3B0aW9ucy5leHBvcnQgPSB7XG4gICAgLi4ub3B0aW9ucy5leHBvcnQsXG4gICAgLi4uZmluZENoYXJ0U2l6ZShvcHRpb25zKVxuICB9O1xuXG4gIC8vIFBvc3QgdGhlIHdvcmsgdG8gdGhlIHBvb2xcbiAgdHJ5IHtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBwb3N0V29yayhcbiAgICAgIGV4cG9ydE9wdGlvbnMuc3RySW5qIHx8IGNoYXJ0SnNvbiB8fCBzdmcsXG4gICAgICBvcHRpb25zXG4gICAgKTtcbiAgICByZXR1cm4gZW5kQ2FsbGJhY2soZmFsc2UsIHJlc3VsdCk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgcmV0dXJuIGVuZENhbGxiYWNrKGVycm9yKTtcbiAgfVxufTtcblxuLyoqXG4gKiBQZXJmb3JtcyBhIGRpcmVjdCBpbmplY3Qgb2Ygb3B0aW9ucyBiZWZvcmUgZXhwb3J0LiBUaGUgZnVuY3Rpb24gYXR0ZW1wdHNcbiAqIHRvIHN0cmluZ2lmeSB0aGUgcHJvdmlkZWQgb3B0aW9ucyBhbmQgcmVtb3ZlcyB1bm5lY2Vzc2FyeSBjaGFyYWN0ZXJzLFxuICogZW5zdXJpbmcgYSBjbGVhbiBhbmQgZm9ybWF0dGVkIGlucHV0LiBUaGUgcmVzdWx0aW5nIHN0cmluZyBpcyBzYXZlZCBhc1xuICogYSBcInN0cmlnaHQgaW5qZWN0XCIgc3RyaW5nIGluIHRoZSBleHBvcnQgb3B0aW9ucy4gSXQgdGhlbiBpbnZva2VzIHRoZVxuICogZG9FeHBvcnQgZnVuY3Rpb24gd2l0aCB0aGUgdXBkYXRlZCBvcHRpb25zLlxuICpcbiAqIElNUE9SVEFOVDogRGFuZ2Vyb3VzIGFuZCBtdXN0IGJlIHVzZWQgZGVsaWJlcmF0ZWx5IGJ5IHNvbWVvbmUgd2hvIHNldHMgdXBcbiAqIGEgc2VydmVyIChzZWUgdGhlICAtLWFsbG93Q29kZUV4ZWN1dGlvbiBvcHRpb24pLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gVGhlIGV4cG9ydCBvcHRpb25zIGNvbnRhaW5pbmcgdGhlIGlucHV0XG4gKiB0byBiZSBpbmplY3RlZC5cbiAqIEBwYXJhbSB7ZnVuY3Rpb259IGVuZENhbGxiYWNrIC0gVGhlIGNhbGxiYWNrIGZ1bmN0aW9uIHRvIGJlIGludm9rZWRcbiAqIGF0IHRoZSBlbmQgb2YgdGhlIHByb2Nlc3MuXG4gKlxuICogQHJldHVybnMge1Byb21pc2V9IEEgUHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGggdGhlIHJlc3VsdCBvZiB0aGUgZXhwb3J0XG4gKiBvcGVyYXRpb24gb3IgcmVqZWN0cyB3aXRoIGFuIGVycm9yIGlmIGFueSBpc3N1ZXMgb2NjdXIgZHVyaW5nIHRoZSBwcm9jZXNzLlxuICovXG5jb25zdCBkb1N0cmFpZ2h0SW5qZWN0ID0gKG9wdGlvbnMsIGVuZENhbGxiYWNrKSA9PiB7XG4gIHRyeSB7XG4gICAgbGV0IHN0ckluajtcbiAgICBsZXQgaW5zdHIgPSBvcHRpb25zLmV4cG9ydC5pbnN0ciB8fCBvcHRpb25zLmV4cG9ydC5vcHRpb25zO1xuXG4gICAgaWYgKHR5cGVvZiBpbnN0ciAhPT0gJ3N0cmluZycpIHtcbiAgICAgIC8vIFRyeSB0byBzdHJpbmdpZnkgb3B0aW9uc1xuICAgICAgc3RySW5qID0gaW5zdHIgPSBvcHRpb25zU3RyaW5naWZ5KFxuICAgICAgICBpbnN0cixcbiAgICAgICAgb3B0aW9ucy5jdXN0b21Mb2dpYz8uYWxsb3dDb2RlRXhlY3V0aW9uXG4gICAgICApO1xuICAgIH1cbiAgICBzdHJJbmogPSBpbnN0ci5yZXBsYWNlQWxsKC9cXHR8XFxufFxcci9nLCAnJykudHJpbSgpO1xuXG4gICAgLy8gR2V0IHJpZCBvZiB0aGUgO1xuICAgIGlmIChzdHJJbmpbc3RySW5qLmxlbmd0aCAtIDFdID09PSAnOycpIHtcbiAgICAgIHN0ckluaiA9IHN0ckluai5zdWJzdHJpbmcoMCwgc3RySW5qLmxlbmd0aCAtIDEpO1xuICAgIH1cblxuICAgIC8vIFNhdmUgYXMgc3RyaWdodCBpbmplY3Qgc3RyaW5nXG4gICAgb3B0aW9ucy5leHBvcnQuc3RySW5qID0gc3RySW5qO1xuICAgIHJldHVybiBkb0V4cG9ydChvcHRpb25zLCBmYWxzZSwgZW5kQ2FsbGJhY2spO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJldHVybiBlbmRDYWxsYmFjayhcbiAgICAgIG5ldyBFeHBvcnRFcnJvcihcbiAgICAgICAgYFtjaGFydF0gTWFsZm9ybWVkIGlucHV0IGRldGVjdGVkIGZvciAke29wdGlvbnMuZXhwb3J0Py5yZXF1ZXN0SWQgfHwgJz8nfS4gUGxlYXNlIG1ha2Ugc3VyZSB0aGF0IHlvdXIgSlNPTi9KYXZhU2NyaXB0IG9wdGlvbnMgYXJlIHNlbnQgdXNpbmcgdGhlIFwib3B0aW9uc1wiIGF0dHJpYnV0ZSwgYW5kIHRoYXQgaWYgeW91J3JlIHVzaW5nIFNWRywgaXQgaXMgdW5lc2NhcGVkLmBcbiAgICAgICkuc2V0RXJyb3IoZXJyb3IpXG4gICAgKTtcbiAgfVxufTtcblxuLyoqXG4gKiBFeHBvcnRzIGEgc3RyaW5nIGJhc2VkIG9uIHRoZSBwcm92aWRlZCBvcHRpb25zIGFuZCBpbnZva2VzIGFuIGVuZCBjYWxsYmFjay5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nVG9FeHBvcnQgLSBUaGUgc3RyaW5nIGNvbnRlbnQgdG8gYmUgZXhwb3J0ZWQuXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIEV4cG9ydCBvcHRpb25zLCBpbmNsdWRpbmcgY3VzdG9tTG9naWMgd2l0aFxuICogYWxsb3dDb2RlRXhlY3V0aW9uIGZsYWcuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBlbmRDYWxsYmFjayAtIENhbGxiYWNrIGZ1bmN0aW9uIHRvIGJlIGludm9rZWQgYXQgdGhlIGVuZFxuICogb2YgdGhlIGV4cG9ydCBwcm9jZXNzLlxuICpcbiAqIEByZXR1cm5zIHthbnl9IFJlc3VsdCBvZiB0aGUgZXhwb3J0IHByb2Nlc3Mgb3IgYW4gZXJyb3IgaWYgZW5jb3VudGVyZWQuXG4gKi9cbmNvbnN0IGV4cG9ydEFzU3RyaW5nID0gKHN0cmluZ1RvRXhwb3J0LCBvcHRpb25zLCBlbmRDYWxsYmFjaykgPT4ge1xuICBjb25zdCB7IGFsbG93Q29kZUV4ZWN1dGlvbiB9ID0gb3B0aW9ucy5jdXN0b21Mb2dpYztcblxuICAvLyBDaGVjayBpZiBpdCBpcyBTVkdcbiAgaWYgKFxuICAgIHN0cmluZ1RvRXhwb3J0LmluZGV4T2YoJzxzdmcnKSA+PSAwIHx8XG4gICAgc3RyaW5nVG9FeHBvcnQuaW5kZXhPZignPD94bWwnKSA+PSAwXG4gICkge1xuICAgIGxvZyg0LCAnW2NoYXJ0XSBQYXJzaW5nIGlucHV0IGFzIFNWRy4nKTtcbiAgICByZXR1cm4gZG9FeHBvcnQob3B0aW9ucywgZmFsc2UsIGVuZENhbGxiYWNrLCBzdHJpbmdUb0V4cG9ydCk7XG4gIH1cblxuICB0cnkge1xuICAgIC8vIFRyeSB0byBwYXJzZSB0byBKU09OIGFuZCBjYWxsIHRoZSBkb0V4cG9ydCBmdW5jdGlvblxuICAgIGNvbnN0IGNoYXJ0SlNPTiA9IEpTT04ucGFyc2Uoc3RyaW5nVG9FeHBvcnQucmVwbGFjZUFsbCgvXFx0fFxcbnxcXHIvZywgJyAnKSk7XG5cbiAgICAvLyBJZiBhIGNvcnJlY3QgSlNPTiwgZG8gdGhlIGV4cG9ydFxuICAgIHJldHVybiBkb0V4cG9ydChvcHRpb25zLCBjaGFydEpTT04sIGVuZENhbGxiYWNrKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAvLyBOb3QgYSB2YWxpZCBKU09OXG4gICAgaWYgKHRvQm9vbGVhbihhbGxvd0NvZGVFeGVjdXRpb24pKSB7XG4gICAgICByZXR1cm4gZG9TdHJhaWdodEluamVjdChvcHRpb25zLCBlbmRDYWxsYmFjayk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIERvIG5vdCBhbGxvdyBzdHJhaWdodCBpbmplY3Rpb24gd2l0aG91dCB0aGUgYWxsb3dDb2RlRXhlY3V0aW9uIGZsYWdcbiAgICAgIHJldHVybiBlbmRDYWxsYmFjayhcbiAgICAgICAgbmV3IEV4cG9ydEVycm9yKFxuICAgICAgICAgICdbY2hhcnRdIE9ubHkgSlNPTiBjb25maWd1cmF0aW9ucyBhbmQgU1ZHIGFyZSBhbGxvd2VkIGZvciB0aGlzIHNlcnZlci4gSWYgdGhpcyBpcyB5b3VyIHNlcnZlciwgSmF2YVNjcmlwdCBjdXN0b20gY29kZSBjYW4gYmUgZW5hYmxlZCBieSBzdGFydGluZyB0aGUgc2VydmVyIHdpdGggdGhlIC0tYWxsb3dDb2RlRXhlY3V0aW9uIGZsYWcuJ1xuICAgICAgICApLnNldEVycm9yKGVycm9yKVxuICAgICAgKTtcbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogUmV0cmlldmVzIGFuZCByZXR1cm5zIHRoZSBjdXJyZW50IHN0YXR1cyBvZiBjb2RlIGV4ZWN1dGlvbiBwZXJtaXNzaW9uLlxuICpcbiAqIEByZXR1cm5zIHthbnl9IFRoZSB2YWx1ZSBvZiBhbGxvd0NvZGVFeGVjdXRpb24uXG4gKi9cbmV4cG9ydCBjb25zdCBnZXRBbGxvd0NvZGVFeGVjdXRpb24gPSAoKSA9PiBhbGxvd0NvZGVFeGVjdXRpb247XG5cbi8qKlxuICogU2V0cyB0aGUgY29kZSBleGVjdXRpb24gcGVybWlzc2lvbiBiYXNlZCBvbiB0aGUgcHJvdmlkZWQgYm9vbGVhbiB2YWx1ZS5cbiAqXG4gKiBAcGFyYW0ge2FueX0gdmFsdWUgLSBUaGUgdmFsdWUgdG8gYmUgY29udmVydGVkIGFuZCBhc3NpZ25lZFxuICogdG8gYWxsb3dDb2RlRXhlY3V0aW9uLlxuICovXG5leHBvcnQgY29uc3Qgc2V0QWxsb3dDb2RlRXhlY3V0aW9uID0gKHZhbHVlKSA9PiB7XG4gIGFsbG93Q29kZUV4ZWN1dGlvbiA9IHRvQm9vbGVhbih2YWx1ZSk7XG59O1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIGJhdGNoRXhwb3J0LFxuICBzaW5nbGVFeHBvcnQsXG4gIGdldEFsbG93Q29kZUV4ZWN1dGlvbixcbiAgc2V0QWxsb3dDb2RlRXhlY3V0aW9uLFxuICBzdGFydEV4cG9ydCxcbiAgZmluZENoYXJ0U2l6ZVxufTtcbiIsIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG5cbkhpZ2hjaGFydHMgRXhwb3J0IFNlcnZlclxuXG5Db3B5cmlnaHQgKGMpIDIwMTYtMjAyNCwgSGlnaHNvZnRcblxuTGljZW5jZWQgdW5kZXIgdGhlIE1JVCBsaWNlbmNlLlxuXG5BZGRpdGlvbmFsbHkgYSB2YWxpZCBIaWdoY2hhcnRzIGxpY2Vuc2UgaXMgcmVxdWlyZWQgZm9yIHVzZS5cblxuU2VlIExJQ0VOU0UgZmlsZSBpbiByb290IGZvciBkZXRhaWxzLlxuXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG4vKipcbiAqIEBvdmVydmlldyBVc2VkIHRvIHNhbml0aXplIHRoZSBzdHJpbmdzIGNvbWluZyBmcm9tIHRoZSBleHBvcnRpbmcgbW9kdWxlXG4gKiB0byBwcmV2ZW50IFhTUyBhdHRhY2tzICh3aXRoIHRoZSBET01QdXJpZnkgbGlicmFyeSkuXG4gKiovXG5cbmltcG9ydCB7IEpTRE9NIH0gZnJvbSAnanNkb20nO1xuaW1wb3J0IERPTVB1cmlmeSBmcm9tICdkb21wdXJpZnknO1xuXG5pbXBvcnQgeyBlbnZzIH0gZnJvbSAnLi9lbnZzLmpzJztcbi8qKlxuICogU2FuaXRpemVzIGEgZ2l2ZW4gSFRNTCBzdHJpbmcgYnkgcmVtb3ZpbmcgPHNjcmlwdD4gdGFncy5cbiAqIFRoaXMgZnVuY3Rpb24gdXNlcyBhIHJlZ3VsYXIgZXhwcmVzc2lvbiB0byBmaW5kIGFuZCByZW1vdmUgYWxsXG4gKiBvY2N1cnJlbmNlcyBvZiA8c2NyaXB0Pi4uLjwvc2NyaXB0PiB0YWdzIGFuZCBhbnkgY29udGVudCB3aXRoaW4gdGhlbS5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gaW5wdXQgVGhlIEhUTUwgc3RyaW5nIHRvIGJlIHNhbml0aXplZC5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBzYW5pdGl6ZWQgSFRNTCBzdHJpbmcuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzYW5pdGl6ZShpbnB1dCkge1xuICBjb25zdCBmb3JiaWRkZW4gPSBbXTtcblxuICBpZiAoIWVudnMuT1RIRVJfQUxMT1dfWExJTkspIHtcbiAgICBmb3JiaWRkZW4ucHVzaCgneGxpbms6aHJlZicpO1xuICB9XG5cbiAgY29uc3Qgd2luZG93ID0gbmV3IEpTRE9NKCcnKS53aW5kb3c7XG4gIGNvbnN0IHB1cmlmeSA9IERPTVB1cmlmeSh3aW5kb3cpO1xuICByZXR1cm4gcHVyaWZ5LnNhbml0aXplKGlucHV0LCB7XG4gICAgQUREX1RBR1M6IFsnZm9yZWlnbk9iamVjdCddLFxuICAgIEZPUkJJRF9BVFRSOiBmb3JiaWRkZW5cbiAgfSk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IHNhbml0aXplO1xuIiwiLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcblxuSGlnaGNoYXJ0cyBFeHBvcnQgU2VydmVyXG5cbkNvcHlyaWdodCAoYykgMjAxNi0yMDI0LCBIaWdoc29mdFxuXG5MaWNlbmNlZCB1bmRlciB0aGUgTUlUIGxpY2VuY2UuXG5cbkFkZGl0aW9uYWxseSBhIHZhbGlkIEhpZ2hjaGFydHMgbGljZW5zZSBpcyByZXF1aXJlZCBmb3IgdXNlLlxuXG5TZWUgTElDRU5TRSBmaWxlIGluIHJvb3QgZm9yIGRldGFpbHMuXG5cbioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG5cbmltcG9ydCB7IGxvZyB9IGZyb20gJy4vbG9nZ2VyLmpzJztcblxuLy8gQXJyYXkgdGhhdCBjb250YWlucyBpZHMgb2YgYWxsIG9uZ29pbmcgaW50ZXJ2YWxzXG5jb25zdCBpbnRlcnZhbElkcyA9IFtdO1xuXG4vKipcbiAqIEFkZHMgaWQgb2YgYSBzZXRJbnRlcnZhbCB0byB0aGUgaW50ZXJ2YWxJZHMgYXJyYXkuXG4gKlxuICogQHBhcmFtIHtOb2RlSlMuVGltZW91dH0gaWQgLSBJZCBvZiBhbiBpbnRlcnZhbC5cbiAqL1xuZXhwb3J0IGNvbnN0IGFkZEludGVydmFsID0gKGlkKSA9PiB7XG4gIGludGVydmFsSWRzLnB1c2goaWQpO1xufTtcblxuLyoqXG4gKiBDbGVhcnMgYWxsIG9mIG9uZ29pbmcgaW50ZXJ2YWxzIGJ5IGlkcyBnYXRoZXJlZCBpbiB0aGUgaW50ZXJ2YWxJZHMgYXJyYXkuXG4gKi9cbmV4cG9ydCBjb25zdCBjbGVhckFsbEludGVydmFscyA9ICgpID0+IHtcbiAgbG9nKDQsIGBbc2VydmVyXSBDbGVhcmluZyBhbGwgcmVnaXN0ZXJlZCBpbnRlcnZhbHMuYCk7XG4gIGZvciAoY29uc3QgaWQgb2YgaW50ZXJ2YWxJZHMpIHtcbiAgICBjbGVhckludGVydmFsKGlkKTtcbiAgfVxufTtcblxuZXhwb3J0IGRlZmF1bHQge1xuICBhZGRJbnRlcnZhbCxcbiAgY2xlYXJBbGxJbnRlcnZhbHNcbn07XG4iLCJpbXBvcnQgeyBlbnZzIH0gZnJvbSAnLi4vZW52cy5qcyc7XG5pbXBvcnQgeyBsb2dXaXRoU3RhY2sgfSBmcm9tICcuLi9sb2dnZXIuanMnO1xuXG4vKipcbiAqIE1pZGRsZXdhcmUgZm9yIGxvZ2dpbmcgZXJyb3JzIHdpdGggc3RhY2sgdHJhY2UgYW5kIGhhbmRsaW5nIGVycm9yIHJlc3BvbnNlLlxuICpcbiAqIEBwYXJhbSB7RXJyb3J9IGVycm9yIC0gVGhlIGVycm9yIG9iamVjdC5cbiAqIEBwYXJhbSB7RXhwcmVzcy5SZXF1ZXN0fSByZXEgLSBUaGUgRXhwcmVzcyByZXF1ZXN0IG9iamVjdC5cbiAqIEBwYXJhbSB7RXhwcmVzcy5SZXNwb25zZX0gcmVzIC0gVGhlIEV4cHJlc3MgcmVzcG9uc2Ugb2JqZWN0LlxuICogQHBhcmFtIHtGdW5jdGlvbn0gbmV4dCAtIFRoZSBuZXh0IG1pZGRsZXdhcmUgZnVuY3Rpb24uXG4gKi9cbmNvbnN0IGxvZ0Vycm9yTWlkZGxld2FyZSA9IChlcnJvciwgcmVxLCByZXMsIG5leHQpID0+IHtcbiAgLy8gRGlzcGxheSB0aGUgZXJyb3Igd2l0aCBzdGFjayBpbiBhIGNvcnJlY3QgZm9ybWF0XG4gIGxvZ1dpdGhTdGFjaygxLCBlcnJvcik7XG5cbiAgLy8gRGVsZXRlIHRoZSBzdGFjayBmb3IgdGhlIGVudmlyb25tZW50IG90aGVyIHRoYW4gdGhlIGRldmVsb3BtZW50XG4gIGlmIChlbnZzLk9USEVSX05PREVfRU5WICE9PSAnZGV2ZWxvcG1lbnQnKSB7XG4gICAgZGVsZXRlIGVycm9yLnN0YWNrO1xuICB9XG5cbiAgLy8gQ2FsbCB0aGUgcmV0dXJuRXJyb3JNaWRkbGV3YXJlXG4gIG5leHQoZXJyb3IpO1xufTtcblxuLyoqXG4gKiBNaWRkbGV3YXJlIGZvciByZXR1cm5pbmcgZXJyb3IgcmVzcG9uc2UuXG4gKlxuICogQHBhcmFtIHtFcnJvcn0gZXJyb3IgLSBUaGUgZXJyb3Igb2JqZWN0LlxuICogQHBhcmFtIHtFeHByZXNzLlJlcXVlc3R9IHJlcSAtIFRoZSBFeHByZXNzIHJlcXVlc3Qgb2JqZWN0LlxuICogQHBhcmFtIHtFeHByZXNzLlJlc3BvbnNlfSByZXMgLSBUaGUgRXhwcmVzcyByZXNwb25zZSBvYmplY3QuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBuZXh0IC0gVGhlIG5leHQgbWlkZGxld2FyZSBmdW5jdGlvbi5cbiAqL1xuY29uc3QgcmV0dXJuRXJyb3JNaWRkbGV3YXJlID0gKGVycm9yLCByZXEsIHJlcywgbmV4dCkgPT4ge1xuICAvLyBHYXRoZXIgYWxsIHJlcXVpZWQgaW5mb3JtYXRpb24gZm9yIHRoZSByZXNwb25zZVxuICBjb25zdCB7IHN0YXR1c0NvZGU6IHN0Q29kZSwgc3RhdHVzLCBtZXNzYWdlLCBzdGFjayB9ID0gZXJyb3I7XG4gIGNvbnN0IHN0YXR1c0NvZGUgPSBzdENvZGUgfHwgc3RhdHVzIHx8IDQwMDtcblxuICAvLyBTZXQgYW5kIHJldHVybiByZXNwb25zZVxuICByZXMuc3RhdHVzKHN0YXR1c0NvZGUpLmpzb24oeyBzdGF0dXNDb2RlLCBtZXNzYWdlLCBzdGFjayB9KTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IChhcHApID0+IHtcbiAgLy8gQWRkIGxvZyBlcnJvciBtaWRkbGV3YXJlXG4gIGFwcC51c2UobG9nRXJyb3JNaWRkbGV3YXJlKTtcblxuICAvLyBBZGQgc2V0IHN0YXR1cyBhbmQgcmV0dXJuIGVycm9yIG1pZGRsZXdhcmVcbiAgYXBwLnVzZShyZXR1cm5FcnJvck1pZGRsZXdhcmUpO1xufTtcbiIsIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG5cbkhpZ2hjaGFydHMgRXhwb3J0IFNlcnZlclxuXG5Db3B5cmlnaHQgKGMpIDIwMTYtMjAyNCwgSGlnaHNvZnRcblxuTGljZW5jZWQgdW5kZXIgdGhlIE1JVCBsaWNlbmNlLlxuXG5BZGRpdGlvbmFsbHkgYSB2YWxpZCBIaWdoY2hhcnRzIGxpY2Vuc2UgaXMgcmVxdWlyZWQgZm9yIHVzZS5cblxuU2VlIExJQ0VOU0UgZmlsZSBpbiByb290IGZvciBkZXRhaWxzLlxuXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG5pbXBvcnQgcmF0ZUxpbWl0IGZyb20gJ2V4cHJlc3MtcmF0ZS1saW1pdCc7XG5cbmltcG9ydCB7IGxvZyB9IGZyb20gJy4uL2xvZ2dlci5qcyc7XG5cbi8qKlxuICogTWlkZGxld2FyZSBmb3IgZW5hYmxpbmcgcmF0ZSBsaW1pdGluZyBvbiB0aGUgc3BlY2lmaWVkIEV4cHJlc3MgYXBwLlxuICpcbiAqIEBwYXJhbSB7RXhwcmVzc30gYXBwIC0gVGhlIEV4cHJlc3MgYXBwIGluc3RhbmNlLlxuICogQHBhcmFtIHtPYmplY3R9IGxpbWl0Q29uZmlnIC0gQ29uZmlndXJhdGlvbiBvcHRpb25zIGZvciByYXRlIGxpbWl0aW5nLlxuICovXG5leHBvcnQgZGVmYXVsdCAoYXBwLCBsaW1pdENvbmZpZykgPT4ge1xuICBjb25zdCBtc2cgPVxuICAgICdUb28gbWFueSByZXF1ZXN0cywgeW91IGhhdmUgYmVlbiByYXRlIGxpbWl0ZWQuIFBsZWFzZSB0cnkgYWdhaW4gbGF0ZXIuJztcblxuICAvLyBPcHRpb25zIGZvciB0aGUgcmF0ZSBsaW1pdGVyXG4gIGNvbnN0IHJhdGVPcHRpb25zID0ge1xuICAgIG1heDogbGltaXRDb25maWcubWF4UmVxdWVzdHMgfHwgMzAsXG4gICAgd2luZG93OiBsaW1pdENvbmZpZy53aW5kb3cgfHwgMSxcbiAgICBkZWxheTogbGltaXRDb25maWcuZGVsYXkgfHwgMCxcbiAgICB0cnVzdFByb3h5OiBsaW1pdENvbmZpZy50cnVzdFByb3h5IHx8IGZhbHNlLFxuICAgIHNraXBLZXk6IGxpbWl0Q29uZmlnLnNraXBLZXkgfHwgZmFsc2UsXG4gICAgc2tpcFRva2VuOiBsaW1pdENvbmZpZy5za2lwVG9rZW4gfHwgZmFsc2VcbiAgfTtcblxuICAvLyBTZXQgaWYgYmVoaW5kIGEgcHJveHlcbiAgaWYgKHJhdGVPcHRpb25zLnRydXN0UHJveHkpIHtcbiAgICBhcHAuZW5hYmxlKCd0cnVzdCBwcm94eScpO1xuICB9XG5cbiAgLy8gQ3JlYXRlIGEgbGltaXRlclxuICBjb25zdCBsaW1pdGVyID0gcmF0ZUxpbWl0KHtcbiAgICB3aW5kb3dNczogcmF0ZU9wdGlvbnMud2luZG93ICogNjAgKiAxMDAwLFxuICAgIC8vIExpbWl0IGVhY2ggSVAgdG8gMTAwIHJlcXVlc3RzIHBlciB3aW5kb3dNc1xuICAgIG1heDogcmF0ZU9wdGlvbnMubWF4LFxuICAgIC8vIERpc2FibGUgZGVsYXlpbmcsIGZ1bGwgc3BlZWQgdW50aWwgdGhlIG1heCBsaW1pdCBpcyByZWFjaGVkXG4gICAgZGVsYXlNczogcmF0ZU9wdGlvbnMuZGVsYXksXG4gICAgaGFuZGxlcjogKHJlcXVlc3QsIHJlc3BvbnNlKSA9PiB7XG4gICAgICByZXNwb25zZS5mb3JtYXQoe1xuICAgICAgICBqc29uOiAoKSA9PiB7XG4gICAgICAgICAgcmVzcG9uc2Uuc3RhdHVzKDQyOSkuc2VuZCh7IG1lc3NhZ2U6IG1zZyB9KTtcbiAgICAgICAgfSxcbiAgICAgICAgZGVmYXVsdDogKCkgPT4ge1xuICAgICAgICAgIHJlc3BvbnNlLnN0YXR1cyg0MjkpLnNlbmQobXNnKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSxcbiAgICBza2lwOiAocmVxdWVzdCkgPT4ge1xuICAgICAgLy8gQWxsb3cgYnlwYXNzaW5nIHRoZSBsaW1pdGVyIGlmIGEgdmFsaWQga2V5L3Rva2VuIGhhcyBiZWVuIHNlbnRcbiAgICAgIGlmIChcbiAgICAgICAgcmF0ZU9wdGlvbnMuc2tpcEtleSAhPT0gZmFsc2UgJiZcbiAgICAgICAgcmF0ZU9wdGlvbnMuc2tpcFRva2VuICE9PSBmYWxzZSAmJlxuICAgICAgICByZXF1ZXN0LnF1ZXJ5LmtleSA9PT0gcmF0ZU9wdGlvbnMuc2tpcEtleSAmJlxuICAgICAgICByZXF1ZXN0LnF1ZXJ5LmFjY2Vzc190b2tlbiA9PT0gcmF0ZU9wdGlvbnMuc2tpcFRva2VuXG4gICAgICApIHtcbiAgICAgICAgbG9nKDQsICdbcmF0ZSBsaW1pdGluZ10gU2tpcHBpbmcgcmF0ZSBsaW1pdGVyLicpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIFVzZSBhIGxpbWl0ZXIgYXMgYSBtaWRkbGV3YXJlXG4gIGFwcC51c2UobGltaXRlcik7XG5cbiAgbG9nKFxuICAgIDMsXG4gICAgYFtyYXRlIGxpbWl0aW5nXSBFbmFibGVkIHJhdGUgbGltaXRpbmcgd2l0aCAke3JhdGVPcHRpb25zLm1heH0gcmVxdWVzdHMgcGVyICR7cmF0ZU9wdGlvbnMud2luZG93fSBtaW51dGUgZm9yIGVhY2ggSVAsIHRydXN0aW5nIHByb3h5OiAke3JhdGVPcHRpb25zLnRydXN0UHJveHl9LmBcbiAgKTtcbn07XG4iLCJpbXBvcnQgRXhwb3J0RXJyb3IgZnJvbSAnLi9FeHBvcnRFcnJvci5qcyc7XG5cbmNsYXNzIEh0dHBFcnJvciBleHRlbmRzIEV4cG9ydEVycm9yIHtcbiAgY29uc3RydWN0b3IobWVzc2FnZSwgc3RhdHVzKSB7XG4gICAgc3VwZXIobWVzc2FnZSk7XG4gICAgdGhpcy5zdGF0dXMgPSB0aGlzLnN0YXR1c0NvZGUgPSBzdGF0dXM7XG4gIH1cblxuICBzZXRTdGF0dXMoc3RhdHVzKSB7XG4gICAgdGhpcy5zdGF0dXMgPSBzdGF0dXM7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgSHR0cEVycm9yO1xuIiwiLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcblxuSGlnaGNoYXJ0cyBFeHBvcnQgU2VydmVyXG5cbkNvcHlyaWdodCAoYykgMjAxNi0yMDI0LCBIaWdoc29mdFxuXG5MaWNlbmNlZCB1bmRlciB0aGUgTUlUIGxpY2VuY2UuXG5cbkFkZGl0aW9uYWxseSBhIHZhbGlkIEhpZ2hjaGFydHMgbGljZW5zZSBpcyByZXF1aXJlZCBmb3IgdXNlLlxuXG5TZWUgTElDRU5TRSBmaWxlIGluIHJvb3QgZm9yIGRldGFpbHMuXG5cbioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG5cbmltcG9ydCB7IHVwZGF0ZVZlcnNpb24sIHZlcnNpb24gfSBmcm9tICcuLi8uLi9jYWNoZS5qcyc7XG5pbXBvcnQgeyBlbnZzIH0gZnJvbSAnLi4vLi4vZW52cy5qcyc7XG5cbmltcG9ydCBIdHRwRXJyb3IgZnJvbSAnLi4vLi4vZXJyb3JzL0h0dHBFcnJvci5qcyc7XG5cbi8qKlxuICogQWRkcyB0aGUgUE9TVCAvY2hhbmdlX2hjX3ZlcnNpb24vOm5ld1ZlcnNpb24gcm91dGUgdGhhdCBjYW4gYmUgdXRpbGl6ZWQgdG8gbW9kaWZ5XG4gKiB0aGUgSGlnaGNoYXJ0cyB2ZXJzaW9uIG9uIHRoZSBzZXJ2ZXIuXG4gKlxuICogVE9ETzogQWRkIGF1dGggdG9rZW4gYW5kIGNvbm5lY3QgdG8gQVBJXG4gKi9cbmV4cG9ydCBkZWZhdWx0IChhcHApID0+XG4gICFhcHBcbiAgICA/IGZhbHNlXG4gICAgOiBhcHAucG9zdChcbiAgICAgICAgJy92ZXJzaW9uL2NoYW5nZS86bmV3VmVyc2lvbicsXG4gICAgICAgIGFzeW5jIChyZXF1ZXN0LCByZXNwb25zZSwgbmV4dCkgPT4ge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBhZG1pblRva2VuID0gZW52cy5ISUdIQ0hBUlRTX0FETUlOX1RPS0VOO1xuXG4gICAgICAgICAgICAvLyBDaGVjayB0aGUgZXhpc3RlbmNlIG9mIHRoZSB0b2tlblxuICAgICAgICAgICAgaWYgKCFhZG1pblRva2VuIHx8ICFhZG1pblRva2VuLmxlbmd0aCkge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgSHR0cEVycm9yKFxuICAgICAgICAgICAgICAgICdUaGUgc2VydmVyIGlzIG5vdCBjb25maWd1cmVkIHRvIHBlcmZvcm0gcnVuLXRpbWUgdmVyc2lvbiBjaGFuZ2VzOiBISUdIQ0hBUlRTX0FETUlOX1RPS0VOIGlzIG5vdCBzZXQuJyxcbiAgICAgICAgICAgICAgICA0MDFcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIGhjLWF1dGggaGVhZGVyIGNvbnRhaW4gYSBjb3JyZWN0IHRva2VuXG4gICAgICAgICAgICBjb25zdCB0b2tlbiA9IHJlcXVlc3QuZ2V0KCdoYy1hdXRoJyk7XG4gICAgICAgICAgICBpZiAoIXRva2VuIHx8IHRva2VuICE9PSBhZG1pblRva2VuKSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBIdHRwRXJyb3IoXG4gICAgICAgICAgICAgICAgJ0ludmFsaWQgb3IgbWlzc2luZyB0b2tlbjogU2V0IHRoZSB0b2tlbiBpbiB0aGUgaGMtYXV0aCBoZWFkZXIuJyxcbiAgICAgICAgICAgICAgICA0MDFcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQ29tcGFyZSB2ZXJzaW9uc1xuICAgICAgICAgICAgY29uc3QgbmV3VmVyc2lvbiA9IHJlcXVlc3QucGFyYW1zLm5ld1ZlcnNpb247XG4gICAgICAgICAgICBpZiAobmV3VmVyc2lvbikge1xuICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tbmFtZWQtYXMtZGVmYXVsdC1tZW1iZXJcbiAgICAgICAgICAgICAgICBhd2FpdCB1cGRhdGVWZXJzaW9uKG5ld1ZlcnNpb24pO1xuICAgICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBIdHRwRXJyb3IoXG4gICAgICAgICAgICAgICAgICBgVmVyc2lvbiBjaGFuZ2U6ICR7ZXJyb3IubWVzc2FnZX1gLFxuICAgICAgICAgICAgICAgICAgZXJyb3Iuc3RhdHVzQ29kZVxuICAgICAgICAgICAgICAgICkuc2V0RXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgLy8gU3VjY2Vzc1xuICAgICAgICAgICAgICByZXNwb25zZS5zdGF0dXMoMjAwKS5zZW5kKHtcbiAgICAgICAgICAgICAgICBzdGF0dXNDb2RlOiAyMDAsXG4gICAgICAgICAgICAgICAgdmVyc2lvbjogdmVyc2lvbigpLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGBTdWNjZXNzZnVsbHkgdXBkYXRlZCBIaWdoY2hhcnRzIHRvIHZlcnNpb246ICR7bmV3VmVyc2lvbn0uYFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIC8vIE5vIHZlcnNpb24gc3BlY2lmaWVkXG4gICAgICAgICAgICAgIHRocm93IG5ldyBIdHRwRXJyb3IoJ05vIG5ldyB2ZXJzaW9uIHN1cHBsaWVkLicsIDQwMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIG5leHQoZXJyb3IpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiIsIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG5cbkhpZ2hjaGFydHMgRXhwb3J0IFNlcnZlclxuXG5Db3B5cmlnaHQgKGMpIDIwMTYtMjAyNCwgSGlnaHNvZnRcblxuTGljZW5jZWQgdW5kZXIgdGhlIE1JVCBsaWNlbmNlLlxuXG5BZGRpdGlvbmFsbHkgYSB2YWxpZCBIaWdoY2hhcnRzIGxpY2Vuc2UgaXMgcmVxdWlyZWQgZm9yIHVzZS5cblxuU2VlIExJQ0VOU0UgZmlsZSBpbiByb290IGZvciBkZXRhaWxzLlxuXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG5pbXBvcnQgeyB2NCBhcyB1dWlkIH0gZnJvbSAndXVpZCc7XG5cbmltcG9ydCB7IGdldEFsbG93Q29kZUV4ZWN1dGlvbiwgc3RhcnRFeHBvcnQgfSBmcm9tICcuLi8uLi9jaGFydC5qcyc7XG5pbXBvcnQgeyBnZXRPcHRpb25zLCBtZXJnZUNvbmZpZ09wdGlvbnMgfSBmcm9tICcuLi8uLi9jb25maWcuanMnO1xuaW1wb3J0IHsgbG9nIH0gZnJvbSAnLi4vLi4vbG9nZ2VyLmpzJztcbmltcG9ydCB7XG4gIGZpeFR5cGUsXG4gIGlzQ29ycmVjdEpTT04sXG4gIGlzT2JqZWN0RW1wdHksXG4gIGlzUHJpdmF0ZVJhbmdlVXJsRm91bmQsXG4gIG9wdGlvbnNTdHJpbmdpZnksXG4gIG1lYXN1cmVUaW1lXG59IGZyb20gJy4uLy4uL3V0aWxzLmpzJztcblxuaW1wb3J0IEh0dHBFcnJvciBmcm9tICcuLi8uLi9lcnJvcnMvSHR0cEVycm9yLmpzJztcblxuLy8gUmV2ZXJzZWQgTUlNRSB0eXBlc1xuY29uc3QgcmV2ZXJzZWRNaW1lID0ge1xuICBwbmc6ICdpbWFnZS9wbmcnLFxuICBqcGVnOiAnaW1hZ2UvanBlZycsXG4gIGdpZjogJ2ltYWdlL2dpZicsXG4gIHBkZjogJ2FwcGxpY2F0aW9uL3BkZicsXG4gIHN2ZzogJ2ltYWdlL3N2Zyt4bWwnXG59O1xuXG4vLyBUaGUgcmVxdWVzdHMgY291bnRlclxubGV0IHJlcXVlc3RzQ291bnRlciA9IDA7XG5cbi8vIFRoZSBhcnJheSBvZiBjYWxsYmFja3MgdG8gY2FsbCBiZWZvcmUgYSByZXF1ZXN0XG5jb25zdCBiZWZvcmVSZXF1ZXN0ID0gW107XG5cbi8vIFRoZSBhcnJheSBvZiBjYWxsYmFja3MgdG8gY2FsbCBhZnRlciBhIHJlcXVlc3RcbmNvbnN0IGFmdGVyUmVxdWVzdCA9IFtdO1xuXG4vKipcbiAqIEludm9rZXMgYW4gYXJyYXkgb2YgY2FsbGJhY2sgZnVuY3Rpb25zIHdpdGggc3BlY2lmaWVkIHBhcmFtZXRlcnMsIGFsbG93aW5nXG4gKiBjdXN0b21pemF0aW9uIG9mIHJlcXVlc3QgaGFuZGxpbmcuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbltdfSBjYWxsYmFja3MgLSBBbiBhcnJheSBvZiBjYWxsYmFjayBmdW5jdGlvbnNcbiAqIHRvIGJlIGV4ZWN1dGVkLlxuICogQHBhcmFtIHtFeHByZXNzLlJlcXVlc3R9IHJlcXVlc3QgLSBUaGUgRXhwcmVzcyByZXF1ZXN0IG9iamVjdC5cbiAqIEBwYXJhbSB7RXhwcmVzcy5SZXNwb25zZX0gcmVzcG9uc2UgLSBUaGUgRXhwcmVzcyByZXNwb25zZSBvYmplY3QuXG4gKiBAcGFyYW0ge09iamVjdH0gZGF0YSAtIEFuIG9iamVjdCBjb250YWluaW5nIHBhcmFtZXRlcnMgbGlrZSBpZCwgdW5pcXVlSWQsXG4gKiB0eXBlLCBhbmQgYm9keS5cbiAqXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBSZXR1cm5zIGEgYm9vbGVhbiBpbmRpY2F0aW5nIHRoZSBvdmVyYWxsIHJlc3VsdFxuICogb2YgdGhlIGNhbGxiYWNrIGludm9jYXRpb25zLlxuICovXG5jb25zdCBkb0NhbGxiYWNrcyA9IChjYWxsYmFja3MsIHJlcXVlc3QsIHJlc3BvbnNlLCBkYXRhKSA9PiB7XG4gIGxldCByZXN1bHQgPSB0cnVlO1xuICBjb25zdCB7IGlkLCB1bmlxdWVJZCwgdHlwZSwgYm9keSB9ID0gZGF0YTtcblxuICBjYWxsYmFja3Muc29tZSgoY2FsbGJhY2spID0+IHtcbiAgICBpZiAoY2FsbGJhY2spIHtcbiAgICAgIGxldCBjYWxsUmVzcG9uc2UgPSBjYWxsYmFjayhyZXF1ZXN0LCByZXNwb25zZSwgaWQsIHVuaXF1ZUlkLCB0eXBlLCBib2R5KTtcblxuICAgICAgaWYgKGNhbGxSZXNwb25zZSAhPT0gdW5kZWZpbmVkICYmIGNhbGxSZXNwb25zZSAhPT0gdHJ1ZSkge1xuICAgICAgICByZXN1bHQgPSBjYWxsUmVzcG9uc2U7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cbi8qKlxuICogSGFuZGxlcyB0aGUgZXhwb3J0IHJlcXVlc3RzIGZyb20gdGhlIGNsaWVudC5cbiAqXG4gKiBAcGFyYW0ge0V4cHJlc3MuUmVxdWVzdH0gcmVxdWVzdCAtIFRoZSBFeHByZXNzIHJlcXVlc3Qgb2JqZWN0LlxuICogQHBhcmFtIHtFeHByZXNzLlJlc3BvbnNlfSByZXNwb25zZSAtIFRoZSBFeHByZXNzIHJlc3BvbnNlIG9iamVjdC5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IG5leHQgLSBUaGUgbmV4dCBtaWRkbGV3YXJlIGZ1bmN0aW9uLlxuICpcbiAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIG9uY2UgdGhlIGV4cG9ydCBwcm9jZXNzXG4gKiBpcyBjb21wbGV0ZS5cbiAqL1xuY29uc3QgZXhwb3J0SGFuZGxlciA9IGFzeW5jIChyZXF1ZXN0LCByZXNwb25zZSwgbmV4dCkgPT4ge1xuICB0cnkge1xuICAgIC8vIFN0YXJ0IGNvdW50aW5nIHRpbWVcbiAgICBjb25zdCBzdG9wQ291bnRlciA9IG1lYXN1cmVUaW1lKCk7XG5cbiAgICAvLyBDcmVhdGUgYSB1bmlxdWUgSUQgZm9yIGEgcmVxdWVzdFxuICAgIGNvbnN0IHVuaXF1ZUlkID0gdXVpZCgpLnJlcGxhY2UoLy0vZywgJycpO1xuXG4gICAgLy8gR2V0IHRoZSBjdXJyZW50IHNlcnZlcidzIGdlbmVyYWwgb3B0aW9uc1xuICAgIGNvbnN0IGRlZmF1bHRPcHRpb25zID0gZ2V0T3B0aW9ucygpO1xuXG4gICAgY29uc3QgYm9keSA9IHJlcXVlc3QuYm9keTtcbiAgICBjb25zdCBpZCA9ICsrcmVxdWVzdHNDb3VudGVyO1xuXG4gICAgbGV0IHR5cGUgPSBmaXhUeXBlKGJvZHkudHlwZSk7XG5cbiAgICAvLyBUaHJvdyAnQmFkIFJlcXVlc3QnIGlmIHRoZXJlJ3Mgbm8gYm9keVxuICAgIGlmICghYm9keSB8fCBpc09iamVjdEVtcHR5KGJvZHkpKSB7XG4gICAgICB0aHJvdyBuZXcgSHR0cEVycm9yKFxuICAgICAgICAnVGhlIHJlcXVlc3QgYm9keSBpcyByZXF1aXJlZC4gUGxlYXNlIGVuc3VyZSB0aGF0IHlvdXIgQ29udGVudC1UeXBlIGhlYWRlciBpcyBjb3JyZWN0IChhY2NlcHRlZCB0eXBlcyBhcmUgYXBwbGljYXRpb24vanNvbiBhbmQgbXVsdGlwYXJ0L2Zvcm0tZGF0YSkuJyxcbiAgICAgICAgNDAwXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIEFsbCBvZiB0aGUgYmVsb3cgY2FuIGJlIHVzZWRcbiAgICBsZXQgaW5zdHIgPSBpc0NvcnJlY3RKU09OKGJvZHkuaW5maWxlIHx8IGJvZHkub3B0aW9ucyB8fCBib2R5LmRhdGEpO1xuXG4gICAgLy8gVGhyb3cgJ0JhZCBSZXF1ZXN0JyBpZiB0aGVyZSdzIG5vIEpTT04gb3IgU1ZHIHRvIGV4cG9ydFxuICAgIGlmICghaW5zdHIgJiYgIWJvZHkuc3ZnKSB7XG4gICAgICBsb2coXG4gICAgICAgIDIsXG4gICAgICAgIGBUaGUgcmVxdWVzdCB3aXRoIElEICR7dW5pcXVlSWR9IGZyb20gJHtcbiAgICAgICAgICByZXF1ZXN0LmhlYWRlcnNbJ3gtZm9yd2FyZGVkLWZvciddIHx8IHJlcXVlc3QuY29ubmVjdGlvbi5yZW1vdGVBZGRyZXNzXG4gICAgICAgIH0gd2FzIGluY29ycmVjdDpcbiAgQ29udGVudC1UeXBlOiAke3JlcXVlc3QuaGVhZGVyc1snY29udGVudC10eXBlJ119LiBcbiAgQ2hhcnQgY29uc3RydWN0b3I6ICR7Ym9keS5jb25zdHJ9LlxuICBEaW1lbnNpb25zOiAke2JvZHkud2lkdGh9eCR7Ym9keS5oZWlnaHR9IEAgJHtib2R5LnNjYWxlfSBzY2FsZS5cbiAgVHlwZTogJHt0eXBlfS5cbiAgSXMgU1ZHIHNldD8gJHt0eXBlb2YgYm9keS5zdmcgIT09ICd1bmRlZmluZWQnfS5cbiAgQjY0PyAke3R5cGVvZiBib2R5LmI2NCAhPT0gJ3VuZGVmaW5lZCd9LlxuICBObyBkb3dubG9hZD8gJHt0eXBlb2YgYm9keS5ub0Rvd25sb2FkICE9PSAndW5kZWZpbmVkJ30uXG5cbiAgUGF5bG9hZCByZWNlaXZlZDogJHtKU09OLnN0cmluZ2lmeShib2R5LmluZmlsZSB8fCBib2R5Lm9wdGlvbnMgfHwgYm9keS5kYXRhIHx8IGJvZHkuc3ZnKX1cblxuICBgXG4gICAgICApO1xuXG4gICAgICB0aHJvdyBuZXcgSHR0cEVycm9yKFxuICAgICAgICBcIk5vIGNvcnJlY3QgY2hhcnQgZGF0YSBmb3VuZC4gRW5zdXJlIHRoYXQgeW91IGFyZSB1c2luZyBlaXRoZXIgYXBwbGljYXRpb24vanNvbiBvciBtdWx0aXBhcnQvZm9ybS1kYXRhIGhlYWRlcnMuIElmIHNlbmRpbmcgSlNPTiwgbWFrZSBzdXJlIHRoZSBjaGFydCBkYXRhIGlzIGluIHRoZSAnaW5maWxlJywgJ29wdGlvbnMnLCBvciAnZGF0YScgYXR0cmlidXRlLiBJZiBzZW5kaW5nIFNWRywgZW5zdXJlIGl0IGlzIGluIHRoZSAnc3ZnJyBhdHRyaWJ1dGUuXCIsXG4gICAgICAgIDQwMFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBsZXQgY2FsbFJlc3BvbnNlID0gZmFsc2U7XG5cbiAgICAvLyBDYWxsIHRoZSBiZWZvcmUgcmVxdWVzdCBmdW5jdGlvbnNcbiAgICBjYWxsUmVzcG9uc2UgPSBkb0NhbGxiYWNrcyhiZWZvcmVSZXF1ZXN0LCByZXF1ZXN0LCByZXNwb25zZSwge1xuICAgICAgaWQsXG4gICAgICB1bmlxdWVJZCxcbiAgICAgIHR5cGUsXG4gICAgICBib2R5XG4gICAgfSk7XG5cbiAgICAvLyBCbG9jayB0aGUgcmVxdWVzdCBpZiBvbmUgb2YgYSBjYWxsYmFja3MgZmFpbGVkXG4gICAgaWYgKGNhbGxSZXNwb25zZSAhPT0gdHJ1ZSkge1xuICAgICAgcmV0dXJuIHJlc3BvbnNlLnNlbmQoY2FsbFJlc3BvbnNlKTtcbiAgICB9XG5cbiAgICBsZXQgY29ubmVjdGlvbkFib3J0ZWQgPSBmYWxzZTtcblxuICAgIC8vIEluIGNhc2UgdGhlIGNvbm5lY3Rpb24gaXMgY2xvc2VkLCBmb3JjZSB0byBhYm9ydCBmdXJ0aGVyIGFjdGlvbnNcbiAgICByZXF1ZXN0LnNvY2tldC5vbignY2xvc2UnLCAoaGFkRXJyb3JzKSA9PiB7XG4gICAgICBpZiAoaGFkRXJyb3JzKSB7XG4gICAgICAgIGNvbm5lY3Rpb25BYm9ydGVkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGxvZyg0LCBgW2V4cG9ydF0gR290IGFuIGluY29taW5nIEhUVFAgcmVxdWVzdCB3aXRoIElEICR7dW5pcXVlSWR9LmApO1xuXG4gICAgYm9keS5jb25zdHIgPSAodHlwZW9mIGJvZHkuY29uc3RyID09PSAnc3RyaW5nJyAmJiBib2R5LmNvbnN0cikgfHwgJ2NoYXJ0JztcblxuICAgIC8vIEdhdGhlciBhbmQgb3JnYW5pemUgb3B0aW9ucyBmcm9tIHRoZSBwYXlsb2FkXG4gICAgY29uc3QgcmVxdWVzdE9wdGlvbnMgPSB7XG4gICAgICBleHBvcnQ6IHtcbiAgICAgICAgaW5zdHIsXG4gICAgICAgIHR5cGUsXG4gICAgICAgIGNvbnN0cjogYm9keS5jb25zdHJbMF0udG9Mb3dlckNhc2UoKSArIGJvZHkuY29uc3RyLnN1YnN0cigxKSxcbiAgICAgICAgaGVpZ2h0OiBib2R5LmhlaWdodCxcbiAgICAgICAgd2lkdGg6IGJvZHkud2lkdGgsXG4gICAgICAgIHNjYWxlOiBib2R5LnNjYWxlIHx8IGRlZmF1bHRPcHRpb25zLmV4cG9ydC5zY2FsZSxcbiAgICAgICAgZ2xvYmFsT3B0aW9uczogaXNDb3JyZWN0SlNPTihib2R5Lmdsb2JhbE9wdGlvbnMsIHRydWUpLFxuICAgICAgICB0aGVtZU9wdGlvbnM6IGlzQ29ycmVjdEpTT04oYm9keS50aGVtZU9wdGlvbnMsIHRydWUpXG4gICAgICB9LFxuICAgICAgY3VzdG9tTG9naWM6IHtcbiAgICAgICAgYWxsb3dDb2RlRXhlY3V0aW9uOiBnZXRBbGxvd0NvZGVFeGVjdXRpb24oKSxcbiAgICAgICAgYWxsb3dGaWxlUmVzb3VyY2VzOiBmYWxzZSxcbiAgICAgICAgcmVzb3VyY2VzOiBpc0NvcnJlY3RKU09OKGJvZHkucmVzb3VyY2VzLCB0cnVlKSxcbiAgICAgICAgY2FsbGJhY2s6IGJvZHkuY2FsbGJhY2ssXG4gICAgICAgIGN1c3RvbUNvZGU6IGJvZHkuY3VzdG9tQ29kZVxuICAgICAgfVxuICAgIH07XG5cbiAgICBpZiAoaW5zdHIpIHtcbiAgICAgIC8vIFN0cmluZ2lmeSBKU09OIHdpdGggb3B0aW9uc1xuICAgICAgcmVxdWVzdE9wdGlvbnMuZXhwb3J0Lmluc3RyID0gb3B0aW9uc1N0cmluZ2lmeShcbiAgICAgICAgaW5zdHIsXG4gICAgICAgIHJlcXVlc3RPcHRpb25zLmN1c3RvbUxvZ2ljLmFsbG93Q29kZUV4ZWN1dGlvblxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBNZXJnZSB0aGUgcmVxdWVzdCBvcHRpb25zIGludG8gZGVmYXVsdCBvbmVzXG4gICAgY29uc3Qgb3B0aW9ucyA9IG1lcmdlQ29uZmlnT3B0aW9ucyhkZWZhdWx0T3B0aW9ucywgcmVxdWVzdE9wdGlvbnMpO1xuXG4gICAgLy8gU2F2ZSB0aGUgSlNPTiBpZiBleGlzdHNcbiAgICBvcHRpb25zLmV4cG9ydC5vcHRpb25zID0gaW5zdHI7XG5cbiAgICAvLyBMYXN0bHksIGFkZCB0aGUgc2VydmVyIHNwZWNpZmljIGFyZ3VtZW50cyBpbnRvIG9wdGlvbnMgYXMgcGF5bG9hZFxuICAgIG9wdGlvbnMucGF5bG9hZCA9IHtcbiAgICAgIHN2ZzogYm9keS5zdmcgfHwgZmFsc2UsXG4gICAgICBiNjQ6IGJvZHkuYjY0IHx8IGZhbHNlLFxuICAgICAgbm9Eb3dubG9hZDogYm9keS5ub0Rvd25sb2FkIHx8IGZhbHNlLFxuICAgICAgcmVxdWVzdElkOiB1bmlxdWVJZFxuICAgIH07XG5cbiAgICAvLyBUZXN0IHhsaW5rOmhyZWYgZWxlbWVudHMgZnJvbSBwYXlsb2FkJ3MgU1ZHXG4gICAgaWYgKGJvZHkuc3ZnICYmIGlzUHJpdmF0ZVJhbmdlVXJsRm91bmQob3B0aW9ucy5wYXlsb2FkLnN2ZykpIHtcbiAgICAgIHRocm93IG5ldyBIdHRwRXJyb3IoXG4gICAgICAgICdTVkcgcG90ZW50aWFsbHkgY29udGFpbiBhdCBsZWFzdCBvbmUgZm9yYmlkZGVuIFVSTCBpbiB4bGluazpocmVmIGVsZW1lbnQuIFBsZWFzZSByZXZpZXcgdGhlIFNWRyBjb250ZW50IGFuZCBlbnN1cmUgdGhhdCBhbGwgcmVmZXJlbmNlZCBVUkxzIGNvbXBseSB3aXRoIHNlY3VyaXR5IHBvbGljaWVzLicsXG4gICAgICAgIDQwMFxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBTdGFydCB0aGUgZXhwb3J0IHByb2Nlc3NcbiAgICBhd2FpdCBzdGFydEV4cG9ydChvcHRpb25zLCAoZXJyb3IsIGluZm8pID0+IHtcbiAgICAgIC8vIFJlbW92ZSB0aGUgY2xvc2UgZXZlbnQgZnJvbSB0aGUgc29ja2V0XG4gICAgICByZXF1ZXN0LnNvY2tldC5yZW1vdmVBbGxMaXN0ZW5lcnMoJ2Nsb3NlJyk7XG5cbiAgICAgIC8vIEFmdGVyIHRoZSB3aG9sZSBleHBvcnRpbmcgcHJvY2Vzc1xuICAgICAgaWYgKGRlZmF1bHRPcHRpb25zLnNlcnZlci5iZW5jaG1hcmtpbmcpIHtcbiAgICAgICAgbG9nKFxuICAgICAgICAgIDUsXG4gICAgICAgICAgYFtiZW5jaG1hcmtdIFJlcXVlc3Qgd2l0aCBJRCAke3VuaXF1ZUlkfSAtIEFmdGVyIHRoZSB3aG9sZSBleHBvcnRpbmcgcHJvY2VzczogJHtzdG9wQ291bnRlcigpfW1zLmBcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgLy8gSWYgdGhlIGNvbm5lY3Rpb24gd2FzIGNsb3NlZCwgZG8gbm90aGluZ1xuICAgICAgaWYgKGNvbm5lY3Rpb25BYm9ydGVkKSB7XG4gICAgICAgIHJldHVybiBsb2coXG4gICAgICAgICAgMyxcbiAgICAgICAgICBgW2V4cG9ydF0gVGhlIGNsaWVudCBjbG9zZWQgdGhlIGNvbm5lY3Rpb24gYmVmb3JlIHRoZSBjaGFydCBmaW5pc2hlZCBwcm9jZXNzaW5nLmBcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgLy8gSWYgZXJyb3IsIGxvZyBpdCBhbmQgc2VuZCBpdCB0byB0aGUgZXJyb3IgbWlkZGxld2FyZVxuICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfVxuXG4gICAgICAvLyBJZiBkYXRhIGlzIG1pc3NpbmcsIGxvZyB0aGUgbWVzc2FnZSBhbmQgc2VuZCBpdCB0byB0aGUgZXJyb3IgbWlkZGxld2FyZVxuICAgICAgaWYgKCFpbmZvIHx8ICFpbmZvLnJlc3VsdCkge1xuICAgICAgICB0aHJvdyBuZXcgSHR0cEVycm9yKFxuICAgICAgICAgIGBVbmV4cGVjdGVkIHJldHVybiBmcm9tIGNoYXJ0IGdlbmVyYXRpb24uIFBsZWFzZSBjaGVjayB5b3VyIHJlcXVlc3QgZGF0YS4gRm9yIHRoZSByZXF1ZXN0IHdpdGggSUQgJHt1bmlxdWVJZH0sIHRoZSByZXN1bHQgaXMgJHtpbmZvLnJlc3VsdH0uYCxcbiAgICAgICAgICA0MDBcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgLy8gR2V0IHRoZSB0eXBlIGZyb20gb3B0aW9uc1xuICAgICAgdHlwZSA9IGluZm8ub3B0aW9ucy5leHBvcnQudHlwZTtcblxuICAgICAgLy8gVGhlIGFmdGVyIHJlcXVlc3QgY2FsbGJhY2tzXG4gICAgICBkb0NhbGxiYWNrcyhhZnRlclJlcXVlc3QsIHJlcXVlc3QsIHJlc3BvbnNlLCB7IGlkLCBib2R5OiBpbmZvLnJlc3VsdCB9KTtcblxuICAgICAgaWYgKGluZm8ucmVzdWx0KSB7XG4gICAgICAgIC8vIElmIG9ubHkgYmFzZTY0IGlzIHJlcXVpcmVkLCByZXR1cm4gaXRcbiAgICAgICAgaWYgKGJvZHkuYjY0KSB7XG4gICAgICAgICAgLy8gU1ZHIEV4Y2VwdGlvbiBmb3IgdGhlIEhpZ2hjaGFydHMgMTEuMy4wIHZlcnNpb25cbiAgICAgICAgICBpZiAodHlwZSA9PT0gJ3BkZicgfHwgdHlwZSA9PSAnc3ZnJykge1xuICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlLnNlbmQoXG4gICAgICAgICAgICAgIEJ1ZmZlci5mcm9tKGluZm8ucmVzdWx0LCAndXRmOCcpLnRvU3RyaW5nKCdiYXNlNjQnKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gcmVzcG9uc2Uuc2VuZChpbmZvLnJlc3VsdCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXQgY29ycmVjdCBjb250ZW50IHR5cGVcbiAgICAgICAgcmVzcG9uc2UuaGVhZGVyKCdDb250ZW50LVR5cGUnLCByZXZlcnNlZE1pbWVbdHlwZV0gfHwgJ2ltYWdlL3BuZycpO1xuXG4gICAgICAgIC8vIERlY2lkZSB3aGV0aGVyIHRvIGRvd25sb2FkIG9yIG5vdCBjaGFydCBmaWxlXG4gICAgICAgIGlmICghYm9keS5ub0Rvd25sb2FkKSB7XG4gICAgICAgICAgcmVzcG9uc2UuYXR0YWNobWVudChcbiAgICAgICAgICAgIGAke3JlcXVlc3QucGFyYW1zLmZpbGVuYW1lIHx8IHJlcXVlc3QuYm9keS5maWxlbmFtZSB8fCAnY2hhcnQnfS4ke1xuICAgICAgICAgICAgICB0eXBlIHx8ICdwbmcnXG4gICAgICAgICAgICB9YFxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBJZiBTVkcsIHJldHVybiBwbGFpbiBjb250ZW50XG4gICAgICAgIHJldHVybiB0eXBlID09PSAnc3ZnJ1xuICAgICAgICAgID8gcmVzcG9uc2Uuc2VuZChpbmZvLnJlc3VsdClcbiAgICAgICAgICA6IHJlc3BvbnNlLnNlbmQoQnVmZmVyLmZyb20oaW5mby5yZXN1bHQsICdiYXNlNjQnKSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgbmV4dChlcnJvcik7XG4gIH1cbn07XG5cbmV4cG9ydCBkZWZhdWx0IChhcHApID0+IHtcbiAgLyoqXG4gICAqIEFkZHMgdGhlIFBPU1QgLyBhIHJvdXRlIGZvciBoYW5kbGluZyBQT1NUIHJlcXVlc3RzIGF0IHRoZSByb290IGVuZHBvaW50LlxuICAgKi9cbiAgYXBwLnBvc3QoJy8nLCBleHBvcnRIYW5kbGVyKTtcblxuICAvKipcbiAgICogQWRkcyB0aGUgUE9TVCAvOmZpbGVuYW1lIGEgcm91dGUgZm9yIGhhbmRsaW5nIFBPU1QgcmVxdWVzdHMgd2l0aFxuICAgKiBhIHNwZWNpZmllZCBmaWxlbmFtZSBwYXJhbWV0ZXIuXG4gICAqL1xuICBhcHAucG9zdCgnLzpmaWxlbmFtZScsIGV4cG9ydEhhbmRsZXIpO1xufTtcbiIsIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG5cbkhpZ2hjaGFydHMgRXhwb3J0IFNlcnZlclxuXG5Db3B5cmlnaHQgKGMpIDIwMTYtMjAyNCwgSGlnaHNvZnRcblxuTGljZW5jZWQgdW5kZXIgdGhlIE1JVCBsaWNlbmNlLlxuXG5BZGRpdGlvbmFsbHkgYSB2YWxpZCBIaWdoY2hhcnRzIGxpY2Vuc2UgaXMgcmVxdWlyZWQgZm9yIHVzZS5cblxuU2VlIExJQ0VOU0UgZmlsZSBpbiByb290IGZvciBkZXRhaWxzLlxuXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG5pbXBvcnQgeyByZWFkRmlsZVN5bmMgfSBmcm9tICdmcyc7XG5pbXBvcnQgeyBqb2luIGFzIHBhdGhlciB9IGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgbG9nIH0gZnJvbSAnLi4vLi4vbG9nZ2VyLmpzJztcblxuaW1wb3J0IHsgdmVyc2lvbiB9IGZyb20gJy4uLy4uL2NhY2hlLmpzJztcbmltcG9ydCB7IGFkZEludGVydmFsIH0gZnJvbSAnLi4vLi4vaW50ZXJ2YWxzLmpzJztcbmltcG9ydCBwb29sIGZyb20gJy4uLy4uL3Bvb2wuanMnO1xuaW1wb3J0IHsgX19kaXJuYW1lIH0gZnJvbSAnLi4vLi4vdXRpbHMuanMnO1xuXG5jb25zdCBwa2dGaWxlID0gSlNPTi5wYXJzZShyZWFkRmlsZVN5bmMocGF0aGVyKF9fZGlybmFtZSwgJ3BhY2thZ2UuanNvbicpKSk7XG5cbmNvbnN0IHNlcnZlclN0YXJ0VGltZSA9IG5ldyBEYXRlKCk7XG5cbmNvbnN0IHN1Y2Nlc3NSYXRlcyA9IFtdO1xuY29uc3QgcmVjb3JkSW50ZXJ2YWwgPSA2MCAqIDEwMDA7IC8vIHJlY29yZCBldmVyeSBtaW51dGVcbmNvbnN0IHdpbmRvd1NpemUgPSAzMDsgLy8gMzAgbWludXRlc1xuXG4vKipcbiAqIENhbGN1bGF0ZXMgbW92aW5nIGF2ZXJhZ2UgaW5kaWNhdG9yIGJhc2VkIG9uIHRoZSBkYXRhIGZyb20gdGhlIHN1Y2Nlc3NSYXRlc1xuICogYXJyYXkuXG4gKlxuICogQHJldHVybnMge251bWJlcn0gLSBBIG1vdmluZyBhdmVyYWdlIGZvciBzdWNjZXNzIHJhdGlvIG9mIHRoZSBzZXJ2ZXIgZXhwb3J0cy5cbiAqL1xuZnVuY3Rpb24gY2FsY3VsYXRlTW92aW5nQXZlcmFnZSgpIHtcbiAgY29uc3Qgc3VtID0gc3VjY2Vzc1JhdGVzLnJlZHVjZSgoYSwgYikgPT4gYSArIGIsIDApO1xuICByZXR1cm4gc3VtIC8gc3VjY2Vzc1JhdGVzLmxlbmd0aDtcbn1cblxuLyoqXG4gKiBTdGFydHMgdGhlIGludGVydmFsIHJlc3BvbnNpYmxlIGZvciBjYWxjdWxhdGluZyBjdXJyZW50IHN1Y2Nlc3MgcmF0ZSByYXRpb1xuICogYW5kIGdhdGhlcnNcbiAqXG4gKiBAcmV0dXJucyB7Tm9kZUpTLlRpbWVvdXR9IGlkIC0gSWQgb2YgYW4gaW50ZXJ2YWwuXG4gKi9cbmV4cG9ydCBjb25zdCBzdGFydFN1Y2Nlc3NSYXRlID0gKCkgPT5cbiAgc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgIGNvbnN0IHN0YXRzID0gcG9vbC5nZXRTdGF0cygpO1xuICAgIGNvbnN0IHN1Y2Nlc3NSYXRpbyA9XG4gICAgICBzdGF0cy5leHBvcnRBdHRlbXB0cyA9PT0gMFxuICAgICAgICA/IDFcbiAgICAgICAgOiAoc3RhdHMucGVyZm9ybWVkRXhwb3J0cyAvIHN0YXRzLmV4cG9ydEF0dGVtcHRzKSAqIDEwMDtcblxuICAgIHN1Y2Nlc3NSYXRlcy5wdXNoKHN1Y2Nlc3NSYXRpbyk7XG4gICAgaWYgKHN1Y2Nlc3NSYXRlcy5sZW5ndGggPiB3aW5kb3dTaXplKSB7XG4gICAgICBzdWNjZXNzUmF0ZXMuc2hpZnQoKTtcbiAgICB9XG4gIH0sIHJlY29yZEludGVydmFsKTtcblxuLyoqXG4gKiBBZGRzIHRoZSAvaGVhbHRoIGFuZCAvc3VjY2Vzcy1tb3ZpbmctYXZlcmFnZSByb3V0ZXNcbiAqIHdoaWNoIG91dHB1dCBiYXNpYyBzdGF0cyBmb3IgdGhlIHNlcnZlci5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gYWRkSGVhbHRoUm91dGVzKGFwcCkge1xuICBpZiAoIWFwcCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIFN0YXJ0IHByb2Nlc3Npbmcgc3VjY2VzcyByYXRlIHJhdGlvIGludGVydmFsIGFuZCBzYXZlIGl0cyBpZCB0byB0aGUgYXJyYXlcbiAgLy8gZm9yIHRoZSBncmFjZWZ1bCBjbGVhcmluZyBvbiBzaHV0ZG93biB3aXRoIGluamVjdGVkIGFkZEludGVydmFsIGZ1bnRpb25cbiAgYWRkSW50ZXJ2YWwoc3RhcnRTdWNjZXNzUmF0ZSgpKTtcblxuICBhcHAuZ2V0KCcvaGVhbHRoJywgKF8sIHJlcykgPT4ge1xuICAgIGNvbnN0IHN0YXRzID0gcG9vbC5nZXRTdGF0cygpO1xuICAgIGNvbnN0IHBlcmlvZCA9IHN1Y2Nlc3NSYXRlcy5sZW5ndGg7XG4gICAgY29uc3QgbW92aW5nQXZlcmFnZSA9IGNhbGN1bGF0ZU1vdmluZ0F2ZXJhZ2UoKTtcblxuICAgIGxvZyg0LCAnW2hlYWx0aC5qc10gR0VUIC9oZWFsdGggWzIwMF0gLSByZXR1cm5pbmcgc2VydmVyIGhlYWx0aC4nKTtcblxuICAgIHJlcy5zZW5kKHtcbiAgICAgIHN0YXR1czogJ09LJyxcbiAgICAgIGJvb3RUaW1lOiBzZXJ2ZXJTdGFydFRpbWUsXG4gICAgICB1cHRpbWU6XG4gICAgICAgIE1hdGguZmxvb3IoXG4gICAgICAgICAgKG5ldyBEYXRlKCkuZ2V0VGltZSgpIC0gc2VydmVyU3RhcnRUaW1lLmdldFRpbWUoKSkgLyAxMDAwIC8gNjBcbiAgICAgICAgKSArICcgbWludXRlcycsXG4gICAgICB2ZXJzaW9uOiBwa2dGaWxlLnZlcnNpb24sXG4gICAgICBoaWdoY2hhcnRzVmVyc2lvbjogdmVyc2lvbigpLFxuICAgICAgYXZlcmFnZVByb2Nlc3NpbmdUaW1lOiBzdGF0cy5zcGVudEF2ZXJhZ2UsXG4gICAgICBwZXJmb3JtZWRFeHBvcnRzOiBzdGF0cy5wZXJmb3JtZWRFeHBvcnRzLFxuICAgICAgZmFpbGVkRXhwb3J0czogc3RhdHMuZHJvcHBlZEV4cG9ydHMsXG4gICAgICBleHBvcnRBdHRlbXB0czogc3RhdHMuZXhwb3J0QXR0ZW1wdHMsXG4gICAgICBzdWNlc3NSYXRpbzogKHN0YXRzLnBlcmZvcm1lZEV4cG9ydHMgLyBzdGF0cy5leHBvcnRBdHRlbXB0cykgKiAxMDAsXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLW5hbWVkLWFzLWRlZmF1bHQtbWVtYmVyXG4gICAgICBwb29sOiBwb29sLmdldFBvb2xJbmZvSlNPTigpLFxuXG4gICAgICAvLyBNb3ZpbmcgYXZlcmFnZVxuICAgICAgcGVyaW9kLFxuICAgICAgbW92aW5nQXZlcmFnZSxcbiAgICAgIG1lc3NhZ2U6XG4gICAgICAgIGlzTmFOKG1vdmluZ0F2ZXJhZ2UpIHx8ICFzdWNjZXNzUmF0ZXMubGVuZ3RoXG4gICAgICAgICAgPyAnVG9vIGVhcmx5IHRvIHJlcG9ydC4gTm8gZXhwb3J0cyBtYWRlIHlldC4gUGxlYXNlIGNoZWNrIGJhY2sgc29vbi4nXG4gICAgICAgICAgOiBgTGFzdCAke3BlcmlvZH0gbWludXRlcyBoYWQgYSBzdWNjZXNzIHJhdGUgb2YgJHttb3ZpbmdBdmVyYWdlLnRvRml4ZWQoMil9JS5gLFxuXG4gICAgICAvLyBTVkcvSlNPTiBhdHRlbXB0c1xuICAgICAgc3ZnRXhwb3J0QXR0ZW1wdHM6IHN0YXRzLmV4cG9ydEZyb21TdmdBdHRlbXB0cyxcbiAgICAgIGpzb25FeHBvcnRBdHRlbXB0czogc3RhdHMucGVyZm9ybWVkRXhwb3J0cyAtIHN0YXRzLmV4cG9ydEZyb21TdmdBdHRlbXB0c1xuICAgIH0pO1xuICB9KTtcbn1cbiIsIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG5cbkhpZ2hjaGFydHMgRXhwb3J0IFNlcnZlclxuXG5Db3B5cmlnaHQgKGMpIDIwMTYtMjAyNCwgSGlnaHNvZnRcblxuTGljZW5jZWQgdW5kZXIgdGhlIE1JVCBsaWNlbmNlLlxuXG5BZGRpdGlvbmFsbHkgYSB2YWxpZCBIaWdoY2hhcnRzIGxpY2Vuc2UgaXMgcmVxdWlyZWQgZm9yIHVzZS5cblxuU2VlIExJQ0VOU0UgZmlsZSBpbiByb290IGZvciBkZXRhaWxzLlxuXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG5pbXBvcnQgeyBwcm9taXNlcyBhcyBmc1Byb21pc2VzIH0gZnJvbSAnZnMnO1xuaW1wb3J0IHsgcG9zaXggfSBmcm9tICdwYXRoJztcblxuaW1wb3J0IGNvcnMgZnJvbSAnY29ycyc7XG5pbXBvcnQgZXhwcmVzcyBmcm9tICdleHByZXNzJztcbmltcG9ydCBodHRwIGZyb20gJ2h0dHAnO1xuaW1wb3J0IGh0dHBzIGZyb20gJ2h0dHBzJztcbmltcG9ydCBtdWx0ZXIgZnJvbSAnbXVsdGVyJztcblxuaW1wb3J0IGVycm9ySGFuZGxlciBmcm9tICcuL2Vycm9yLmpzJztcbmltcG9ydCByYXRlTGltaXQgZnJvbSAnLi9yYXRlX2xpbWl0LmpzJztcbmltcG9ydCB7IGxvZywgbG9nV2l0aFN0YWNrIH0gZnJvbSAnLi4vbG9nZ2VyLmpzJztcbmltcG9ydCB7IF9fZGlybmFtZSB9IGZyb20gJy4uL3V0aWxzLmpzJztcblxuaW1wb3J0IHZTd2l0Y2hSb3V0ZSBmcm9tICcuL3JvdXRlcy9jaGFuZ2VfaGNfdmVyc2lvbi5qcyc7XG5pbXBvcnQgZXhwb3J0Um91dGVzIGZyb20gJy4vcm91dGVzL2V4cG9ydC5qcyc7XG5pbXBvcnQgaGVhbHRoUm91dGUgZnJvbSAnLi9yb3V0ZXMvaGVhbHRoLmpzJztcbmltcG9ydCB1aVJvdXRlIGZyb20gJy4vcm91dGVzL3VpLmpzJztcblxuaW1wb3J0IEV4cG9ydEVycm9yIGZyb20gJy4uL2Vycm9ycy9FeHBvcnRFcnJvci5qcyc7XG5cbi8vIEFycmF5IG9mIGFuIGFjdGl2ZSBzZXJ2ZXJzXG5jb25zdCBhY3RpdmVTZXJ2ZXJzID0gbmV3IE1hcCgpO1xuXG4vLyBDcmVhdGUgZXhwcmVzcyBhcHBcbmNvbnN0IGFwcCA9IGV4cHJlc3MoKTtcblxuLy8gRGlzYWJsZSB0aGUgWC1Qb3dlcmVkLUJ5IGhlYWRlclxuYXBwLmRpc2FibGUoJ3gtcG93ZXJlZC1ieScpO1xuXG4vLyBFbmFibGUgQ09SUyBzdXBwb3J0XG5hcHAudXNlKGNvcnMoKSk7XG5cbi8vIEdldHRpbmcgYSBsb3Qgb2YgUmFuZ2VOb3RTYXRpc2ZpYWJsZUVycm9yIGV4Y2VwdGlvbi5cbi8vIEV2ZW4gdGhvdWdoIHRoaXMgaXMgYSBkZXByZWNhdGVkIG9wdGlvbnMsIGxldCdzIHRyeSB0byBzZXQgaXQgdG8gZmFsc2UuXG5hcHAudXNlKChfcmVxLCByZXMsIG5leHQpID0+IHtcbiAgcmVzLnNldCgnQWNjZXB0LVJhbmdlcycsICdub25lJyk7XG4gIG5leHQoKTtcbn0pO1xuXG4vKipcbiAqIEF0dGFjaCBlcnJvciBoYW5kbGVycyB0byB0aGUgc2VydmVyLlxuICpcbiAqIEBwYXJhbSB7aHR0cC5TZXJ2ZXJ9IHNlcnZlciAtIFRoZSBIVFRQL0hUVFBTIHNlcnZlciBpbnN0YW5jZS5cbiAqL1xuY29uc3QgYXR0YWNoU2VydmVyRXJyb3JIYW5kbGVycyA9IChzZXJ2ZXIpID0+IHtcbiAgc2VydmVyLm9uKCdjbGllbnRFcnJvcicsIChlcnJvciwgc29ja2V0KSA9PiB7XG4gICAgbG9nV2l0aFN0YWNrKFxuICAgICAgMSxcbiAgICAgIGVycm9yLFxuICAgICAgYFtzZXJ2ZXJdIENsaWVudCBlcnJvcjogJHtlcnJvci5tZXNzYWdlfSwgZGVzdHJveWluZyBzb2NrZXQuYFxuICAgICk7XG4gICAgc29ja2V0LmRlc3Ryb3koKTtcbiAgfSk7XG5cbiAgc2VydmVyLm9uKCdlcnJvcicsIChlcnJvcikgPT4ge1xuICAgIGxvZ1dpdGhTdGFjaygxLCBlcnJvciwgYFtzZXJ2ZXJdIFNlcnZlciBlcnJvcjogJHtlcnJvci5tZXNzYWdlfWApO1xuICB9KTtcblxuICBzZXJ2ZXIub24oJ2Nvbm5lY3Rpb24nLCAoc29ja2V0KSA9PiB7XG4gICAgc29ja2V0Lm9uKCdlcnJvcicsIChlcnJvcikgPT4ge1xuICAgICAgbG9nV2l0aFN0YWNrKDEsIGVycm9yLCBgW3NlcnZlcl0gU29ja2V0IGVycm9yOiAke2Vycm9yLm1lc3NhZ2V9YCk7XG4gICAgfSk7XG4gIH0pO1xufTtcblxuLyoqXG4gKiBTdGFydHMgYW4gSFRUUCBzZXJ2ZXIgYmFzZWQgb24gdGhlIHByb3ZpZGVkIGNvbmZpZ3VyYXRpb24uIFRoZSBgc2VydmVyQ29uZmlnYFxuICogb2JqZWN0IGNvbnRhaW5zIGFsbCBzZXJ2ZXIgcmVsYXRlZCBwcm9wZXJ0aWVzIChzZWUgdGhlIGBzZXJ2ZXJgIHNlY3Rpb25cbiAqIGluIHRoZSBgbGliL3NjaGVtYXMvY29uZmlnLmpzYCBmaWxlIGZvciBhIHJlZmVyZW5jZSkuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHNlcnZlckNvbmZpZyAtIFRoZSBzZXJ2ZXIgY29uZmlndXJhdGlvbiBvYmplY3QuXG4gKlxuICogQHRocm93cyB7RXhwb3J0RXJyb3J9IC0gVGhyb3dzIGFuIGVycm9yIGlmIHRoZSBzZXJ2ZXIgY2Fubm90IGJlIGNvbmZpZ3VyZWRcbiAqIGFuZCBzdGFydGVkLlxuICovXG5leHBvcnQgY29uc3Qgc3RhcnRTZXJ2ZXIgPSBhc3luYyAoc2VydmVyQ29uZmlnKSA9PiB7XG4gIHRyeSB7XG4gICAgLy8gVE9ETzogUmVhZCBmcm9tIGNvbmZpZy9lbnZcbiAgICAvLyBOT1RFOlxuICAgIC8vIFRvbyBiaWcgbGltaXRzIGxlYWQgdG8gdGltZW91dHMgaW4gdGhlIGV4cG9ydCBwcm9jZXNzIHdoZW4gdGhlXG4gICAgLy8gcmFzdGVyaXphdGlvbiB0aW1lb3V0IGlzIHNldCB0b28gbG93LlxuICAgIGNvbnN0IHVwbG9hZExpbWl0TWlCID0gc2VydmVyQ29uZmlnLm1heFVwbG9hZFNpemUgfHwgMztcbiAgICBjb25zdCB1cGxvYWRMaW1pdEJ5dGVzID0gdXBsb2FkTGltaXRNaUIgKiAxMDI0ICogMTAyNDtcblxuICAgIC8vIEVuYWJsZSBwYXJzaW5nIG9mIGZvcm0gZGF0YSAoZmlsZXMpIHdpdGggTXVsdGVyIHBhY2thZ2VcbiAgICBjb25zdCBzdG9yYWdlID0gbXVsdGVyLm1lbW9yeVN0b3JhZ2UoKTtcbiAgICBjb25zdCB1cGxvYWQgPSBtdWx0ZXIoe1xuICAgICAgc3RvcmFnZSxcbiAgICAgIGxpbWl0czoge1xuICAgICAgICBmaWVsZFNpemU6IHVwbG9hZExpbWl0Qnl0ZXNcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIEVuYWJsZSBib2R5IHBhcnNlclxuICAgIGFwcC51c2UoZXhwcmVzcy5qc29uKHsgbGltaXQ6IHVwbG9hZExpbWl0Qnl0ZXMgfSkpO1xuICAgIGFwcC51c2UoZXhwcmVzcy51cmxlbmNvZGVkKHsgZXh0ZW5kZWQ6IHRydWUsIGxpbWl0OiB1cGxvYWRMaW1pdEJ5dGVzIH0pKTtcblxuICAgIC8vIFVzZSBvbmx5IG5vbi1maWxlIG11bHRpcGFydCBmb3JtIGZpZWxkc1xuICAgIGFwcC51c2UodXBsb2FkLm5vbmUoKSk7XG5cbiAgICAvLyBTdG9wIGlmIG5vdCBlbmFibGVkXG4gICAgaWYgKCFzZXJ2ZXJDb25maWcuZW5hYmxlKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gTGlzdGVuIEhUVFAgc2VydmVyXG4gICAgaWYgKCFzZXJ2ZXJDb25maWcuc3NsLmZvcmNlKSB7XG4gICAgICAvLyBNYWluIHNlcnZlciBpbnN0YW5jZSAoSFRUUClcbiAgICAgIGNvbnN0IGh0dHBTZXJ2ZXIgPSBodHRwLmNyZWF0ZVNlcnZlcihhcHApO1xuXG4gICAgICAvLyBBdHRhY2ggZXJyb3IgaGFuZGxlcnMgYW5kIGxpc3RlbiB0byB0aGUgc2VydmVyXG4gICAgICBhdHRhY2hTZXJ2ZXJFcnJvckhhbmRsZXJzKGh0dHBTZXJ2ZXIpO1xuXG4gICAgICAvLyBMaXN0ZW5cbiAgICAgIGh0dHBTZXJ2ZXIubGlzdGVuKHNlcnZlckNvbmZpZy5wb3J0LCBzZXJ2ZXJDb25maWcuaG9zdCk7XG5cbiAgICAgIC8vIFNhdmUgdGhlIHJlZmVyZW5jZSB0byBIVFRQIHNlcnZlclxuICAgICAgYWN0aXZlU2VydmVycy5zZXQoc2VydmVyQ29uZmlnLnBvcnQsIGh0dHBTZXJ2ZXIpO1xuXG4gICAgICBsb2coXG4gICAgICAgIDMsXG4gICAgICAgIGBbc2VydmVyXSBTdGFydGVkIEhUVFAgc2VydmVyIG9uICR7c2VydmVyQ29uZmlnLmhvc3R9OiR7c2VydmVyQ29uZmlnLnBvcnR9LmBcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gTGlzdGVuIEhUVFBTIHNlcnZlclxuICAgIGlmIChzZXJ2ZXJDb25maWcuc3NsLmVuYWJsZSkge1xuICAgICAgLy8gU2V0IHVwIGFuIFNTTCBzZXJ2ZXIgYWxzb1xuICAgICAgbGV0IGtleSwgY2VydDtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gR2V0IHRoZSBTU0wga2V5XG4gICAgICAgIGtleSA9IGF3YWl0IGZzUHJvbWlzZXMucmVhZEZpbGUoXG4gICAgICAgICAgcG9zaXguam9pbihzZXJ2ZXJDb25maWcuc3NsLmNlcnRQYXRoLCAnc2VydmVyLmtleScpLFxuICAgICAgICAgICd1dGY4J1xuICAgICAgICApO1xuXG4gICAgICAgIC8vIEdldCB0aGUgU1NMIGNlcnRpZmljYXRlXG4gICAgICAgIGNlcnQgPSBhd2FpdCBmc1Byb21pc2VzLnJlYWRGaWxlKFxuICAgICAgICAgIHBvc2l4LmpvaW4oc2VydmVyQ29uZmlnLnNzbC5jZXJ0UGF0aCwgJ3NlcnZlci5jcnQnKSxcbiAgICAgICAgICAndXRmOCdcbiAgICAgICAgKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGxvZyhcbiAgICAgICAgICAyLFxuICAgICAgICAgIGBbc2VydmVyXSBVbmFibGUgdG8gbG9hZCBrZXkvY2VydGlmaWNhdGUgZnJvbSB0aGUgJyR7c2VydmVyQ29uZmlnLnNzbC5jZXJ0UGF0aH0nIHBhdGguIENvdWxkIG5vdCBydW4gc2VjdXJlZCBsYXllciBzZXJ2ZXIuYFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBpZiAoa2V5ICYmIGNlcnQpIHtcbiAgICAgICAgLy8gTWFpbiBzZXJ2ZXIgaW5zdGFuY2UgKEhUVFBTKVxuICAgICAgICBjb25zdCBodHRwc1NlcnZlciA9IGh0dHBzLmNyZWF0ZVNlcnZlcih7IGtleSwgY2VydCB9LCBhcHApO1xuXG4gICAgICAgIC8vIEF0dGFjaCBlcnJvciBoYW5kbGVycyBhbmQgbGlzdGVuIHRvIHRoZSBzZXJ2ZXJcbiAgICAgICAgYXR0YWNoU2VydmVyRXJyb3JIYW5kbGVycyhodHRwc1NlcnZlcik7XG5cbiAgICAgICAgLy8gTGlzdGVuXG4gICAgICAgIGh0dHBzU2VydmVyLmxpc3RlbihzZXJ2ZXJDb25maWcuc3NsLnBvcnQsIHNlcnZlckNvbmZpZy5ob3N0KTtcblxuICAgICAgICAvLyBTYXZlIHRoZSByZWZlcmVuY2UgdG8gSFRUUFMgc2VydmVyXG4gICAgICAgIGFjdGl2ZVNlcnZlcnMuc2V0KHNlcnZlckNvbmZpZy5zc2wucG9ydCwgaHR0cHNTZXJ2ZXIpO1xuXG4gICAgICAgIGxvZyhcbiAgICAgICAgICAzLFxuICAgICAgICAgIGBbc2VydmVyXSBTdGFydGVkIEhUVFBTIHNlcnZlciBvbiAke3NlcnZlckNvbmZpZy5ob3N0fToke3NlcnZlckNvbmZpZy5zc2wucG9ydH0uYFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEVuYWJsZSB0aGUgcmF0ZSBsaW1pdGVyIGlmIGNvbmZpZyBzYXlzIHNvXG4gICAgaWYgKFxuICAgICAgc2VydmVyQ29uZmlnLnJhdGVMaW1pdGluZyAmJlxuICAgICAgc2VydmVyQ29uZmlnLnJhdGVMaW1pdGluZy5lbmFibGUgJiZcbiAgICAgICFbMCwgTmFOXS5pbmNsdWRlcyhzZXJ2ZXJDb25maWcucmF0ZUxpbWl0aW5nLm1heFJlcXVlc3RzKVxuICAgICkge1xuICAgICAgcmF0ZUxpbWl0KGFwcCwgc2VydmVyQ29uZmlnLnJhdGVMaW1pdGluZyk7XG4gICAgfVxuXG4gICAgLy8gU2V0IHVwIHN0YXRpYyBmb2xkZXIncyByb3V0ZVxuICAgIGFwcC51c2UoZXhwcmVzcy5zdGF0aWMocG9zaXguam9pbihfX2Rpcm5hbWUsICdwdWJsaWMnKSkpO1xuXG4gICAgLy8gU2V0IHVwIHJvdXRlc1xuICAgIGhlYWx0aFJvdXRlKGFwcCk7XG4gICAgZXhwb3J0Um91dGVzKGFwcCk7XG4gICAgdWlSb3V0ZShhcHApO1xuICAgIHZTd2l0Y2hSb3V0ZShhcHApO1xuXG4gICAgLy8gU2V0IHVwIGNlbnRyYWxpemVkIGVycm9yIGhhbmRsZXJcbiAgICBlcnJvckhhbmRsZXIoYXBwKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICB0aHJvdyBuZXcgRXhwb3J0RXJyb3IoXG4gICAgICAnW3NlcnZlcl0gQ291bGQgbm90IGNvbmZpZ3VyZSBhbmQgc3RhcnQgdGhlIHNlcnZlci4nXG4gICAgKS5zZXRFcnJvcihlcnJvcik7XG4gIH1cbn07XG5cbi8qKlxuICogQ2xvc2VzIGFsbCBzZXJ2ZXJzIGFzc29jaWF0ZWQgd2l0aCBFeHByZXNzIGFwcCBpbnN0YW5jZS5cbiAqL1xuZXhwb3J0IGNvbnN0IGNsb3NlU2VydmVycyA9ICgpID0+IHtcbiAgbG9nKDQsIGBbc2VydmVyXSBDbG9zaW5nIGFsbCBzZXJ2ZXJzLmApO1xuICBmb3IgKGNvbnN0IFtwb3J0LCBzZXJ2ZXJdIG9mIGFjdGl2ZVNlcnZlcnMpIHtcbiAgICBzZXJ2ZXIuY2xvc2UoKCkgPT4ge1xuICAgICAgYWN0aXZlU2VydmVycy5kZWxldGUocG9ydCk7XG4gICAgICBsb2coNCwgYFtzZXJ2ZXJdIENsb3NlZCBzZXJ2ZXIgb24gcG9ydDogJHtwb3J0fS5gKTtcbiAgICB9KTtcbiAgfVxufTtcblxuLyoqXG4gKiBHZXQgYWxsIHNlcnZlcnMgYXNzb2NpYXRlZCB3aXRoIEV4cHJlc3MgYXBwIGluc3RhbmNlLlxuICpcbiAqIEByZXR1cm5zIHtBcnJheX0gLSBTZXJ2ZXJzIGFzc29jaWF0ZWQgd2l0aCBFeHByZXNzIGFwcCBpbnN0YW5jZS5cbiAqL1xuZXhwb3J0IGNvbnN0IGdldFNlcnZlcnMgPSAoKSA9PiBhY3RpdmVTZXJ2ZXJzO1xuXG4vKipcbiAqIEVuYWJsZSByYXRlIGxpbWl0aW5nIGZvciB0aGUgc2VydmVyLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBsaW1pdENvbmZpZyAtIENvbmZpZ3VyYXRpb24gb2JqZWN0IGZvciByYXRlIGxpbWl0aW5nLlxuICovXG5leHBvcnQgY29uc3QgZW5hYmxlUmF0ZUxpbWl0aW5nID0gKGxpbWl0Q29uZmlnKSA9PiByYXRlTGltaXQoYXBwLCBsaW1pdENvbmZpZyk7XG5cbi8qKlxuICogR2V0IHRoZSBFeHByZXNzIGluc3RhbmNlLlxuICpcbiAqIEByZXR1cm5zIHtPYmplY3R9IC0gVGhlIEV4cHJlc3MgaW5zdGFuY2UuXG4gKi9cbmV4cG9ydCBjb25zdCBnZXRFeHByZXNzID0gKCkgPT4gZXhwcmVzcztcblxuLyoqXG4gKiBHZXQgdGhlIEV4cHJlc3MgYXBwIGluc3RhbmNlLlxuICpcbiAqIEByZXR1cm5zIHtPYmplY3R9IC0gVGhlIEV4cHJlc3MgYXBwIGluc3RhbmNlLlxuICovXG5leHBvcnQgY29uc3QgZ2V0QXBwID0gKCkgPT4gYXBwO1xuXG4vKipcbiAqIEFwcGx5IG1pZGRsZXdhcmUocykgdG8gYSBzcGVjaWZpYyBwYXRoLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoIC0gVGhlIHBhdGggdG8gd2hpY2ggdGhlIG1pZGRsZXdhcmUocykgc2hvdWxkIGJlIGFwcGxpZWQuXG4gKiBAcGFyYW0gey4uLkZ1bmN0aW9ufSBtaWRkbGV3YXJlcyAtIFRoZSBtaWRkbGV3YXJlIGZ1bmN0aW9ucyB0byBiZSBhcHBsaWVkLlxuICovXG5leHBvcnQgY29uc3QgdXNlID0gKHBhdGgsIC4uLm1pZGRsZXdhcmVzKSA9PiB7XG4gIGFwcC51c2UocGF0aCwgLi4ubWlkZGxld2FyZXMpO1xufTtcblxuLyoqXG4gKiBTZXQgdXAgYSByb3V0ZSB3aXRoIEdFVCBtZXRob2QgYW5kIGFwcGx5IG1pZGRsZXdhcmUocykuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHBhdGggLSBUaGUgcm91dGUgcGF0aC5cbiAqIEBwYXJhbSB7Li4uRnVuY3Rpb259IG1pZGRsZXdhcmVzIC0gVGhlIG1pZGRsZXdhcmUgZnVuY3Rpb25zIHRvIGJlIGFwcGxpZWQuXG4gKi9cbmV4cG9ydCBjb25zdCBnZXQgPSAocGF0aCwgLi4ubWlkZGxld2FyZXMpID0+IHtcbiAgYXBwLmdldChwYXRoLCAuLi5taWRkbGV3YXJlcyk7XG59O1xuXG4vKipcbiAqIFNldCB1cCBhIHJvdXRlIHdpdGggUE9TVCBtZXRob2QgYW5kIGFwcGx5IG1pZGRsZXdhcmUocykuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHBhdGggLSBUaGUgcm91dGUgcGF0aC5cbiAqIEBwYXJhbSB7Li4uRnVuY3Rpb259IG1pZGRsZXdhcmVzIC0gVGhlIG1pZGRsZXdhcmUgZnVuY3Rpb25zIHRvIGJlIGFwcGxpZWQuXG4gKi9cbmV4cG9ydCBjb25zdCBwb3N0ID0gKHBhdGgsIC4uLm1pZGRsZXdhcmVzKSA9PiB7XG4gIGFwcC5wb3N0KHBhdGgsIC4uLm1pZGRsZXdhcmVzKTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgc3RhcnRTZXJ2ZXIsXG4gIGNsb3NlU2VydmVycyxcbiAgZ2V0U2VydmVycyxcbiAgZW5hYmxlUmF0ZUxpbWl0aW5nLFxuICBnZXRFeHByZXNzLFxuICBnZXRBcHAsXG4gIHVzZSxcbiAgZ2V0LFxuICBwb3N0XG59O1xuIiwiLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcblxuSGlnaGNoYXJ0cyBFeHBvcnQgU2VydmVyXG5cbkNvcHlyaWdodCAoYykgMjAxNi0yMDI0LCBIaWdoc29mdFxuXG5MaWNlbmNlZCB1bmRlciB0aGUgTUlUIGxpY2VuY2UuXG5cbkFkZGl0aW9uYWxseSBhIHZhbGlkIEhpZ2hjaGFydHMgbGljZW5zZSBpcyByZXF1aXJlZCBmb3IgdXNlLlxuXG5TZWUgTElDRU5TRSBmaWxlIGluIHJvb3QgZm9yIGRldGFpbHMuXG5cbioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG5cbmltcG9ydCB7IGpvaW4gfSBmcm9tICdwYXRoJztcblxuaW1wb3J0IHsgX19kaXJuYW1lIH0gZnJvbSAnLi4vLi4vdXRpbHMuanMnO1xuXG4vKipcbiAqIEFkZHMgdGhlIEdFVCAvIHJvdXRlIGZvciBhIFVJIHdoZW4gZW5hYmxlZCBvbiB0aGUgZXhwb3J0IHNlcnZlci5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgKGFwcCkgPT5cbiAgIWFwcFxuICAgID8gZmFsc2VcbiAgICA6IGFwcC5nZXQoJy8nLCAoX3JlcXVlc3QsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgIHJlc3BvbnNlLnNlbmRGaWxlKGpvaW4oX19kaXJuYW1lLCAncHVibGljJywgJ2luZGV4Lmh0bWwnKSwge1xuICAgICAgICAgIGFjY2VwdFJhbmdlczogZmFsc2VcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiIsIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG5cbkhpZ2hjaGFydHMgRXhwb3J0IFNlcnZlclxuXG5Db3B5cmlnaHQgKGMpIDIwMTYtMjAyNCwgSGlnaHNvZnRcblxuTGljZW5jZWQgdW5kZXIgdGhlIE1JVCBsaWNlbmNlLlxuXG5BZGRpdGlvbmFsbHkgYSB2YWxpZCBIaWdoY2hhcnRzIGxpY2Vuc2UgaXMgcmVxdWlyZWQgZm9yIHVzZS5cblxuU2VlIExJQ0VOU0UgZmlsZSBpbiByb290IGZvciBkZXRhaWxzLlxuXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG5pbXBvcnQgeyBjbGVhckFsbEludGVydmFscyB9IGZyb20gJy4vaW50ZXJ2YWxzLmpzJztcbmltcG9ydCB7IGtpbGxQb29sIH0gZnJvbSAnLi9wb29sLmpzJztcbmltcG9ydCB7IGNsb3NlU2VydmVycyB9IGZyb20gJy4vc2VydmVyL3NlcnZlci5qcyc7XG5cbi8qKlxuICogQ2xlYW4gdXAgZnVuY3Rpb24gdG8gdHJpZ2dlciBiZWZvcmUgZW5kaW5nIHByb2Nlc3MgZm9yIHRoZSBncmFjZWZ1bCBzaHV0ZG93bi5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gZXhpdENvZGUgLSBBbiBleGl0IGNvZGUgZm9yIHRoZSBwcm9jZXNzLmV4aXQoKSBmdW5jdGlvbi5cbiAqL1xuZXhwb3J0IGNvbnN0IHNodXRkb3duQ2xlYW5VcCA9IGFzeW5jIChleGl0Q29kZSkgPT4ge1xuICAvLyBBd2FpdCBmcmVlaW5nIGFsbCByZXNvdXJjZXNcbiAgYXdhaXQgUHJvbWlzZS5hbGxTZXR0bGVkKFtcbiAgICAvLyBDbGVhciBhbGwgb25nb2luZyBpbnRlcnZhbHNcbiAgICBjbGVhckFsbEludGVydmFscygpLFxuXG4gICAgLy8gR2V0IGF2YWlsYWJsZSBzZXJ2ZXIgaW5zdGFuY2VzIChIVFRQL0hUVFBTKSBhbmQgY2xvc2UgdGhlbVxuICAgIGNsb3NlU2VydmVycygpLFxuXG4gICAgLy8gQ2xvc2UgcG9vbCBhbG9uZyB3aXRoIGl0cyB3b3JrZXJzIGFuZCB0aGUgYnJvd3NlciBpbnN0YW5jZSwgaWYgZXhpc3RzXG4gICAga2lsbFBvb2woKVxuICBdKTtcblxuICAvLyBFeGl0IHByb2Nlc3Mgd2l0aCBhIGNvcnJlY3QgY29kZVxuICBwcm9jZXNzLmV4aXQoZXhpdENvZGUpO1xufTtcblxuZXhwb3J0IGRlZmF1bHQge1xuICBzaHV0ZG93bkNsZWFuVXBcbn07XG4iLCIvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuXG5IaWdoY2hhcnRzIEV4cG9ydCBTZXJ2ZXJcblxuQ29weXJpZ2h0IChjKSAyMDE2LTIwMjQsIEhpZ2hzb2Z0XG5cbkxpY2VuY2VkIHVuZGVyIHRoZSBNSVQgbGljZW5jZS5cblxuQWRkaXRpb25hbGx5IGEgdmFsaWQgSGlnaGNoYXJ0cyBsaWNlbnNlIGlzIHJlcXVpcmVkIGZvciB1c2UuXG5cblNlZSBMSUNFTlNFIGZpbGUgaW4gcm9vdCBmb3IgZGV0YWlscy5cblxuKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuaW1wb3J0ICdjb2xvcnMnO1xuXG5pbXBvcnQgeyBjaGVja0FuZFVwZGF0ZUNhY2hlIH0gZnJvbSAnLi9jYWNoZS5qcyc7XG5pbXBvcnQge1xuICBiYXRjaEV4cG9ydCxcbiAgc2V0QWxsb3dDb2RlRXhlY3V0aW9uLFxuICBzaW5nbGVFeHBvcnQsXG4gIHN0YXJ0RXhwb3J0XG59IGZyb20gJy4vY2hhcnQuanMnO1xuaW1wb3J0IHsgbWFwVG9OZXdDb25maWcsIG1hbnVhbENvbmZpZywgc2V0T3B0aW9ucyB9IGZyb20gJy4vY29uZmlnLmpzJztcbmltcG9ydCB7XG4gIGluaXRMb2dnaW5nLFxuICBsb2csXG4gIGxvZ1dpdGhTdGFjayxcbiAgc2V0TG9nTGV2ZWwsXG4gIGVuYWJsZUZpbGVMb2dnaW5nXG59IGZyb20gJy4vbG9nZ2VyLmpzJztcbmltcG9ydCB7IGluaXRQb29sLCBraWxsUG9vbCB9IGZyb20gJy4vcG9vbC5qcyc7XG5pbXBvcnQgeyBzaHV0ZG93bkNsZWFuVXAgfSBmcm9tICcuL3Jlc291cmNlX3JlbGVhc2UuanMnO1xuaW1wb3J0IHNlcnZlciwgeyBzdGFydFNlcnZlciB9IGZyb20gJy4vc2VydmVyL3NlcnZlci5qcyc7XG5pbXBvcnQgeyBwcmludExvZ28sIHByaW50VXNhZ2UgfSBmcm9tICcuL3V0aWxzLmpzJztcblxuLyoqXG4gKiBBdHRhY2hlcyBleGl0IGxpc3RlbmVycyB0byB0aGUgcHJvY2VzcywgZW5zdXJpbmcgcHJvcGVyIGNsZWFudXAgb2YgcmVzb3VyY2VzXG4gKiBhbmQgdGVybWluYXRpb24gb24gZXhpdCBzaWduYWxzLiBIYW5kbGVzICdleGl0JywgJ1NJR0lOVCcsICdTSUdURVJNJywgYW5kXG4gKiAndW5jYXVnaHRFeGNlcHRpb24nIGV2ZW50cy5cbiAqL1xuY29uc3QgYXR0YWNoUHJvY2Vzc0V4aXRMaXN0ZW5lcnMgPSAoKSA9PiB7XG4gIGxvZygzLCAnW3Byb2Nlc3NdIEF0dGFjaGluZyBleGl0IGxpc3RlbmVycyB0byB0aGUgcHJvY2Vzcy4nKTtcblxuICAvLyBIYW5kbGVyIGZvciB0aGUgJ2V4aXQnXG4gIHByb2Nlc3Mub24oJ2V4aXQnLCAoY29kZSkgPT4ge1xuICAgIGxvZyg0LCBgUHJvY2VzcyBleGl0ZWQgd2l0aCBjb2RlICR7Y29kZX0uYCk7XG4gIH0pO1xuXG4gIC8vIEhhbmRsZXIgZm9yIHRoZSAnU0lHSU5UJ1xuICBwcm9jZXNzLm9uKCdTSUdJTlQnLCBhc3luYyAobmFtZSwgY29kZSkgPT4ge1xuICAgIGxvZyg0LCBgVGhlICR7bmFtZX0gZXZlbnQgd2l0aCBjb2RlOiAke2NvZGV9LmApO1xuICAgIGF3YWl0IHNodXRkb3duQ2xlYW5VcCgwKTtcbiAgfSk7XG5cbiAgLy8gSGFuZGxlciBmb3IgdGhlICdTSUdURVJNJ1xuICBwcm9jZXNzLm9uKCdTSUdURVJNJywgYXN5bmMgKG5hbWUsIGNvZGUpID0+IHtcbiAgICBsb2coNCwgYFRoZSAke25hbWV9IGV2ZW50IHdpdGggY29kZTogJHtjb2RlfS5gKTtcbiAgICBhd2FpdCBzaHV0ZG93bkNsZWFuVXAoMCk7XG4gIH0pO1xuXG4gIC8vIEhhbmRsZXIgZm9yIHRoZSAnU0lHSFVQJ1xuICBwcm9jZXNzLm9uKCdTSUdIVVAnLCBhc3luYyAobmFtZSwgY29kZSkgPT4ge1xuICAgIGxvZyg0LCBgVGhlICR7bmFtZX0gZXZlbnQgd2l0aCBjb2RlOiAke2NvZGV9LmApO1xuICAgIGF3YWl0IHNodXRkb3duQ2xlYW5VcCgwKTtcbiAgfSk7XG5cbiAgLy8gSGFuZGxlciBmb3IgdGhlICd1bmNhdWdodEV4Y2VwdGlvbidcbiAgcHJvY2Vzcy5vbigndW5jYXVnaHRFeGNlcHRpb24nLCBhc3luYyAoZXJyb3IsIG5hbWUpID0+IHtcbiAgICBsb2dXaXRoU3RhY2soMSwgZXJyb3IsIGBUaGUgJHtuYW1lfSBlcnJvci5gKTtcbiAgICBhd2FpdCBzaHV0ZG93bkNsZWFuVXAoMSk7XG4gIH0pO1xufTtcblxuLyoqXG4gKiBJbml0aWFsaXplcyB0aGUgZXhwb3J0IHByb2Nlc3MuIFRhc2tzIHN1Y2ggYXMgY29uZmlndXJpbmcgbG9nZ2luZywgY2hlY2tpbmdcbiAqIGNhY2hlIGFuZCBzb3VyY2VzLCBhbmQgaW5pdGlhbGl6aW5nIHRoZSBwb29sIG9mIHJlc291cmNlcyBoYXBwZW4gZHVyaW5nXG4gKiB0aGlzIHN0YWdlLiBGdW5jdGlvbiB0aGF0IGlzIHJlcXVpcmVkIHRvIGJlIGNhbGxlZCBiZWZvcmUgdHJ5aW5nIHRvIGV4cG9ydCBjaGFydHMgb3Igc2V0dGluZyBhIHNlcnZlci4gVGhlIGBvcHRpb25zYCBpcyBhbiBvYmplY3QgdGhhdCBjb250YWlucyBhbGwgb3B0aW9ucy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIEFsbCBleHBvcnQgb3B0aW9ucy5cbiAqXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxPYmplY3Q+fSBQcm9taXNlIHJlc29sdmluZyB0byB0aGUgdXBkYXRlZCBleHBvcnQgb3B0aW9ucy5cbiAqL1xuY29uc3QgaW5pdEV4cG9ydCA9IGFzeW5jIChvcHRpb25zKSA9PiB7XG4gIC8vIFNldCB0aGUgYWxsb3dDb2RlRXhlY3V0aW9uIHBlciBleHBvcnQgbW9kdWxlIHNjb3BlXG4gIHNldEFsbG93Q29kZUV4ZWN1dGlvbihcbiAgICBvcHRpb25zLmN1c3RvbUxvZ2ljICYmIG9wdGlvbnMuY3VzdG9tTG9naWMuYWxsb3dDb2RlRXhlY3V0aW9uXG4gICk7XG5cbiAgLy8gSW5pdCB0aGUgbG9nZ2luZ1xuICBpbml0TG9nZ2luZyhvcHRpb25zLmxvZ2dpbmcpO1xuXG4gIC8vIEF0dGFjaCBwcm9jZXNzJyBleGl0IGxpc3RlbmVyc1xuICBpZiAob3B0aW9ucy5vdGhlci5saXN0ZW5Ub1Byb2Nlc3NFeGl0cykge1xuICAgIGF0dGFjaFByb2Nlc3NFeGl0TGlzdGVuZXJzKCk7XG4gIH1cblxuICAvLyBDaGVjayBpZiBjYWNoZSBuZWVkcyB0byBiZSB1cGRhdGVkXG4gIGF3YWl0IGNoZWNrQW5kVXBkYXRlQ2FjaGUob3B0aW9ucyk7XG5cbiAgLy8gSW5pdCB0aGUgcG9vbFxuICBhd2FpdCBpbml0UG9vbCh7XG4gICAgcG9vbDogb3B0aW9ucy5wb29sIHx8IHtcbiAgICAgIG1pbldvcmtlcnM6IDEsXG4gICAgICBtYXhXb3JrZXJzOiAxXG4gICAgfSxcbiAgICBwdXBwZXRlZXJBcmdzOiBvcHRpb25zLnB1cHBldGVlci5hcmdzIHx8IFtdXG4gIH0pO1xuXG4gIC8vIFJldHVybiB1cGRhdGVkIG9wdGlvbnNcbiAgcmV0dXJuIG9wdGlvbnM7XG59O1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIC8vIFNlcnZlclxuICBzZXJ2ZXIsXG4gIHN0YXJ0U2VydmVyLFxuXG4gIC8vIEV4cG9ydGluZ1xuICBpbml0RXhwb3J0LFxuICBzaW5nbGVFeHBvcnQsXG4gIGJhdGNoRXhwb3J0LFxuICBzdGFydEV4cG9ydCxcblxuICAvLyBQb29sXG4gIGluaXRQb29sLFxuICBraWxsUG9vbCxcblxuICAvLyBPdGhlclxuICBzZXRPcHRpb25zLFxuICBzaHV0ZG93bkNsZWFuVXAsXG5cbiAgLy8gTG9nc1xuICBsb2csXG4gIGxvZ1dpdGhTdGFjayxcbiAgc2V0TG9nTGV2ZWwsXG4gIGVuYWJsZUZpbGVMb2dnaW5nLFxuXG4gIC8vIFV0aWxzXG4gIG1hcFRvTmV3Q29uZmlnLFxuICBtYW51YWxDb25maWcsXG4gIHByaW50TG9nbyxcbiAgcHJpbnRVc2FnZVxufTtcbiJdLCJuYW1lcyI6WyJzY3JpcHRzTmFtZXMiLCJjb3JlIiwibW9kdWxlcyIsImluZGljYXRvcnMiLCJjdXN0b20iLCJkZWZhdWx0Q29uZmlnIiwicHVwcGV0ZWVyIiwiYXJncyIsInZhbHVlIiwidHlwZSIsImRlc2NyaXB0aW9uIiwidGVtcERpciIsImVudkxpbmsiLCJoaWdoY2hhcnRzIiwidmVyc2lvbiIsImNkblVSTCIsImNvcmVTY3JpcHRzIiwibW9kdWxlU2NyaXB0cyIsImluZGljYXRvclNjcmlwdHMiLCJjdXN0b21TY3JpcHRzIiwiZm9yY2VGZXRjaCIsImNhY2hlUGF0aCIsImV4cG9ydCIsImluZmlsZSIsImluc3RyIiwib3B0aW9ucyIsIm91dGZpbGUiLCJjb25zdHIiLCJkZWZhdWx0SGVpZ2h0IiwiZGVmYXVsdFdpZHRoIiwiZGVmYXVsdFNjYWxlIiwiaGVpZ2h0Iiwid2lkdGgiLCJzY2FsZSIsImdsb2JhbE9wdGlvbnMiLCJ0aGVtZU9wdGlvbnMiLCJiYXRjaCIsInJhc3Rlcml6YXRpb25UaW1lb3V0IiwiY3VzdG9tTG9naWMiLCJhbGxvd0NvZGVFeGVjdXRpb24iLCJhbGxvd0ZpbGVSZXNvdXJjZXMiLCJjdXN0b21Db2RlIiwiY2FsbGJhY2siLCJyZXNvdXJjZXMiLCJsb2FkQ29uZmlnIiwibGVnYWN5TmFtZSIsImNyZWF0ZUNvbmZpZyIsInNlcnZlciIsIm1heFVwbG9hZFNpemUiLCJlbmFibGUiLCJjbGlOYW1lIiwiaG9zdCIsInBvcnQiLCJiZW5jaG1hcmtpbmciLCJwcm94eSIsInVzZXJuYW1lIiwicGFzc3dvcmQiLCJ0aW1lb3V0IiwicmF0ZUxpbWl0aW5nIiwibWF4UmVxdWVzdHMiLCJ3aW5kb3ciLCJkZWxheSIsInRydXN0UHJveHkiLCJza2lwS2V5Iiwic2tpcFRva2VuIiwic3NsIiwiZm9yY2UiLCJjZXJ0UGF0aCIsInBvb2wiLCJtaW5Xb3JrZXJzIiwibWF4V29ya2VycyIsIndvcmtMaW1pdCIsImFjcXVpcmVUaW1lb3V0IiwiY3JlYXRlVGltZW91dCIsImRlc3Ryb3lUaW1lb3V0IiwiaWRsZVRpbWVvdXQiLCJjcmVhdGVSZXRyeUludGVydmFsIiwicmVhcGVySW50ZXJ2YWwiLCJsb2dnaW5nIiwibGV2ZWwiLCJmaWxlIiwiZGVzdCIsInRvQ29uc29sZSIsInRvRmlsZSIsInVpIiwicm91dGUiLCJvdGhlciIsIm5vZGVFbnYiLCJsaXN0ZW5Ub1Byb2Nlc3NFeGl0cyIsIm5vTG9nbyIsImhhcmRSZXNldFBhZ2UiLCJicm93c2VyU2hlbGxNb2RlIiwiZGVidWciLCJoZWFkbGVzcyIsImRldnRvb2xzIiwibGlzdGVuVG9Db25zb2xlIiwiZHVtcGlvIiwic2xvd01vIiwiZGVidWdnaW5nUG9ydCIsInByb21wdHNDb25maWciLCJuYW1lIiwibWVzc2FnZSIsImluaXRpYWwiLCJqb2luIiwic2VwYXJhdG9yIiwiaW5zdHJ1Y3Rpb25zIiwiY2hvaWNlcyIsImhpbnQiLCJtaW4iLCJtYXgiLCJyb3VuZCIsImFic29sdXRlUHJvcHMiLCJuZXN0ZWRBcmdzIiwiY3JlYXRlTmVzdGVkQXJncyIsIm9iaiIsInByb3BDaGFpbiIsIk9iamVjdCIsImtleXMiLCJmb3JFYWNoIiwiayIsImluY2x1ZGVzIiwiZW50cnkiLCJzdWJzdHJpbmciLCJ1bmRlZmluZWQiLCJkb3RlbnYiLCJjb25maWciLCJ2IiwiZmlsdGVyQXJyYXkiLCJ6Iiwic3RyaW5nIiwidHJhbnNmb3JtIiwic3BsaXQiLCJtYXAiLCJ0cmltIiwiZmlsdGVyIiwibGVuZ3RoIiwiZW51bSIsInZhbHVlcyIsInJlZmluZSIsInRlc3QiLCJpc05hTiIsInBhcnNlRmxvYXQiLCJlbnZzIiwib2JqZWN0IiwiUFVQUEVURUVSX1RFTVBfRElSIiwiSElHSENIQVJUU19WRVJTSU9OIiwiSElHSENIQVJUU19DRE5fVVJMIiwic3RhcnRzV2l0aCIsIkhJR0hDSEFSVFNfQ09SRV9TQ1JJUFRTIiwiSElHSENIQVJUU19NT0RVTEVfU0NSSVBUUyIsIkhJR0hDSEFSVFNfSU5ESUNBVE9SX1NDUklQVFMiLCJISUdIQ0hBUlRTX0ZPUkNFX0ZFVENIIiwiSElHSENIQVJUU19DQUNIRV9QQVRIIiwiSElHSENIQVJUU19BRE1JTl9UT0tFTiIsIkVYUE9SVF9UWVBFIiwiRVhQT1JUX0NPTlNUUiIsIkVYUE9SVF9ERUZBVUxUX0hFSUdIVCIsIkVYUE9SVF9ERUZBVUxUX1dJRFRIIiwiRVhQT1JUX0RFRkFVTFRfU0NBTEUiLCJFWFBPUlRfUkFTVEVSSVpBVElPTl9USU1FT1VUIiwiQ1VTVE9NX0xPR0lDX0FMTE9XX0NPREVfRVhFQ1VUSU9OIiwiQ1VTVE9NX0xPR0lDX0FMTE9XX0ZJTEVfUkVTT1VSQ0VTIiwiU0VSVkVSX0VOQUJMRSIsIlNFUlZFUl9IT1NUIiwiU0VSVkVSX1BPUlQiLCJTRVJWRVJfTUFYX1VQTE9BRF9TSVpFIiwiU0VSVkVSX0JFTkNITUFSS0lORyIsIlNFUlZFUl9QUk9YWV9IT1NUIiwiU0VSVkVSX1BST1hZX1BPUlQiLCJTRVJWRVJfUFJPWFlfVVNFUk5BTUUiLCJTRVJWRVJfUFJPWFlfUEFTU1dPUkQiLCJTRVJWRVJfUFJPWFlfVElNRU9VVCIsIlNFUlZFUl9SQVRFX0xJTUlUSU5HX0VOQUJMRSIsIlNFUlZFUl9SQVRFX0xJTUlUSU5HX01BWF9SRVFVRVNUUyIsIlNFUlZFUl9SQVRFX0xJTUlUSU5HX1dJTkRPVyIsIlNFUlZFUl9SQVRFX0xJTUlUSU5HX0RFTEFZIiwiU0VSVkVSX1JBVEVfTElNSVRJTkdfVFJVU1RfUFJPWFkiLCJTRVJWRVJfUkFURV9MSU1JVElOR19TS0lQX0tFWSIsIlNFUlZFUl9SQVRFX0xJTUlUSU5HX1NLSVBfVE9LRU4iLCJTRVJWRVJfU1NMX0VOQUJMRSIsIlNFUlZFUl9TU0xfRk9SQ0UiLCJTRVJWRVJfU1NMX1BPUlQiLCJTRVJWRVJfU1NMX0NFUlRfUEFUSCIsIlBPT0xfTUlOX1dPUktFUlMiLCJQT09MX01BWF9XT1JLRVJTIiwiUE9PTF9XT1JLX0xJTUlUIiwiUE9PTF9BQ1FVSVJFX1RJTUVPVVQiLCJQT09MX0NSRUFURV9USU1FT1VUIiwiUE9PTF9ERVNUUk9ZX1RJTUVPVVQiLCJQT09MX0lETEVfVElNRU9VVCIsIlBPT0xfQ1JFQVRFX1JFVFJZX0lOVEVSVkFMIiwiUE9PTF9SRUFQRVJfSU5URVJWQUwiLCJQT09MX0JFTkNITUFSS0lORyIsIkxPR0dJTkdfTEVWRUwiLCJMT0dHSU5HX0ZJTEUiLCJMT0dHSU5HX0RFU1QiLCJMT0dHSU5HX1RPX0NPTlNPTEUiLCJMT0dHSU5HX1RPX0ZJTEUiLCJVSV9FTkFCTEUiLCJVSV9ST1VURSIsIk9USEVSX05PREVfRU5WIiwiT1RIRVJfTElTVEVOX1RPX1BST0NFU1NfRVhJVFMiLCJPVEhFUl9OT19MT0dPIiwiT1RIRVJfSEFSRF9SRVNFVF9QQUdFIiwiT1RIRVJfQlJPV1NFUl9TSEVMTF9NT0RFIiwiT1RIRVJfQUxMT1dfWExJTksiLCJERUJVR19FTkFCTEUiLCJERUJVR19IRUFETEVTUyIsIkRFQlVHX0RFVlRPT0xTIiwiREVCVUdfTElTVEVOX1RPX0NPTlNPTEUiLCJERUJVR19EVU1QSU8iLCJERUJVR19TTE9XX01PIiwiREVCVUdfREVCVUdHSU5HX1BPUlQiLCJwYXJ0aWFsIiwicGFyc2UiLCJwcm9jZXNzIiwiZW52IiwiY29sb3JzIiwicGF0aENyZWF0ZWQiLCJsZXZlbHNEZXNjIiwidGl0bGUiLCJjb2xvciIsImxpc3RlbmVycyIsImxvZ1RvRmlsZSIsInRleHRzIiwicHJlZml4IiwiZXhpc3RzU3luYyIsIm1rZGlyU3luYyIsImFwcGVuZEZpbGUiLCJjb25jYXQiLCJlcnJvciIsImNvbnNvbGUiLCJsb2ciLCJuZXdMZXZlbCIsIkRhdGUiLCJ0b1N0cmluZyIsImZuIiwiYXBwbHkiLCJsb2dXaXRoU3RhY2siLCJjdXN0b21NZXNzYWdlIiwibWFpbk1lc3NhZ2UiLCJzdGFja01lc3NhZ2UiLCJzdGFjayIsInNsaWNlIiwic2V0TG9nTGV2ZWwiLCJlbmFibGVGaWxlTG9nZ2luZyIsImxvZ0Rlc3QiLCJsb2dGaWxlIiwiZW5kc1dpdGgiLCJfX2Rpcm5hbWUiLCJmaWxlVVJMVG9QYXRoIiwiVVJMIiwiZG9jdW1lbnQiLCJyZXF1aXJlIiwicGF0aFRvRmlsZVVSTCIsIl9fZmlsZW5hbWUiLCJocmVmIiwiX2RvY3VtZW50Q3VycmVudFNjcmlwdCIsInRhZ05hbWUiLCJ0b1VwcGVyQ2FzZSIsInNyYyIsImJhc2VVUkkiLCJmaXhUeXBlIiwiZm9ybWF0cyIsIm91dFR5cGUiLCJwb3AiLCJmaW5kIiwidCIsImhhbmRsZVJlc291cmNlcyIsImFsbG93ZWRQcm9wcyIsImhhbmRsZWRSZXNvdXJjZXMiLCJjb3JyZWN0UmVzb3VyY2VzIiwiaXNDb3JyZWN0SlNPTiIsInJlYWRGaWxlU3luYyIsImZpbGVzIiwicHJvcE5hbWUiLCJpdGVtIiwiZGF0YSIsInBhcnNlZERhdGEiLCJKU09OIiwic3RyaW5naWZ5IiwiaXNPYmplY3QiLCJBcnJheSIsImlzQXJyYXkiLCJkZWVwQ29weSIsImNvcHkiLCJrZXkiLCJwcm90b3R5cGUiLCJoYXNPd25Qcm9wZXJ0eSIsImNhbGwiLCJvcHRpb25zU3RyaW5naWZ5IiwiYWxsb3dGdW5jdGlvbnMiLCJyZXBsYWNlQWxsIiwicHJpbnRVc2FnZSIsImJvbGQiLCJ5ZWxsb3ciLCJjeWNsZUNhdGVnb3JpZXMiLCJvcHRpb24iLCJlbnRyaWVzIiwiZGVzY05hbWUiLCJncmVlbiIsImkiLCJibHVlIiwiY2F0ZWdvcnkiLCJyZWQiLCJ0b0Jvb2xlYW4iLCJ3cmFwQXJvdW5kIiwicmVwbGFjZSIsIm1lYXN1cmVUaW1lIiwic3RhcnQiLCJocnRpbWUiLCJiaWdpbnQiLCJOdW1iZXIiLCJnZW5lcmFsT3B0aW9ucyIsImdldE9wdGlvbnMiLCJtZXJnZUNvbmZpZ09wdGlvbnMiLCJuZXdPcHRpb25zIiwibWVyZ2VkT3B0aW9ucyIsInVwZGF0ZURlZmF1bHRDb25maWciLCJjb25maWdPYmoiLCJjdXN0b21PYmoiLCJjdXN0b21WYWx1ZSIsImluaXRPcHRpb25zIiwiaXRlbXMiLCJyZWN1cnNpdmVQcm9wcyIsIm9iamVjdFRvVXBkYXRlIiwibmVzdGVkTmFtZXMiLCJzaGlmdCIsImFzc2lnbiIsImFzeW5jIiwiZmV0Y2giLCJ1cmwiLCJyZXF1ZXN0T3B0aW9ucyIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVqZWN0IiwicHJvdG9jb2wiLCJodHRwcyIsImh0dHAiLCJnZXRQcm90b2NvbCIsImdldCIsImhlYWRlcnMiLCJSZWZlcmVyIiwicmVzIiwib24iLCJjaHVuayIsInRleHQiLCJFeHBvcnRFcnJvciIsIkVycm9yIiwiY29uc3RydWN0b3IiLCJzdXBlciIsInRoaXMiLCJzZXRFcnJvciIsInN0YXR1c0NvZGUiLCJjYWNoZSIsImFjdGl2ZU1hbmlmZXN0Iiwic291cmNlcyIsImhjVmVyc2lvbiIsImV4dHJhY3RWZXJzaW9uIiwiaW5kZXhPZiIsImZldGNoQW5kUHJvY2Vzc1NjcmlwdCIsInNjcmlwdCIsImZldGNoZWRNb2R1bGVzIiwic2hvdWxkVGhyb3dFcnJvciIsInJlc3BvbnNlIiwidXBkYXRlQ2FjaGUiLCJoaWdoY2hhcnRzT3B0aW9ucyIsInByb3h5T3B0aW9ucyIsInNvdXJjZVBhdGgiLCJwcm94eUFnZW50IiwiSHR0cHNQcm94eUFnZW50IiwiYWdlbnQiLCJhbGxGZXRjaFByb21pc2VzIiwiYWxsIiwiZmV0Y2hTY3JpcHRzIiwiYyIsIm0iLCJ3cml0ZUZpbGVTeW5jIiwiY2hlY2tBbmRVcGRhdGVDYWNoZSIsIm1hbmlmZXN0UGF0aCIsInJlcXVlc3RVcGRhdGUiLCJtYW5pZmVzdCIsIm1vZHVsZU1hcCIsIm51bWJlck9mTW9kdWxlcyIsInNvbWUiLCJtb2R1bGVOYW1lIiwibmV3TWFuaWZlc3QiLCJzYXZlQ29uZmlnVG9NYW5pZmVzdCIsInNldHVwSGlnaGNoYXJ0cyIsIkhpZ2hjaGFydHMiLCJhbmltT2JqZWN0IiwiZHVyYXRpb24iLCJ0cmlnZ2VyRXhwb3J0IiwiY2hhcnRPcHRpb25zIiwiZGlzcGxheUVycm9ycyIsIl9kaXNwbGF5RXJyb3JzIiwibWVyZ2UiLCJzZXRPcHRpb25zIiwid3JhcCIsInNldE9wdGlvbnNPYmoiLCJjaGFydCIsImFuaW1hdGlvbiIsInN0ckluaiIsImlzUmVuZGVyQ29tcGxldGUiLCJDaGFydCIsInByb2NlZWQiLCJ1c2VyT3B0aW9ucyIsImNiIiwiZXhwb3J0aW5nIiwiZW5hYmxlZCIsInBsb3RPcHRpb25zIiwic2VyaWVzIiwibGFiZWwiLCJ0b29sdGlwIiwib25IaWdoY2hhcnRzUmVuZGVyIiwiYWRkRXZlbnQiLCJTZXJpZXMiLCJGdW5jdGlvbiIsImZpbmFsT3B0aW9ucyIsImZpbmFsQ2FsbGJhY2siLCJkZWZhdWx0T3B0aW9ucyIsInByb3AiLCJ0ZW1wbGF0ZSIsImJyb3dzZXIiLCJuZXdQYWdlIiwicGFnZSIsInNldENhY2hlRW5hYmxlZCIsInNldFBhZ2VDb250ZW50IiwiaXNDbG9zZWQiLCIkZXZhbCIsImVsZW1lbnQiLCJlcnJvck1lc3NhZ2UiLCJpbm5lckhUTUwiLCJzZXRQYWdlRXZlbnRzIiwiY2xlYXJQYWdlUmVzb3VyY2VzIiwiaW5qZWN0ZWRSZXNvdXJjZXMiLCJyZXNvdXJjZSIsImRpc3Bvc2UiLCJldmFsdWF0ZSIsIm9sZENoYXJ0cyIsImNoYXJ0cyIsIm9sZENoYXJ0IiwiZGVzdHJveSIsInNjcmlwdHNUb1JlbW92ZSIsImdldEVsZW1lbnRzQnlUYWdOYW1lIiwic3R5bGVzVG9SZW1vdmUiLCJsaW5rc1RvUmVtb3ZlIiwicmVtb3ZlIiwic2V0Q29udGVudCIsIndhaXRVbnRpbCIsImFkZFNjcmlwdFRhZyIsInBhdGgiLCJzZXRBc0NvbmZpZyIsInRvdGFsU2l6ZSIsIkJ1ZmZlciIsImJ5dGVMZW5ndGgiLCJ0b0ZpeGVkIiwicHVwcGV0ZWVyRXhwb3J0IiwiZXhwb3J0T3B0aW9ucyIsImRlYnVnZ2VyIiwiaXNTVkciLCJzdmdUZW1wbGF0ZSIsImluamVjdGVkSnMiLCJqcyIsInB1c2giLCJjb250ZW50IiwiaXNMb2NhbCIsImpzUmVzb3VyY2UiLCJpbmplY3RlZENzcyIsImNzcyIsImNzc0ltcG9ydHMiLCJtYXRjaCIsImNzc0ltcG9ydFBhdGgiLCJjc3NSZXNvdXJjZSIsImFkZFN0eWxlVGFnIiwiYWRkUGFnZVJlc291cmNlcyIsInNpemUiLCJzdmdFbGVtZW50IiwicXVlcnlTZWxlY3RvciIsImNoYXJ0SGVpZ2h0IiwiYmFzZVZhbCIsImNoYXJ0V2lkdGgiLCJib2R5Iiwic3R5bGUiLCJ6b29tIiwibWFyZ2luIiwidmlld3BvcnRIZWlnaHQiLCJNYXRoIiwiYWJzIiwiY2VpbCIsInZpZXdwb3J0V2lkdGgiLCJ4IiwieSIsImdldEJvdW5kaW5nQ2xpZW50UmVjdCIsInRydW5jIiwiZ2V0Q2xpcFJlZ2lvbiIsInNldFZpZXdwb3J0IiwiZGV2aWNlU2NhbGVGYWN0b3IiLCJvdXRlckhUTUwiLCJjcmVhdGVTVkciLCJlbmNvZGluZyIsImNsaXAiLCJyYWNlIiwic2NyZWVuc2hvdCIsImNhcHR1cmVCZXlvbmRWaWV3cG9ydCIsImZ1bGxQYWdlIiwib3B0aW1pemVGb3JTcGVlZCIsInF1YWxpdHkiLCJvbWl0QmFja2dyb3VuZCIsIl9yZXNvbHZlIiwic2V0VGltZW91dCIsImNyZWF0ZUltYWdlIiwiZW11bGF0ZU1lZGlhVHlwZSIsInBkZiIsImNyZWF0ZVBERiIsInN0YXRzIiwicGVyZm9ybWVkRXhwb3J0cyIsImV4cG9ydEF0dGVtcHRzIiwiZXhwb3J0RnJvbVN2Z0F0dGVtcHRzIiwidGltZVNwZW50IiwiZHJvcHBlZEV4cG9ydHMiLCJzcGVudEF2ZXJhZ2UiLCJwb29sQ29uZmlnIiwiZmFjdG9yeSIsImNyZWF0ZSIsImlkIiwidXVpZCIsInN0YXJ0RGF0ZSIsImdldFRpbWUiLCJ3b3JrQ291bnQiLCJyYW5kb20iLCJ2YWxpZGF0ZSIsIndvcmtlckhhbmRsZSIsImNsb3NlIiwiaW5pdFBvb2wiLCJwdXBwZXRlZXJBcmdzIiwicHVwcGV0ZWVyT3B0aW9ucyIsImVuYWJsZWREZWJ1ZyIsImRlYnVnT3B0aW9ucyIsImxhdW5jaE9wdGlvbnMiLCJ1c2VyRGF0YURpciIsImhhbmRsZVNJR0lOVCIsImhhbmRsZVNJR1RFUk0iLCJoYW5kbGVTSUdIVVAiLCJ3YWl0Rm9ySW5pdGlhbFBhZ2UiLCJkZWZhdWx0Vmlld3BvcnQiLCJtYXhUcmllcyIsInRyeUNvdW50Iiwib3BlbiIsImxhdW5jaCIsImNyZWF0ZUJyb3dzZXIiLCJwYXJzZUludCIsIlBvb2wiLCJhY3F1aXJlVGltZW91dE1pbGxpcyIsImNyZWF0ZVRpbWVvdXRNaWxsaXMiLCJkZXN0cm95VGltZW91dE1pbGxpcyIsImlkbGVUaW1lb3V0TWlsbGlzIiwiY3JlYXRlUmV0cnlJbnRlcnZhbE1pbGxpcyIsInJlYXBJbnRlcnZhbE1pbGxpcyIsInByb3BhZ2F0ZUNyZWF0ZUVycm9yIiwiciIsImhhcmRSZXNldCIsImdvdG8iLCJjbGVhclBhZ2UiLCJldmVudElkIiwiaW5pdGlhbFJlc291cmNlcyIsImFjcXVpcmUiLCJwcm9taXNlIiwicmVsZWFzZSIsImtpbGxQb29sIiwid29ya2VyIiwidXNlZCIsImRlc3Ryb3llZCIsImNvbm5lY3RlZCIsImNsb3NlQnJvd3NlciIsInBvc3RXb3JrIiwiZ2V0UG9vbEluZm8iLCJhY3F1aXJlQ291bnRlciIsInBheWxvYWQiLCJyZXF1ZXN0SWQiLCJ3b3JrU3RhcnQiLCJleHBvcnRDb3VudGVyIiwicmVzdWx0IiwiZXhwb3J0VGltZSIsImdldFBvb2xJbmZvSlNPTiIsIm51bUZyZWUiLCJudW1Vc2VkIiwiYXZhaWxhYmxlIiwicGVuZGluZyIsIm51bVBlbmRpbmdBY3F1aXJlcyIsInBvb2wkMSIsInN0YXJ0RXhwb3J0Iiwic2V0dGluZ3MiLCJlbmRDYWxsYmFjayIsInN2ZyIsImluaXRFeHBvcnRTZXR0aW5ncyIsImV4cG9ydEFzU3RyaW5nIiwiaW5wdXQiLCJmb3JiaWRkZW4iLCJKU0RPTSIsIkRPTVB1cmlmeSIsInNhbml0aXplIiwiQUREX1RBR1MiLCJGT1JCSURfQVRUUiIsImRvU3RyYWlnaHRJbmplY3QiLCJkb0V4cG9ydCIsImZpbmRDaGFydFNpemUiLCJwcmVjaXNpb24iLCJtdWx0aXBsaWVyIiwicG93Iiwicm91bmROdW1iZXIiLCJzb3VyY2VIZWlnaHQiLCJzb3VyY2VXaWR0aCIsInBhcmFtIiwiY2hhcnRKc29uIiwiY3VzdG9tTG9naWNPcHRpb25zIiwiYWxsb3dDb2RlRXhlY3V0aW9uU2NvcGVkIiwib3B0aW9uc05hbWUiLCJzdHJpbmdUb0V4cG9ydCIsImNoYXJ0SlNPTiIsImludGVydmFsSWRzIiwiY2xlYXJBbGxJbnRlcnZhbHMiLCJjbGVhckludGVydmFsIiwibG9nRXJyb3JNaWRkbGV3YXJlIiwicmVxIiwibmV4dCIsInJldHVybkVycm9yTWlkZGxld2FyZSIsInN0Q29kZSIsInN0YXR1cyIsImpzb24iLCJyYXRlTGltaXQiLCJhcHAiLCJsaW1pdENvbmZpZyIsIm1zZyIsInJhdGVPcHRpb25zIiwibGltaXRlciIsIndpbmRvd01zIiwiZGVsYXlNcyIsImhhbmRsZXIiLCJyZXF1ZXN0IiwiZm9ybWF0Iiwic2VuZCIsImRlZmF1bHQiLCJza2lwIiwicXVlcnkiLCJhY2Nlc3NfdG9rZW4iLCJ1c2UiLCJIdHRwRXJyb3IiLCJzZXRTdGF0dXMiLCJ2U3dpdGNoUm91dGUiLCJwb3N0IiwiYWRtaW5Ub2tlbiIsInRva2VuIiwibmV3VmVyc2lvbiIsInBhcmFtcyIsInVwZGF0ZVZlcnNpb24iLCJyZXZlcnNlZE1pbWUiLCJwbmciLCJqcGVnIiwiZ2lmIiwicmVxdWVzdHNDb3VudGVyIiwiYmVmb3JlUmVxdWVzdCIsImFmdGVyUmVxdWVzdCIsImRvQ2FsbGJhY2tzIiwiY2FsbGJhY2tzIiwidW5pcXVlSWQiLCJjYWxsUmVzcG9uc2UiLCJleHBvcnRIYW5kbGVyIiwic3RvcENvdW50ZXIiLCJjb25uZWN0aW9uIiwicmVtb3RlQWRkcmVzcyIsImI2NCIsIm5vRG93bmxvYWQiLCJjb25uZWN0aW9uQWJvcnRlZCIsInNvY2tldCIsImhhZEVycm9ycyIsInRvTG93ZXJDYXNlIiwic3Vic3RyIiwicGF0dGVybiIsImlzUHJpdmF0ZVJhbmdlVXJsRm91bmQiLCJpbmZvIiwicmVtb3ZlQWxsTGlzdGVuZXJzIiwiZnJvbSIsImhlYWRlciIsImF0dGFjaG1lbnQiLCJmaWxlbmFtZSIsInBrZ0ZpbGUiLCJwYXRoZXIiLCJzZXJ2ZXJTdGFydFRpbWUiLCJzdWNjZXNzUmF0ZXMiLCJhZGRIZWFsdGhSb3V0ZXMiLCJzZXRJbnRlcnZhbCIsInN1Y2Nlc3NSYXRpbyIsIl8iLCJwZXJpb2QiLCJtb3ZpbmdBdmVyYWdlIiwicmVkdWNlIiwiYSIsImIiLCJib290VGltZSIsInVwdGltZSIsImZsb29yIiwiaGlnaGNoYXJ0c1ZlcnNpb24iLCJhdmVyYWdlUHJvY2Vzc2luZ1RpbWUiLCJmYWlsZWRFeHBvcnRzIiwic3VjZXNzUmF0aW8iLCJzdmdFeHBvcnRBdHRlbXB0cyIsImpzb25FeHBvcnRBdHRlbXB0cyIsImFjdGl2ZVNlcnZlcnMiLCJNYXAiLCJleHByZXNzIiwiZGlzYWJsZSIsImNvcnMiLCJfcmVxIiwic2V0IiwiYXR0YWNoU2VydmVyRXJyb3JIYW5kbGVycyIsInN0YXJ0U2VydmVyIiwic2VydmVyQ29uZmlnIiwidXBsb2FkTGltaXRCeXRlcyIsInN0b3JhZ2UiLCJtdWx0ZXIiLCJtZW1vcnlTdG9yYWdlIiwidXBsb2FkIiwibGltaXRzIiwiZmllbGRTaXplIiwibGltaXQiLCJ1cmxlbmNvZGVkIiwiZXh0ZW5kZWQiLCJub25lIiwiaHR0cFNlcnZlciIsImNyZWF0ZVNlcnZlciIsImxpc3RlbiIsImNlcnQiLCJmc1Byb21pc2VzIiwicmVhZEZpbGUiLCJwb3NpeCIsImh0dHBzU2VydmVyIiwiTmFOIiwic3RhdGljIiwiaGVhbHRoUm91dGUiLCJleHBvcnRSb3V0ZXMiLCJfcmVxdWVzdCIsInNlbmRGaWxlIiwiYWNjZXB0UmFuZ2VzIiwidWlSb3V0ZSIsImVycm9ySGFuZGxlciIsImNsb3NlU2VydmVycyIsImRlbGV0ZSIsImdldFNlcnZlcnMiLCJlbmFibGVSYXRlTGltaXRpbmciLCJnZXRFeHByZXNzIiwiZ2V0QXBwIiwibWlkZGxld2FyZXMiLCJzaHV0ZG93bkNsZWFuVXAiLCJleGl0Q29kZSIsImFsbFNldHRsZWQiLCJleGl0IiwiaW5kZXgiLCJpbml0RXhwb3J0IiwibG9nZ2luZ09wdGlvbnMiLCJpbml0TG9nZ2luZyIsImNvZGUiLCJzaW5nbGVFeHBvcnQiLCJiYXRjaEV4cG9ydCIsImJhdGNoRnVuY3Rpb25zIiwicGFpciIsImNvbmZpZ0luZGV4IiwiZmluZEluZGV4IiwiYXJnIiwiZmlsZU5hbWUiLCJsb2FkQ29uZmlnRmlsZSIsInNob3dVc2FnZSIsInByb3BlcnRpZXNDaGFpbiIsImFyZ3VtZW50VHlwZSIsInBhaXJBcmd1bWVudFZhbHVlIiwibWFwVG9OZXdDb25maWciLCJvbGRPcHRpb25zIiwibWFudWFsQ29uZmlnIiwiY29uZmlnRmlsZU5hbWUiLCJjb25maWdGaWxlIiwiY2hvaWNlIiwicHJvbXB0cyIsIm9uU3VibWl0IiwicCIsImNhdGVnb3JpZXMiLCJxdWVzdGlvbnNDb3VudGVyIiwiYWxsUXVlc3Rpb25zIiwic2VjdGlvbiIsInByb21wdCIsImFuc3dlciIsIm1vZHVsZSIsIndyaXRlRmlsZSIsInByaW50TG9nbyIsInBhY2thZ2VWZXJzaW9uIl0sIm1hcHBpbmdzIjoiK2NBZU8sTUFBTUEsRUFBZSxDQUMxQkMsS0FBTSxDQUFDLGFBQWMsa0JBQW1CLGlCQUN4Q0MsUUFBUyxDQUNQLFFBQ0EsTUFDQSxRQUNBLFlBQ0EsdUJBQ0EsZ0JBRUEsZUFDQSxRQUNBLE9BQ0EsYUFDQSxtQkFDQSxlQUNBLGNBQ0EsVUFDQSxVQUNBLGNBQ0EsV0FDQSxVQUNBLFlBQ0EsY0FDQSxZQUNBLHNCQUNBLFNBQ0EsU0FDQSxXQUNBLGFBQ0EsWUFDQSxlQUNBLHlCQUNBLFNBQ0EsZUFDQSxZQUNBLGtCQUNBLFNBQ0EsY0FDQSxtQkFDQSxlQUNBLGtCQUNBLGNBQ0EsZUFFQSxjQUNBLFdBQ0EsZUFDQSxXQUNBLFNBQ0EsT0FDQSxXQUNBLFlBQ0EsU0FDQSxxQkFDQSxhQUNBLFdBQ0EsV0FDQSxXQUNBLFdBQ0EsZUFDQSxVQUNBLGtCQUNBLG9CQUNBLGFBQ0EsVUFDQSxjQUNBLFlBQ0EsWUFFRkMsV0FBWSxDQUFDLGtCQUNiQyxPQUFRLENBQ04sd0VBQ0EsbUdBTVNDLEVBQWdCLENBQzNCQyxVQUFXLENBQ1RDLEtBQU0sQ0FDSkMsTUFBTyxDQUNMLG1DQUNBLGtCQUNBLDBDQUNBLDJCQUNBLGtD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 diff --git a/dist/index.esm.js b/dist/index.esm.js index 8f17193f..ded1e652 100644 --- a/dist/index.esm.js +++ b/dist/index.esm.js @@ -1,2 +1,2 @@ -import"colors";import{existsSync as e,mkdirSync as t,appendFile as o,readFileSync as r,promises as i,writeFileSync as s}from"fs";import n,{join as a,posix as l}from"path";import{HttpsProxyAgent as c}from"https-proxy-agent";import p from"prompts";import h from"dotenv";import{z as u}from"zod";import{fileURLToPath as d}from"url";import g from"http";import m from"https";import{Pool as f}from"tarn";import{v4 as v}from"uuid";import y from"puppeteer";import{JSDOM as b}from"jsdom";import w from"dompurify";import E from"cors";import T from"express";import S from"multer";import x from"express-rate-limit";const R={core:["highcharts","highcharts-more","highcharts-3d"],modules:["stock","map","gantt","exporting","parallel-coordinates","accessibility","boost-canvas","boost","data","data-tools","draggable-points","static-scale","broken-axis","heatmap","tilemap","tiledwebmap","timeline","treemap","treegraph","item-series","drilldown","histogram-bellcurve","bullet","funnel","funnel3d","geoheatmap","pyramid3d","networkgraph","overlapping-datalabels","pareto","pattern-fill","pictorial","price-indicator","sankey","arc-diagram","dependency-wheel","series-label","series-on-point","solid-gauge","sonification","streamgraph","sunburst","variable-pie","variwide","vector","venn","windbarb","wordcloud","xrange","no-data-to-display","drag-panes","debugger","dumbbell","lollipop","cylinder","organization","dotplot","marker-clusters","hollowcandlestick","heikinashi","flowmap","export-data","navigator","textpath"],indicators:["indicators-all"],custom:["https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.30.1/moment.min.js","https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.45/moment-timezone-with-data.min.js"]},_={puppeteer:{args:{value:["--allow-running-insecure-content","--ash-no-nudges","--autoplay-policy=user-gesture-required","--block-new-web-contents","--disable-accelerated-2d-canvas","--disable-background-networking","--disable-background-timer-throttling","--disable-backgrounding-occluded-windows","--disable-breakpad","--disable-checker-imaging","--disable-client-side-phishing-detection","--disable-component-extensions-with-background-pages","--disable-component-update","--disable-default-apps","--disable-dev-shm-usage","--disable-domain-reliability","--disable-extensions","--disable-features=CalculateNativeWinOcclusion,InterestFeedContentSuggestions,WebOTP","--disable-hang-monitor","--disable-ipc-flooding-protection","--disable-logging","--disable-notifications","--disable-offer-store-unmasked-wallet-cards","--disable-popup-blocking","--disable-print-preview","--disable-prompt-on-repost","--disable-renderer-backgrounding","--disable-search-engine-choice-screen","--disable-session-crashed-bubble","--disable-setuid-sandbox","--disable-site-isolation-trials","--disable-speech-api","--disable-sync","--enable-unsafe-webgpu","--hide-crash-restore-bubble","--hide-scrollbars","--metrics-recording-only","--mute-audio","--no-default-browser-check","--no-first-run","--no-pings","--pipe","--no-startup-window","--password-store=basic","--process-per-tab","--use-mock-keychain"],type:"string[]",description:"Arguments array to send to Puppeteer."},tempDir:{value:"./tmp/",type:"string",envLink:"PUPPETEER_TEMP_DIR",description:"The directory for Puppeteer to store temporary files."}},highcharts:{version:{value:"latest",type:"string",envLink:"HIGHCHARTS_VERSION",description:"The Highcharts version to be used."},cdnURL:{value:"https://code.highcharts.com/",type:"string",envLink:"HIGHCHARTS_CDN_URL",description:"The CDN URL for Highcharts scripts to be used."},coreScripts:{value:R.core,type:"string[]",envLink:"HIGHCHARTS_CORE_SCRIPTS",description:"The core Highcharts scripts to fetch."},moduleScripts:{value:R.modules,type:"string[]",envLink:"HIGHCHARTS_MODULE_SCRIPTS",description:"The modules of Highcharts to fetch."},indicatorScripts:{value:R.indicators,type:"string[]",envLink:"HIGHCHARTS_INDICATOR_SCRIPTS",description:"The indicators of Highcharts to fetch."},customScripts:{value:R.custom,type:"string[]",description:"Additional custom scripts or dependencies to fetch."},forceFetch:{value:!1,type:"boolean",envLink:"HIGHCHARTS_FORCE_FETCH",description:"The flag to determine whether to refetch all scripts after each server rerun."},cachePath:{value:".cache",type:"string",envLink:"HIGHCHARTS_CACHE_PATH",description:"The path to the cache directory. It is used to store the Highcharts scripts and custom scripts."}},export:{infile:{value:!1,type:"string",description:"The input file should include a name and a type (json or svg). It must be correctly formatted as a JSON or SVG file."},instr:{value:!1,type:"string",description:"Input, provided in the form of a stringified JSON or SVG file, will override the --infile option."},options:{value:!1,type:"string",description:"An alias for the --instr option."},outfile:{value:!1,type:"string",description:"The output filename along with a type (jpeg, png, pdf, or svg). This will ignore the --type flag."},type:{value:"png",type:"string",envLink:"EXPORT_TYPE",description:"The file export format. It can be jpeg, png, pdf, or svg."},constr:{value:"chart",type:"string",envLink:"EXPORT_CONSTR",description:"The constructor to use. Can be chart, stockChart, mapChart, or ganttChart."},defaultHeight:{value:400,type:"number",envLink:"EXPORT_DEFAULT_HEIGHT",description:"the default height of the exported chart. Used when no value is set."},defaultWidth:{value:600,type:"number",envLink:"EXPORT_DEFAULT_WIDTH",description:"The default width of the exported chart. Used when no value is set."},defaultScale:{value:1,type:"number",envLink:"EXPORT_DEFAULT_SCALE",description:"The default scale of the exported chart. Used when no value is set."},height:{value:!1,type:"number",description:"The height of the exported chart, overriding the option in the chart settings."},width:{value:!1,type:"number",description:"The width of the exported chart, overriding the option in the chart settings."},scale:{value:!1,type:"number",description:"The scale of the exported chart, overriding the option in the chart settings. Ranges between 0.1 and 5.0."},globalOptions:{value:!1,type:"string",description:"Either a stringified JSON or a filename containing options to be passed into the Highcharts.setOptions."},themeOptions:{value:!1,type:"string",description:"Either a stringified JSON or a filename containing theme options to be passed into the Highcharts.setOptions."},batch:{value:!1,type:"string",description:'Initiates a batch job with a string containing input/output pairs: "in=out;in=out;...".'},rasterizationTimeout:{value:1500,type:"number",envLink:"EXPORT_RASTERIZATION_TIMEOUT",description:"The duration in milliseconds to wait for rendering a webpage."}},customLogic:{allowCodeExecution:{value:!1,type:"boolean",envLink:"CUSTOM_LOGIC_ALLOW_CODE_EXECUTION",description:"Controls whether the execution of arbitrary code is allowed during the exporting process."},allowFileResources:{value:!1,type:"boolean",envLink:"CUSTOM_LOGIC_ALLOW_FILE_RESOURCES",description:"Controls the ability to inject resources from the filesystem. This setting has no effect when running as a server."},customCode:{value:!1,type:"string",description:"Custom code to execute before chart initialization. It can be a function, code wrapped within a function, or a filename with the .js extension."},callback:{value:!1,type:"string",description:"JavaScript code to run during construction. It can be a function or a filename with the .js extension."},resources:{value:!1,type:"string",description:"Additional resource in the form of a stringified JSON, which may contain files, js, and css sections."},loadConfig:{value:!1,type:"string",legacyName:"fromFile",description:"A file containing a pre-defined configuration to use."},createConfig:{value:!1,type:"string",description:"Enables setting options through a prompt and saving them in a provided config file."}},server:{maxUploadSize:{value:3,type:"number",envLink:"SERVER_MAX_UPLOAD_SIZE",description:"The maximum upload size, in MB, for the server."},enable:{value:!1,type:"boolean",envLink:"SERVER_ENABLE",cliName:"enableServer",description:"When set to true, the server starts on the local IP address 0.0.0.0."},host:{value:"0.0.0.0",type:"string",envLink:"SERVER_HOST",description:"The hostname of the server. Additionally, it starts a server on the provided hostname."},port:{value:7801,type:"number",envLink:"SERVER_PORT",description:"The server port when enabled."},benchmarking:{value:!1,type:"boolean",envLink:"SERVER_BENCHMARKING",cliName:"serverBenchmarking",description:"Indicates whether to display the duration, in milliseconds, of specific actions that occur on the server while serving a request."},proxy:{host:{value:!1,type:"string",envLink:"SERVER_PROXY_HOST",cliName:"proxyHost",description:"The host of the proxy server to use, if it exists."},port:{value:8080,type:"number",envLink:"SERVER_PROXY_PORT",cliName:"proxyPort",description:"The port of the proxy server to use, if it exists."},username:{value:!1,type:"string",envLink:"SERVER_PROXY_USERNAME",cliName:"proxyUsername",description:"The username for the proxy server, if it exists."},password:{value:!1,type:"string",envLink:"SERVER_PROXY_PASSWORD",cliName:"proxyPassword",description:"The password for the proxy server, if it exists."},timeout:{value:5e3,type:"number",envLink:"SERVER_PROXY_TIMEOUT",cliName:"proxyTimeout",description:"The timeout for the proxy server to use, if it exists."}},rateLimiting:{enable:{value:!1,type:"boolean",envLink:"SERVER_RATE_LIMITING_ENABLE",cliName:"enableRateLimiting",description:"Enables rate limiting for the server."},maxRequests:{value:10,type:"number",envLink:"SERVER_RATE_LIMITING_MAX_REQUESTS",legacyName:"rateLimit",description:"The maximum number of requests allowed in one minute."},window:{value:1,type:"number",envLink:"SERVER_RATE_LIMITING_WINDOW",description:"The time window, in minutes, for the rate limiting."},delay:{value:0,type:"number",envLink:"SERVER_RATE_LIMITING_DELAY",description:"The delay duration for each successive request before reaching the maximum limit."},trustProxy:{value:!1,type:"boolean",envLink:"SERVER_RATE_LIMITING_TRUST_PROXY",description:"Set this to true if the server is behind a load balancer."},skipKey:{value:!1,type:"string",envLink:"SERVER_RATE_LIMITING_SKIP_KEY",description:"Allows bypassing the rate limiter and should be provided with the skipToken argument."},skipToken:{value:!1,type:"string",envLink:"SERVER_RATE_LIMITING_SKIP_TOKEN",description:"Allows bypassing the rate limiter and should be provided with the skipKey argument."}},ssl:{enable:{value:!1,type:"boolean",envLink:"SERVER_SSL_ENABLE",cliName:"enableSsl",description:"Enables or disables the SSL protocol."},force:{value:!1,type:"boolean",envLink:"SERVER_SSL_FORCE",cliName:"sslForce",legacyName:"sslOnly",description:"When set to true, the server is forced to serve only over HTTPS."},port:{value:443,type:"number",envLink:"SERVER_SSL_PORT",cliName:"sslPort",description:"The port on which to run the SSL server."},certPath:{value:!1,type:"string",envLink:"SERVER_SSL_CERT_PATH",legacyName:"sslPath",description:"The path to the SSL certificate/key file."}}},pool:{minWorkers:{value:4,type:"number",envLink:"POOL_MIN_WORKERS",description:"The number of minimum and initial pool workers to spawn."},maxWorkers:{value:8,type:"number",envLink:"POOL_MAX_WORKERS",legacyName:"workers",description:"The number of maximum pool workers to spawn."},workLimit:{value:40,type:"number",envLink:"POOL_WORK_LIMIT",description:"The number of work pieces that can be performed before restarting the worker process."},acquireTimeout:{value:5e3,type:"number",envLink:"POOL_ACQUIRE_TIMEOUT",description:"The duration, in milliseconds, to wait for acquiring a resource."},createTimeout:{value:5e3,type:"number",envLink:"POOL_CREATE_TIMEOUT",description:"The duration, in milliseconds, to wait for creating a resource."},destroyTimeout:{value:5e3,type:"number",envLink:"POOL_DESTROY_TIMEOUT",description:"The duration, in milliseconds, to wait for destroying a resource."},idleTimeout:{value:3e4,type:"number",envLink:"POOL_IDLE_TIMEOUT",description:"The duration, in milliseconds, after which an idle resource is destroyed."},createRetryInterval:{value:200,type:"number",envLink:"POOL_CREATE_RETRY_INTERVAL",description:"The duration, in milliseconds, to wait before retrying the create process in case of a failure."},reaperInterval:{value:1e3,type:"number",envLink:"POOL_REAPER_INTERVAL",description:"The duration, in milliseconds, after which the check for idle resources to destroy is triggered."},benchmarking:{value:!1,type:"boolean",envLink:"POOL_BENCHMARKING",cliName:"poolBenchmarking",description:"Indicate whether to show statistics for the pool of resources or not."}},logging:{level:{value:4,type:"number",envLink:"LOGGING_LEVEL",cliName:"logLevel",description:"The logging level to be used."},file:{value:"highcharts-export-server.log",type:"string",envLink:"LOGGING_FILE",cliName:"logFile",description:"The name of a log file. The `logToFile` and `logDest` options also need to be set to enable file logging."},dest:{value:"log/",type:"string",envLink:"LOGGING_DEST",cliName:"logDest",description:"The path to store log files. The `logToFile` option also needs to be set to enable file logging."},toConsole:{value:!0,type:"boolean",envLink:"LOGGING_TO_CONSOLE",cliName:"logToConsole",description:"Enables or disables showing logs in the console."},toFile:{value:!0,type:"boolean",envLink:"LOGGING_TO_FILE",cliName:"logToFile",description:"Enables or disables creation of the log directory and saving the log into a .log file."}},ui:{enable:{value:!1,type:"boolean",envLink:"UI_ENABLE",cliName:"enableUi",description:"Enables or disables the user interface (UI) for the export server."},route:{value:"/",type:"string",envLink:"UI_ROUTE",cliName:"uiRoute",description:"The endpoint route to which the user interface (UI) should be attached."}},other:{nodeEnv:{value:"production",type:"string",envLink:"OTHER_NODE_ENV",description:"The type of Node.js environment."},listenToProcessExits:{value:!0,type:"boolean",envLink:"OTHER_LISTEN_TO_PROCESS_EXITS",description:"Decides whether or not to attach process.exit handlers."},noLogo:{value:!1,type:"boolean",envLink:"OTHER_NO_LOGO",description:"Skip printing the logo on a startup. Will be replaced by a simple text."},hardResetPage:{value:!1,type:"boolean",envLink:"OTHER_HARD_RESET_PAGE",description:"Decides if the page content should be reset entirely."},browserShellMode:{value:!0,type:"boolean",envLink:"OTHER_BROWSER_SHELL_MODE",description:"Decides if the browser runs in the shell mode."}},debug:{enable:{value:!1,type:"boolean",envLink:"DEBUG_ENABLE",cliName:"enableDebug",description:"Enables or disables debug mode for the underlying browser."},headless:{value:!0,type:"boolean",envLink:"DEBUG_HEADLESS",description:"Controls the mode in which the browser is launched when in the debug mode."},devtools:{value:!1,type:"boolean",envLink:"DEBUG_DEVTOOLS",description:"Decides whether to enable DevTools when the browser is in a headful state."},listenToConsole:{value:!1,type:"boolean",envLink:"DEBUG_LISTEN_TO_CONSOLE",description:"Decides whether to enable a listener for console messages sent from the browser."},dumpio:{value:!1,type:"boolean",envLink:"DEBUG_DUMPIO",description:"Redirects browser process stdout and stderr to process.stdout and process.stderr."},slowMo:{value:0,type:"number",envLink:"DEBUG_SLOW_MO",description:"Slows down Puppeteer operations by the specified number of milliseconds."},debuggingPort:{value:9222,type:"number",envLink:"DEBUG_DEBUGGING_PORT",description:"Specifies the debugging port."}}},O={puppeteer:[{type:"list",name:"args",message:"Puppeteer arguments",initial:_.puppeteer.args.value.join(","),separator:","}],highcharts:[{type:"text",name:"version",message:"Highcharts version",initial:_.highcharts.version.value},{type:"text",name:"cdnURL",message:"The URL of CDN",initial:_.highcharts.cdnURL.value},{type:"multiselect",name:"coreScripts",message:"Available core scripts",instructions:"Space: Select specific, A: Select all, Enter: Confirm.",choices:_.highcharts.coreScripts.value},{type:"multiselect",name:"moduleScripts",message:"Available module scripts",instructions:"Space: Select specific, A: Select all, Enter: Confirm.",choices:_.highcharts.moduleScripts.value},{type:"multiselect",name:"indicatorScripts",message:"Available indicator scripts",instructions:"Space: Select specific, A: Select all, Enter: Confirm.",choices:_.highcharts.indicatorScripts.value},{type:"list",name:"customScripts",message:"Custom scripts",initial:_.highcharts.customScripts.value.join(","),separator:","},{type:"toggle",name:"forceFetch",message:"Force re-fetch the scripts",initial:_.highcharts.forceFetch.value},{type:"text",name:"cachePath",message:"The path to the cache directory",initial:_.highcharts.cachePath.value}],export:[{type:"select",name:"type",message:"The default export file type",hint:`Default: ${_.export.type.value}`,initial:0,choices:["png","jpeg","pdf","svg"]},{type:"select",name:"constr",message:"The default constructor for Highcharts",hint:`Default: ${_.export.constr.value}`,initial:0,choices:["chart","stockChart","mapChart","ganttChart"]},{type:"number",name:"defaultHeight",message:"The default fallback height of the exported chart",initial:_.export.defaultHeight.value},{type:"number",name:"defaultWidth",message:"The default fallback width of the exported chart",initial:_.export.defaultWidth.value},{type:"number",name:"defaultScale",message:"The default fallback scale of the exported chart",initial:_.export.defaultScale.value,min:.1,max:5},{type:"number",name:"rasterizationTimeout",message:"The rendering webpage timeout in milliseconds",initial:_.export.rasterizationTimeout.value}],customLogic:[{type:"toggle",name:"allowCodeExecution",message:"Enable execution of custom code",initial:_.customLogic.allowCodeExecution.value},{type:"toggle",name:"allowFileResources",message:"Enable file resources",initial:_.customLogic.allowFileResources.value}],server:[{type:"toggle",name:"enable",message:"Starts the server on 0.0.0.0",initial:_.server.enable.value},{type:"text",name:"host",message:"Server hostname",initial:_.server.host.value},{type:"number",name:"port",message:"Server port",initial:_.server.port.value},{type:"toggle",name:"benchmarking",message:"Enable server benchmarking",initial:_.server.benchmarking.value},{type:"text",name:"proxy.host",message:"The host of the proxy server to use",initial:_.server.proxy.host.value},{type:"number",name:"proxy.port",message:"The port of the proxy server to use",initial:_.server.proxy.port.value},{type:"number",name:"proxy.timeout",message:"The timeout for the proxy server to use",initial:_.server.proxy.timeout.value},{type:"toggle",name:"rateLimiting.enable",message:"Enable rate limiting",initial:_.server.rateLimiting.enable.value},{type:"number",name:"rateLimiting.maxRequests",message:"The maximum requests allowed per minute",initial:_.server.rateLimiting.maxRequests.value},{type:"number",name:"rateLimiting.window",message:"The rate-limiting time window in minutes",initial:_.server.rateLimiting.window.value},{type:"number",name:"rateLimiting.delay",message:"The delay for each successive request before reaching the maximum",initial:_.server.rateLimiting.delay.value},{type:"toggle",name:"rateLimiting.trustProxy",message:"Set to true if behind a load balancer",initial:_.server.rateLimiting.trustProxy.value},{type:"text",name:"rateLimiting.skipKey",message:"Allows bypassing the rate limiter when provided with the skipToken argument",initial:_.server.rateLimiting.skipKey.value},{type:"text",name:"rateLimiting.skipToken",message:"Allows bypassing the rate limiter when provided with the skipKey argument",initial:_.server.rateLimiting.skipToken.value},{type:"toggle",name:"ssl.enable",message:"Enable SSL protocol",initial:_.server.ssl.enable.value},{type:"toggle",name:"ssl.force",message:"Force serving only over HTTPS",initial:_.server.ssl.force.value},{type:"number",name:"ssl.port",message:"SSL server port",initial:_.server.ssl.port.value},{type:"text",name:"ssl.certPath",message:"The path to find the SSL certificate/key",initial:_.server.ssl.certPath.value}],pool:[{type:"number",name:"minWorkers",message:"The initial number of workers to spawn",initial:_.pool.minWorkers.value},{type:"number",name:"maxWorkers",message:"The maximum number of workers to spawn",initial:_.pool.maxWorkers.value},{type:"number",name:"workLimit",message:"The pieces of work that can be performed before restarting a Puppeteer process",initial:_.pool.workLimit.value},{type:"number",name:"acquireTimeout",message:"The number of milliseconds to wait for acquiring a resource",initial:_.pool.acquireTimeout.value},{type:"number",name:"createTimeout",message:"The number of milliseconds to wait for creating a resource",initial:_.pool.createTimeout.value},{type:"number",name:"destroyTimeout",message:"The number of milliseconds to wait for destroying a resource",initial:_.pool.destroyTimeout.value},{type:"number",name:"idleTimeout",message:"The number of milliseconds after an idle resource is destroyed",initial:_.pool.idleTimeout.value},{type:"number",name:"createRetryInterval",message:"The retry interval in milliseconds after a create process fails",initial:_.pool.createRetryInterval.value},{type:"number",name:"reaperInterval",message:"The reaper interval in milliseconds after triggering the check for idle resources to destroy",initial:_.pool.reaperInterval.value},{type:"toggle",name:"benchmarking",message:"Enable benchmarking for a resource pool",initial:_.pool.benchmarking.value}],logging:[{type:"number",name:"level",message:"The log level (0: silent, 1: error, 2: warning, 3: notice, 4: verbose, 5: benchmark)",initial:_.logging.level.value,round:0,min:0,max:5},{type:"text",name:"file",message:"A log file name. Set with --toFile and --logDest to enable file logging",initial:_.logging.file.value},{type:"text",name:"dest",message:"The path to a log file when the file logging is enabled",initial:_.logging.dest.value},{type:"toggle",name:"toConsole",message:"Enable logging to the console",initial:_.logging.toConsole.value},{type:"toggle",name:"toFile",message:"Enables logging to a file",initial:_.logging.toFile.value}],ui:[{type:"toggle",name:"enable",message:"Enable UI for the export server",initial:_.ui.enable.value},{type:"text",name:"route",message:"A route to attach the UI",initial:_.ui.route.value}],other:[{type:"text",name:"nodeEnv",message:"The type of Node.js environment",initial:_.other.nodeEnv.value},{type:"toggle",name:"listenToProcessExits",message:"Set to false to skip attaching process.exit handlers",initial:_.other.listenToProcessExits.value},{type:"toggle",name:"noLogo",message:"Skip printing the logo on startup. Replaced by simple text",initial:_.other.noLogo.value},{type:"toggle",name:"hardResetPage",message:"Decides if the page content should be reset entirely",initial:_.other.hardResetPage.value},{type:"toggle",name:"browserShellMode",message:"Decides if the browser runs in the shell mode",initial:_.other.browserShellMode.value}],debug:[{type:"toggle",name:"enable",message:"Enables debug mode for the browser instance",initial:_.debug.enable.value},{type:"toggle",name:"headless",message:"The mode setting for the browser",initial:_.debug.headless.value},{type:"toggle",name:"devtools",message:"The DevTools for the headful browser",initial:_.debug.devtools.value},{type:"toggle",name:"listenToConsole",message:"The event listener for console messages from the browser",initial:_.debug.listenToConsole.value},{type:"toggle",name:"dumpio",message:"Redirects the browser stdout and stderr to NodeJS process",initial:_.debug.dumpio.value},{type:"number",name:"slowMo",message:"Puppeteer operations slow down in milliseconds",initial:_.debug.slowMo.value},{type:"number",name:"debuggingPort",message:"The port number for debugging",initial:_.debug.debuggingPort.value}]},L=["options","globalOptions","themeOptions","resources","payload"],k={},I=(e,t="")=>{Object.keys(e).forEach((o=>{if(!["puppeteer","highcharts"].includes(o)){const r=e[o];void 0===r.value?I(r,`${t}.${o}`):(k[r.cliName||o]=`${t}.${o}`.substring(1),void 0!==r.legacyName&&(k[r.legacyName]=`${t}.${o}`.substring(1)))}}))};I(_),h.config();const C=e=>u.string().transform((t=>t.split(",").map((e=>e.trim())).filter((t=>e.includes(t))))).transform((e=>e.length?e:void 0)),N=()=>u.enum(["true","false",""]).transform((e=>""!==e?"true"===e:void 0)),A=e=>u.enum([...e,""]).transform((e=>""!==e?e:void 0)),P=()=>u.string().trim().refine((e=>!["false","undefined","null","NaN"].includes(e)||""===e),(e=>({message:`The string contains forbidden values, received '${e}'`}))).transform((e=>""!==e?e:void 0)),$=()=>u.string().trim().refine((e=>/^(\.\/|\.\.\/|\/|[a-zA-Z]:\\|[a-zA-Z]:\/)?((?:[\w-]+)[\\/]?)+$/.test(e)),{},{message:"The string is an invalid path directory string."}),H=()=>u.string().trim().refine((e=>""===e||!isNaN(parseFloat(e))&&parseFloat(e)>0),(e=>({message:`The value must be numeric and positive, received '${e}'`}))).transform((e=>""!==e?parseFloat(e):void 0)),D=()=>u.string().trim().refine((e=>""===e||!isNaN(parseFloat(e))&&parseFloat(e)>=0),(e=>({message:`The value must be numeric and non-negative, received '${e}'`}))).transform((e=>""!==e?parseFloat(e):void 0)),G=u.object({PUPPETEER_TEMP_DIR:$(),HIGHCHARTS_VERSION:u.string().trim().refine((e=>/^(latest|\d+(\.\d+){0,2})$/.test(e)||""===e),(e=>({message:`HIGHCHARTS_VERSION must be 'latest', a major version, or in the form XX.YY.ZZ, received '${e}'`}))).transform((e=>""!==e?e:void 0)),HIGHCHARTS_CDN_URL:u.string().trim().refine((e=>e.startsWith("https://")||e.startsWith("http://")||""===e),(e=>({message:`Invalid value for HIGHCHARTS_CDN_URL. It should start with http:// or https://, received '${e}'`}))).transform((e=>""!==e?e:void 0)),HIGHCHARTS_CORE_SCRIPTS:C(R.core),HIGHCHARTS_MODULE_SCRIPTS:C(R.modules),HIGHCHARTS_INDICATOR_SCRIPTS:C(R.indicators),HIGHCHARTS_FORCE_FETCH:N(),HIGHCHARTS_CACHE_PATH:P(),HIGHCHARTS_ADMIN_TOKEN:P(),EXPORT_TYPE:A(["jpeg","png","pdf","svg"]),EXPORT_CONSTR:A(["chart","stockChart","mapChart","ganttChart"]),EXPORT_DEFAULT_HEIGHT:H(),EXPORT_DEFAULT_WIDTH:H(),EXPORT_DEFAULT_SCALE:H(),EXPORT_RASTERIZATION_TIMEOUT:D(),CUSTOM_LOGIC_ALLOW_CODE_EXECUTION:N(),CUSTOM_LOGIC_ALLOW_FILE_RESOURCES:N(),SERVER_ENABLE:N(),SERVER_HOST:P(),SERVER_PORT:H(),SERVER_MAX_UPLOAD_SIZE:H(),SERVER_BENCHMARKING:N(),SERVER_PROXY_HOST:P(),SERVER_PROXY_PORT:H(),SERVER_PROXY_USERNAME:P(),SERVER_PROXY_PASSWORD:P(),SERVER_PROXY_TIMEOUT:D(),SERVER_RATE_LIMITING_ENABLE:N(),SERVER_RATE_LIMITING_MAX_REQUESTS:D(),SERVER_RATE_LIMITING_WINDOW:D(),SERVER_RATE_LIMITING_DELAY:D(),SERVER_RATE_LIMITING_TRUST_PROXY:N(),SERVER_RATE_LIMITING_SKIP_KEY:P(),SERVER_RATE_LIMITING_SKIP_TOKEN:P(),SERVER_SSL_ENABLE:N(),SERVER_SSL_FORCE:N(),SERVER_SSL_PORT:H(),SERVER_SSL_CERT_PATH:P(),POOL_MIN_WORKERS:D(),POOL_MAX_WORKERS:D(),POOL_WORK_LIMIT:H(),POOL_ACQUIRE_TIMEOUT:D(),POOL_CREATE_TIMEOUT:D(),POOL_DESTROY_TIMEOUT:D(),POOL_IDLE_TIMEOUT:D(),POOL_CREATE_RETRY_INTERVAL:D(),POOL_REAPER_INTERVAL:D(),POOL_BENCHMARKING:N(),LOGGING_LEVEL:u.string().trim().refine((e=>""===e||!isNaN(parseFloat(e))&&parseFloat(e)>=0&&parseFloat(e)<=5),(e=>({message:`Invalid value for LOGGING_LEVEL. We only accept values from 0 to 5 as logging levels, received '${e}'`}))).transform((e=>""!==e?parseFloat(e):void 0)),LOGGING_FILE:P(),LOGGING_DEST:P(),LOGGING_TO_CONSOLE:N(),LOGGING_TO_FILE:N(),UI_ENABLE:N(),UI_ROUTE:P(),OTHER_NODE_ENV:A(["development","production","test"]),OTHER_LISTEN_TO_PROCESS_EXITS:N(),OTHER_NO_LOGO:N(),OTHER_HARD_RESET_PAGE:N(),OTHER_BROWSER_SHELL_MODE:N(),OTHER_ALLOW_XLINK:N(),DEBUG_ENABLE:N(),DEBUG_HEADLESS:N(),DEBUG_DEVTOOLS:N(),DEBUG_LISTEN_TO_CONSOLE:N(),DEBUG_DUMPIO:N(),DEBUG_SLOW_MO:D(),DEBUG_DEBUGGING_PORT:H()}).partial().parse(process.env),U=["red","yellow","blue","gray","green"];let M={toConsole:!0,toFile:!1,pathCreated:!1,levelsDesc:[{title:"error",color:U[0]},{title:"warning",color:U[1]},{title:"notice",color:U[2]},{title:"verbose",color:U[3]},{title:"benchmark",color:U[4]}],listeners:[]};const j=(r,i)=>{M.pathCreated||(!e(M.dest)&&t(M.dest),M.pathCreated=!0),o(`${M.dest}${M.file}`,[i].concat(r).join(" ")+"\n",(e=>{e&&(console.log(`[logger] Unable to write to log file: ${e}`),M.toFile=!1)}))},F=(...e)=>{const[t,...o]=e,{levelsDesc:r,level:i}=M;if(5!==t&&(0===t||t>i||i>r.length))return;const s=`${(new Date).toString().split("(")[0].trim()} [${r[t-1].title}] -`;M.listeners.forEach((e=>{e(s,o.join(" "))})),M.toConsole&&console.log.apply(void 0,[s.toString()[M.levelsDesc[t-1].color]].concat(o)),M.toFile&&j(o,s)},V=(e,t,o)=>{const r=o||t.message,{level:i,levelsDesc:s}=M;if(0===e||e>i||i>s.length)return;const n=`${(new Date).toString().split("(")[0].trim()} [${s[e-1].title}] -`,a=t.message!==t.stackMessage||void 0===t.stackMessage?t.stack:t.stack.split("\n").slice(1).join("\n"),l=[r,"\n",a];M.toConsole&&console.log.apply(void 0,[n.toString()[M.levelsDesc[e-1].color]].concat([r[U[e-1]],"\n",a])),M.listeners.forEach((e=>{e(n,l.join(" "))})),M.toFile&&j(l,n)},W=e=>{e>=0&&e<=M.levelsDesc.length&&(M.level=e)},q=(e,t)=>{if(M={...M,dest:e||M.dest,file:t||M.file,toFile:!0},0===M.dest.length)return F(1,"[logger] File logging initialization: no path supplied.");M.dest.endsWith("/")||(M.dest+="/")},B=d(new URL("../.",import.meta.url)),X=(e,t)=>{const o=["png","jpeg","pdf","svg"];if(t){const r=t.split(".").pop();"jpg"===r?e="jpeg":o.includes(r)&&e!==r&&(e=r)}return{"image/png":"png","image/jpeg":"jpeg","application/pdf":"pdf","image/svg+xml":"svg"}[e]||o.find((t=>t===e))||"png"},K=(e=!1,t)=>{const o=["js","css","files"];let i=e,s=!1;if(t&&e.endsWith(".json"))try{i=z(r(e,"utf8"))}catch(e){return V(2,e,"[cli] No resources found.")}else i=z(e),i&&!t&&delete i.files;for(const e in i)o.includes(e)?s||(s=!0):delete i[e];return s?(i.files&&(i.files=i.files.map((e=>e.trim())),(!i.files||i.files.length<=0)&&delete i.files),i):F(3,"[cli] No resources found.")};function z(e,t){try{const o=JSON.parse("string"!=typeof e?JSON.stringify(e):e);return"string"!=typeof o&&t?JSON.stringify(o):o}catch{return!1}}const J=e=>{if(null===e||"object"!=typeof e)return e;const t=Array.isArray(e)?[]:{};for(const o in e)Object.prototype.hasOwnProperty.call(e,o)&&(t[o]=J(e[o]));return t},Y=(e,t)=>JSON.stringify(e,((e,o)=>("string"==typeof o&&((o=o.trim()).startsWith("function(")||o.startsWith("function ("))&&o.endsWith("}")&&(o=t?`EXP_FUN${(o+"").replaceAll(/\n|\t|\r/g," ")}EXP_FUN`:void 0),"function"==typeof o?`EXP_FUN${(o+"").replaceAll(/\n|\t|\r/g," ")}EXP_FUN`:o))).replaceAll(/"EXP_FUN|EXP_FUN"/g,"");function Z(){console.log("\nUsage of CLI arguments:".bold,"\n------",`\nFor more detailed information, visit the readme at: ${"https://github.com/highcharts/node-export-server#readme".bold.yellow}.`);const e=t=>{for(const[o,r]of Object.entries(t))if(Object.prototype.hasOwnProperty.call(r,"value")){let e=` --${r.cliName||o} ${("<"+r.type+">").green} `;if(e.length<48)for(let t=e.length;t<48;t++)e+=".";console.log(e,r.description,`[Default: ${r.value.toString().bold}]`.blue)}else e(r)};Object.keys(_).forEach((t=>{["puppeteer","highcharts"].includes(t)||(console.log(`\n${t.toUpperCase()}`.red),e(_[t]))})),console.log("\n")}const Q=e=>!["false","undefined","null","NaN","0",""].includes(e)&&!!e,ee=(e,t)=>{if(e&&"string"==typeof e)return(e=e.trim()).endsWith(".js")?!!t&&ee(r(e,"utf8")):e.startsWith("function()")||e.startsWith("function ()")||e.startsWith("()=>")||e.startsWith("() =>")?`(${e})()`:e.replace(/;$/,"")},te=()=>{const e=process.hrtime.bigint();return()=>Number(process.hrtime.bigint()-e)/1e6};let oe={};const re=()=>oe,ie=(e,t,o=[])=>{const r=J(e);for(const[e,s]of Object.entries(t))r[e]="object"!=typeof(i=s)||Array.isArray(i)||null===i||o.includes(e)||void 0===r[e]?void 0!==s?s:r[e]:ie(r[e],s,o);var i;return r};function se(e,t={},o=""){Object.keys(e).forEach((r=>{const i=e[r],s=t&&t[r];void 0===i.value?se(i,s,`${o}.${r}`):(void 0!==s&&(i.value=s),i.envLink in G&&void 0!==G[i.envLink]&&(i.value=G[i.envLink]))}))}function ne(e){let t={};for(const[o,r]of Object.entries(e))t[o]=Object.prototype.hasOwnProperty.call(r,"value")?r.value:ne(r);return t}function ae(e,t,o){for(;t.length>1;){const r=t.shift();return Object.prototype.hasOwnProperty.call(e,r)||(e[r]={}),e[r]=ae(Object.assign({},e[r]),t,o),e}return e[t[0]]=o,e}async function le(e,t={}){return new Promise(((o,r)=>{const i=(e=>e.startsWith("https")?m:g)(e);i.get(e,Object.assign({headers:{"User-Agent":"highcharts/export",Referer:"highcharts.export"}},t||{}),(e=>{let t="";e.on("data",(e=>{t+=e})),e.on("end",(()=>{t||r("Nothing was fetched from the URL."),e.text=t,o(e)}))})).on("error",(e=>{r(e)}))}))}class ce extends Error{constructor(e){super(),this.message=e,this.stackMessage=e}setError(e){return this.error=e,e.name&&(this.name=e.name),e.statusCode&&(this.statusCode=e.statusCode),e.stack&&(this.stackMessage=e.message,this.stack=e.stack),this}}const pe={cdnURL:"https://code.highcharts.com/",activeManifest:{},sources:"",hcVersion:""},he=e=>e.sources.substring(0,e.sources.indexOf("*/")).replace("/*","").replace("*/","").replace(/\n/g,"").trim(),ue=async(e,t,o,r=!1)=>{e.endsWith(".js")&&(e=e.substring(0,e.length-3)),F(4,`[cache] Fetching script - ${e}.js`);const i=await le(`${e}.js`,t);if(200===i.statusCode&&"string"==typeof i.text){if(o){o[e.replace(/(.*)\/|(.*)modules\/|stock\/(.*)indicators\/|maps\/(.*)modules\//gi,"")]=1}return i.text}if(r)throw new ce(`Could not fetch the ${e}.js. The script might not exist in the requested version (status code: ${i.statusCode}).`).setError(i);return F(2,`[cache] Could not fetch the ${e}.js. The script might not exist in the requested version.`),""},de=async(e,t,o)=>{const r=e.version,i="latest"!==r&&r?`${r}/`:"",n=e.cdnURL||pe.cdnURL;F(3,`[cache] Updating cache version to Highcharts: ${i||"latest"}.`);const a={};try{return pe.sources=await(async(e,t,o,r,i)=>{let s;const{host:n,port:a,username:l,password:p}=r;if(n&&a)try{s=new c({host:n,port:a,...l&&p?{username:l,password:p}:{}})}catch(e){throw new ce("[cache] Could not create a Proxy Agent.").setError(e)}const h=s?{agent:s,timeout:G.SERVER_PROXY_TIMEOUT}:{},u=[...e.map((e=>ue(`${e}`,h,i,!0))),...t.map((e=>ue(`${e}`,h,i))),...o.map((e=>ue(`${e}`,h)))];return(await Promise.all(u)).join(";\n")})([...e.coreScripts.map((e=>`${n}${i}${e}`))],[...e.moduleScripts.map((e=>"map"===e?`${n}maps/${i}modules/${e}`:`${n}${i}modules/${e}`)),...e.indicatorScripts.map((e=>`${n}stock/${i}indicators/${e}`))],e.customScripts,t,a),pe.hcVersion=he(pe),s(o,pe.sources),a}catch(e){throw new ce("[cache] Unable to update the local Highcharts cache.").setError(e)}},ge=async o=>{const{highcharts:i,server:n}=o,l=a(B,i.cachePath);let c;const p=a(l,"manifest.json"),h=a(l,"sources.js");if(!e(l)&&t(l),!e(p)||i.forceFetch)F(3,"[cache] Fetching and caching Highcharts dependencies."),c=await de(i,n.proxy,h);else{let e=!1;const t=JSON.parse(r(p));if(t.modules&&Array.isArray(t.modules)){const e={};t.modules.forEach((t=>e[t]=1)),t.modules=e}const{coreScripts:o,moduleScripts:s,indicatorScripts:a}=i,l=o.length+s.length+a.length;t.version!==i.version?(F(2,"[cache] A Highcharts version mismatch in the cache, need to re-fetch."),e=!0):Object.keys(t.modules||{}).length!==l?(F(2,"[cache] The cache and the requested modules do not match, need to re-fetch."),e=!0):e=(s||[]).some((e=>{if(!t.modules[e])return F(2,`[cache] The ${e} is missing in the cache, need to re-fetch.`),!0})),e?c=await de(i,n.proxy,h):(F(3,"[cache] Dependency cache is up to date, proceeding."),pe.sources=r(h,"utf8"),c=t.modules,pe.hcVersion=he(pe))}await(async(e,t)=>{const o={version:e.version,modules:t||{}};pe.activeManifest=o,F(3,"[cache] Writing a new manifest.");try{s(a(B,e.cachePath,"manifest.json"),JSON.stringify(o),"utf8")}catch(e){throw new ce("[cache] Error writing the cache manifest.").setError(e)}})(i,c)},me=()=>a(B,re().highcharts.cachePath),fe=()=>pe.hcVersion;function ve(){Highcharts.animObject=function(){return{duration:0}}}async function ye(e,t,o){window._displayErrors=o;const{getOptions:r,merge:i,setOptions:s,wrap:n}=Highcharts;Highcharts.setOptionsObj=i(!1,{},r());const a={animation:!1};t.export.strInj&&(a.height=e.chart.height,a.width=e.chart.width),window.isRenderComplete=!1,n(Highcharts.Chart.prototype,"init",(function(e,t,o){((t=i(t,{exporting:{enabled:!1},plotOptions:{series:{label:{enabled:!1}}},tooltip:{}})).series||[]).forEach((function(e){e.animation=!1})),window.onHighchartsRender||(window.onHighchartsRender=Highcharts.addEvent(this,"render",(()=>{window.isRenderComplete=!0}))),e.apply(this,[t,o])})),n(Highcharts.Series.prototype,"init",(function(e,t,o){e.apply(this,[t,o])}));const l=t.export.strInj?new Function(`return ${t.export.strInj}`)():e;t.customLogic.customCode&&new Function("options",t.customLogic.customCode)(l);const c=i(!1,JSON.parse(t.export.themeOptions),l,{chart:a}),p=t.customLogic.callback?new Function(`return ${t.customLogic.callback}`)():void 0,h=JSON.parse(t.export.globalOptions);h&&s(h);let u=t.export.constr||"chart";u=void 0!==Highcharts[u]?u:"chart",Highcharts[u]("container",c,p);const d=r();for(const e in d)"function"!=typeof d[e]&&delete d[e];s(Highcharts.setOptionsObj),Highcharts.setOptionsObj={}}const be=r(B+"/templates/template.html","utf8");let we;async function Ee(){if(!we)return!1;const e=await we.newPage();return await e.setCacheEnabled(!1),await Se(e),function(e){const{debug:t}=re();t.enable&&t.listenToConsole&&e.on("console",(e=>{console.log(`[debug] ${e.text()}`)}));e.on("pageerror",(async t=>{e.isClosed()||await e.$eval("#container",((e,t)=>{window._displayErrors&&(e.innerHTML=t)}),`

Chart input data error:

${t.toString()}`)}))}(e),e}async function Te(e,t){try{for(const e of t)await e.dispose();await e.evaluate((()=>{if("undefined"!=typeof Highcharts){const e=Highcharts.charts;if(Array.isArray(e)&&e.length)for(const t of e)t&&t.destroy(),Highcharts.charts.shift()}const[...e]=document.getElementsByTagName("script"),[,...t]=document.getElementsByTagName("style"),[...o]=document.getElementsByTagName("link");for(const r of[...e,...t,...o])r.remove()}))}catch(e){V(2,e,"[browser] Could not clear page's resources.")}}async function Se(e){await e.setContent(be,{waitUntil:"domcontentloaded"}),await e.addScriptTag({path:`${me()}/sources.js`}),await e.evaluate(ve)}const xe=async(e,t,o,r)=>{o.export.instr=null,o.export.infile=null;const i=Buffer.byteLength(o.export?.strInj?o.export?.strInj:JSON.stringify(t),"utf-8");if(F(4,`[export] The current total size of data passed to a page is around ${(i/1048576).toFixed(2)} MB`),i>=104857600)throw new ce("[export] The data passed to a page exceeded 100MB.");return e.evaluate(ye,t,o,r)};var Re=async(e,t,o)=>{let i=[];try{F(4,"[export] Determining export path.");const s=o.export,a=s?.options?.chart?.displayErrors&&pe.activeManifest.modules.debugger;let l;if(t.indexOf&&(t.indexOf("=0||t.indexOf("=0)){if(F(4,"[export] Treating as SVG."),"svg"===s.type)return t;l=!0,await e.setContent((e=>`\n\n\n \n \n Highcharts Export\n \n \n \n
\n ${e}\n
\n \n\n\n`)(t),{waitUntil:"domcontentloaded"})}else F(4,"[export] Treating as config."),s.strInj?await xe(e,{chart:{height:s.height,width:s.width}},o,a):(t.chart.height=s.height,t.chart.width=s.width,await xe(e,t,o,a));i=await async function(e,t){const o=[],i=t.customLogic.resources;if(i){const s=[];if(i.js&&s.push({content:i.js}),i.files)for(const e of i.files){const t=!e.startsWith("http");s.push(t?{content:r(e,"utf8")}:{url:e})}for(const t of s)try{o.push(await e.addScriptTag(t))}catch(e){V(2,e,"[export] The JS resource cannot be loaded.")}s.length=0;const a=[];if(i.css){let r=i.css.match(/@import\s*([^;]*);/g);if(r)for(let e of r)e&&(e=e.replace("url(","").replace("@import","").replace(/"/g,"").replace(/'/g,"").replace(/;/,"").replace(/\)/g,"").trim(),e.startsWith("http")?a.push({url:e}):t.customLogic.allowFileResources&&a.push({path:n.join(B,e)}));a.push({content:i.css.replace(/@import\s*([^;]*);/g,"")||" "});for(const t of a)try{o.push(await e.addStyleTag(t))}catch(e){V(2,e,"[export] The CSS resource cannot be loaded.")}a.length=0}}return o}(e,o);const c=l?await e.evaluate((e=>{const t=document.querySelector("#chart-container svg:first-of-type"),o=t.height.baseVal.value*e,r=t.width.baseVal.value*e;return document.body.style.zoom=e,document.body.style.margin="0px",{chartHeight:o,chartWidth:r}}),parseFloat(s.scale)):await e.evaluate((()=>{const{chartHeight:e,chartWidth:t}=window.Highcharts.charts[0];return document.body.style.zoom=1,{chartHeight:e,chartWidth:t}})),p=Math.abs(Math.ceil(c.chartHeight||s.height)),h=Math.abs(Math.ceil(c.chartWidth||s.width)),{x:u,y:d}=await(e=>e.$eval("#chart-container",(e=>{const{x:t,y:o,width:r,height:i}=e.getBoundingClientRect();return{x:t,y:o,width:r,height:Math.trunc(i>1?i:500)}})))(e);let g;if(await e.setViewport({height:p,width:h,deviceScaleFactor:l?1:parseFloat(s.scale)}),"svg"===s.type)g=await(e=>e.$eval("#container svg:first-of-type",(e=>e.outerHTML)))(e);else if(["png","jpeg"].includes(s.type))g=await((e,t,o,r,i)=>Promise.race([e.screenshot({type:t,encoding:o,clip:r,captureBeyondViewport:!0,fullPage:!1,optimizeForSpeed:!0,..."png"!==t?{quality:80}:{},omitBackground:"png"==t}),new Promise(((e,t)=>setTimeout((()=>t(new ce("Rasterization timeout"))),i||1500)))]))(e,s.type,"base64",{width:h,height:p,x:u,y:d},s.rasterizationTimeout);else{if("pdf"!==s.type)throw new ce(`[export] Unsupported output format ${s.type}.`);g=await(async(e,t,o,r,i)=>(await e.emulateMediaType("screen"),e.pdf({height:t+1,width:o,encoding:r,timeout:i||1500})))(e,p,h,"base64",s.rasterizationTimeout)}return await Te(e,i),g}catch(t){return await Te(e,i),t}};let _e=!1;const Oe={performedExports:0,exportAttempts:0,exportFromSvgAttempts:0,timeSpent:0,droppedExports:0,spentAverage:0};let Le={};const ke={create:async()=>{let e=!1;const t=v(),o=(new Date).getTime();try{if(e=await Ee(),!e||e.isClosed())throw new ce("The page is invalid or closed.");F(3,`[pool] Successfully created a worker ${t} - took ${(new Date).getTime()-o} ms.`)}catch(e){throw new ce("Error encountered when creating a new page.").setError(e)}return{id:t,page:e,workCount:Math.round(Math.random()*(Le.workLimit/2))}},validate:async e=>!(!e.page||e.page?.isClosed())&&(!(Le.workLimit&&++e.workCount>Le.workLimit)||(F(3,`[pool] Worker failed validation: exceeded work limit (limit is ${Le.workLimit}).`),!1)),destroy:async e=>{F(3,`[pool] Destroying pool entry ${e.id}.`),e.page&&!e.page.isClosed()&&await e.page.close()}},Ie=async e=>{if(Le=e&&e.pool?{...e.pool}:{},await async function(e){const{puppeteer:t,debug:o,other:r}=re(),{enable:i,...s}=o,n={headless:!r.browserShellMode||"shell",userDataDir:t.tempDir||"./tmp/",args:e,handleSIGINT:!1,handleSIGTERM:!1,handleSIGHUP:!1,waitForInitialPage:!1,defaultViewport:null,...i&&s};if(!we){const e=25;let t=0;const o=async()=>{try{F(3,`[browser] Attempting to get a browser instance (try ${++t}).`),we=await y.launch(n)}catch(r){if(V(2,r,`[browser] Failed to launch a browser instance - retrying (attempt ${t}/${e}).`),!(t<25))throw r;F(3,`[browser] Retry to open a browser (attempt ${t}/${e}).`),await new Promise((e=>setTimeout(e,4e3))),await o()}};try{await o(),"shell"===n.headless&&F(3,"[browser] Launched browser in shell mode."),i&&F(3,"[browser] Launched browser in debug mode.")}catch(e){throw new ce("[browser] Maximum retries to open a browser instance reached.").setError(e)}if(!we)throw new ce("[browser] Cannot find a browser to open.")}return we}(e.puppeteerArgs),F(3,`[pool] Initializing pool with workers: min ${Le.minWorkers}, max ${Le.maxWorkers}.`),_e)return F(4,"[pool] Already initialized, please kill it before creating a new one.");parseInt(Le.minWorkers)>parseInt(Le.maxWorkers)&&(Le.minWorkers=Le.maxWorkers);try{_e=new f({...ke,min:parseInt(Le.minWorkers),max:parseInt(Le.maxWorkers),acquireTimeoutMillis:Le.acquireTimeout,createTimeoutMillis:Le.createTimeout,destroyTimeoutMillis:Le.destroyTimeout,idleTimeoutMillis:Le.idleTimeout,createRetryIntervalMillis:Le.createRetryInterval,reapIntervalMillis:Le.reaperInterval,propagateCreateError:!1}),_e.on("release",(async e=>{const t=await async function(e,t=!1){try{if(e&&!e.isClosed())return t?(await e.goto("about:blank",{waitUntil:"domcontentloaded"}),await Se(e)):await e.evaluate((()=>{document.body.innerHTML='
'})),!0}catch(e){V(2,e,"[browser] Could not clear the content of the page.")}return!1}(e.page,!1);F(4,`[pool] Releasing a worker with ID ${e.id}. Clear page status: ${t}.`)})),_e.on("destroySuccess",((e,t)=>{F(4,`[pool] Destroyed a worker with ID ${t.id}.`),t.page=null}));const e=[];for(let t=0;t{_e.release(e)})),F(3,"[pool] The pool is ready"+(e.length?` with ${e.length} initial resources waiting.`:"."))}catch(e){throw new ce("[pool] Could not create the pool of workers.").setError(e)}};async function Ce(){if(F(3,"[pool] Killing pool with all workers and closing browser."),_e){for(const e of _e.used)_e.release(e.resource);_e.destroyed||(await _e.destroy(),F(4,"[browser] Destroyed the pool of resources."))}await async function(){we?.connected&&await we.close(),F(4,"[browser] Closed the browser.")}()}const Ne=async(e,t)=>{let o;try{if(F(4,"[pool] Work received, starting to process."),++Oe.exportAttempts,Le.benchmarking&&Pe(),!_e)throw new ce("Work received, but pool has not been started.");const r=te();try{F(4,"[pool] Acquiring a worker handle."),o=await _e.acquire().promise,t.server.benchmarking&&F(5,t.payload?.requestId?`[benchmark] Request with ID ${t.payload?.requestId} -`:"[benchmark]",`Acquired a worker handle: ${r()}ms.`)}catch(e){throw new ce((t.payload?.requestId?`For request with ID ${t.payload?.requestId} - `:"")+`Error encountered when acquiring an available entry: ${r()}ms.`).setError(e)}if(F(4,"[pool] Acquired a worker handle."),!o.page)throw new ce("Resolved worker page is invalid: the pool setup is wonky.");let i=(new Date).getTime();F(4,`[pool] Starting work on pool entry with ID ${o.id}.`);const s=te(),n=await Re(o.page,e,t);if(n instanceof Error)throw"Rasterization timeout"===n.message&&(o.workCount=Le.workLimit+1,o.page=null),"TimeoutError"===n.name||"Rasterization timeout"===n.message?new ce("Rasterization timeout: your chart may be too complex or large, and failed to render within the allotted time.").setError(n):new ce((t.payload?.requestId?`For request with ID ${t.payload?.requestId} - `:"")+`Error encountered during export: ${s()}ms.`).setError(n);t.server.benchmarking&&F(5,t.payload?.requestId?`[benchmark] Request with ID ${t.payload?.requestId} -`:"[benchmark]",`Exported a chart sucessfully: ${s()}ms.`),_e.release(o);const a=(new Date).getTime()-i;return Oe.timeSpent+=a,Oe.spentAverage=Oe.timeSpent/++Oe.performedExports,F(4,`[pool] Work completed in ${a} ms.`),{result:n,options:t}}catch(e){throw++Oe.droppedExports,o&&_e.release(o),new ce(`[pool] In pool.postWork: ${e.message}`).setError(e)}},Ae=()=>({min:_e.min,max:_e.max,all:_e.numFree()+_e.numUsed(),available:_e.numFree(),used:_e.numUsed(),pending:_e.numPendingAcquires()});function Pe(){const{min:e,max:t,all:o,available:r,used:i,pending:s}=Ae();F(5,`[pool] The minimum number of resources allowed by pool: ${e}.`),F(5,`[pool] The maximum number of resources allowed by pool: ${t}.`),F(5,`[pool] The number of all created resources: ${o}.`),F(5,`[pool] The number of available resources: ${r}.`),F(5,`[pool] The number of acquired resources: ${i}.`),F(5,`[pool] The number of resources waiting to be acquired: ${s}.`)}var $e=Ae,He=()=>Oe;let De=!1;const Ge=async(e,t)=>{F(4,"[chart] Starting the exporting process.");const o=((e,t={})=>{let o={};return e.svg?(o=J(t),o.export.type=e.type||e.export.type,o.export.scale=e.scale||e.export.scale,o.export.outfile=e.outfile||e.export.outfile,o.payload={svg:e.svg}):o=ie(t,e,L),o.export.outfile=o.export?.outfile||`chart.${o.export?.type||"png"}`,o})(e,re()),i=o.export;if(o.payload?.svg&&""!==o.payload.svg)try{F(4,"[chart] Attempting to export from a SVG input.");const e=Fe(function(e){const t=[];G.OTHER_ALLOW_XLINK||t.push("xlink:href");const o=new b("").window;return w(o).sanitize(e,{ADD_TAGS:["foreignObject"],FORBID_ATTR:t})}(o.payload.svg),o,t);return++Oe.exportFromSvgAttempts,e}catch(e){return t(new ce("[chart] Error loading SVG input.").setError(e))}if(i.infile&&i.infile.length)try{return F(4,"[chart] Attempting to export from an input file."),o.export.instr=r(i.infile,"utf8"),Fe(o.export.instr.trim(),o,t)}catch(e){return t(new ce("[chart] Error loading input file.").setError(e))}if(i.instr&&""!==i.instr||i.options&&""!==i.options)try{return F(4,"[chart] Attempting to export from a raw input."),i.instr=i.instr||i.options,Q(o.customLogic?.allowCodeExecution)?je(o,t):"string"==typeof i.instr?Fe(i.instr.trim(),o,t):Me(o,i.instr||i.options,t)}catch(e){return t(new ce("[chart] Error loading raw input.").setError(e))}return t(new ce("[chart] No valid input specified. Check if at least one of the following parameters is correctly set: 'infile', 'instr', 'options', or 'svg'."))},Ue=e=>{const{chart:t,exporting:o}=e.export?.options||z(e.export?.instr),r=z(e.export?.globalOptions);let i=e.export?.scale||o?.scale||r?.exporting?.scale||e.export?.defaultScale||1;i=Math.max(.1,Math.min(i,5)),i=((e,t=1)=>{const o=Math.pow(10,t||0);return Math.round(+e*o)/o})(i,2);const s={height:e.export?.height||o?.sourceHeight||t?.height||r?.exporting?.sourceHeight||r?.chart?.height||e.export?.defaultHeight||400,width:e.export?.width||o?.sourceWidth||t?.width||r?.exporting?.sourceWidth||r?.chart?.width||e.export?.defaultWidth||600,scale:i};for(let[e,t]of Object.entries(s))s[e]="string"==typeof t?+t.replace(/px|%/gi,""):t;return s},Me=async(e,t,o,i)=>{let{export:s,customLogic:n}=e;const a="boolean"==typeof n.allowCodeExecution?n.allowCodeExecution:De;if(n){if(a)if("string"==typeof e.customLogic.resources)e.customLogic.resources=K(e.customLogic.resources,Q(e.customLogic.allowFileResources));else if(!e.customLogic.resources)try{const t=r("resources.json","utf8");e.customLogic.resources=K(t,Q(e.customLogic.allowFileResources))}catch(e){F(2,"[chart] Unable to load the default resources.json file.")}}else n=e.customLogic={};if(!a&&n){if(n.callback||n.resources||n.customCode)return o(new ce("[chart] The 'callback', 'resources' and 'customCode' options have been disabled for this server."));n.callback=!1,n.resources=!1,n.customCode=!1}if(t&&(t.chart=t.chart||{},t.exporting=t.exporting||{},t.exporting.enabled=!1),s.constr=s.constr||"chart",s.type=X(s.type,s.outfile),"svg"===s.type&&(s.width=!1),["globalOptions","themeOptions"].forEach((e=>{try{s&&s[e]&&("string"==typeof s[e]&&s[e].endsWith(".json")?s[e]=z(r(s[e],"utf8"),!0):s[e]=z(s[e],!0))}catch(t){s[e]={},V(2,t,`[chart] The '${e}' cannot be loaded.`)}})),n.allowCodeExecution)try{n.customCode=ee(n.customCode,n.allowFileResources)}catch(e){V(2,e,"[chart] The 'customCode' cannot be loaded.")}if(n&&n.callback&&n.callback?.indexOf("{")<0)if(n.allowFileResources)try{n.callback=r(n.callback,"utf8")}catch(e){n.callback=!1,V(2,e,"[chart] The 'callback' cannot be loaded.")}else n.callback=!1;e.export={...e.export,...Ue(e)};try{return o(!1,await Ne(s.strInj||t||i,e))}catch(e){return o(e)}},je=(e,t)=>{try{let o,r=e.export.instr||e.export.options;return"string"!=typeof r&&(o=r=Y(r,e.customLogic?.allowCodeExecution)),o=r.replaceAll(/\t|\n|\r/g,"").trim(),";"===o[o.length-1]&&(o=o.substring(0,o.length-1)),e.export.strInj=o,Me(e,!1,t)}catch(o){return t(new ce(`[chart] Malformed input detected for ${e.export?.requestId||"?"}. Please make sure that your JSON/JavaScript options are sent using the "options" attribute, and that if you're using SVG, it is unescaped.`).setError(o))}},Fe=(e,t,o)=>{const{allowCodeExecution:r}=t.customLogic;if(e.indexOf("=0||e.indexOf("=0)return F(4,"[chart] Parsing input as SVG."),Me(t,!1,o,e);try{const r=JSON.parse(e.replaceAll(/\t|\n|\r/g," "));return Me(t,r,o)}catch(e){return Q(r)?je(t,o):o(new ce("[chart] Only JSON configurations and SVG are allowed for this server. If this is your server, JavaScript custom code can be enabled by starting the server with the --allowCodeExecution flag.").setError(e))}},Ve=[],We=()=>{F(4,"[server] Clearing all registered intervals.");for(const e of Ve)clearInterval(e)},qe=(e,t,o,r)=>{V(1,e),"development"!==G.OTHER_NODE_ENV&&delete e.stack,r(e)},Be=(e,t,o,r)=>{const{statusCode:i,status:s,message:n,stack:a}=e,l=i||s||400;o.status(l).json({statusCode:l,message:n,stack:a})};var Xe=(e,t)=>{const o="Too many requests, you have been rate limited. Please try again later.",r={max:t.maxRequests||30,window:t.window||1,delay:t.delay||0,trustProxy:t.trustProxy||!1,skipKey:t.skipKey||!1,skipToken:t.skipToken||!1};r.trustProxy&&e.enable("trust proxy");const i=x({windowMs:60*r.window*1e3,max:r.max,delayMs:r.delay,handler:(e,t)=>{t.format({json:()=>{t.status(429).send({message:o})},default:()=>{t.status(429).send(o)}})},skip:e=>!1!==r.skipKey&&!1!==r.skipToken&&e.query.key===r.skipKey&&e.query.access_token===r.skipToken&&(F(4,"[rate limiting] Skipping rate limiter."),!0)});e.use(i),F(3,`[rate limiting] Enabled rate limiting with ${r.max} requests per ${r.window} minute for each IP, trusting proxy: ${r.trustProxy}.`)};class Ke extends ce{constructor(e,t){super(e),this.status=this.statusCode=t}setStatus(e){return this.status=e,this}}var ze=e=>!!e&&e.post("/version/change/:newVersion",(async(e,t,o)=>{try{const o=G.HIGHCHARTS_ADMIN_TOKEN;if(!o||!o.length)throw new Ke("The server is not configured to perform run-time version changes: HIGHCHARTS_ADMIN_TOKEN is not set.",401);const r=e.get("hc-auth");if(!r||r!==o)throw new Ke("Invalid or missing token: Set the token in the hc-auth header.",401);const i=e.params.newVersion;if(!i)throw new Ke("No new version supplied.",400);try{await(async e=>{const t=re();t?.highcharts&&(t.highcharts.version=e),await ge(t)})(i)}catch(e){throw new Ke(`Version change: ${e.message}`,e.statusCode).setError(e)}t.status(200).send({statusCode:200,version:fe(),message:`Successfully updated Highcharts to version: ${i}.`})}catch(e){o(e)}}));const Je={png:"image/png",jpeg:"image/jpeg",gif:"image/gif",pdf:"application/pdf",svg:"image/svg+xml"};let Ye=0;const Ze=[],Qe=[],et=(e,t,o,r)=>{let i=!0;const{id:s,uniqueId:n,type:a,body:l}=r;return e.some((e=>{if(e){let r=e(t,o,s,n,a,l);return void 0!==r&&!0!==r&&(i=r),!0}})),i},tt=async(e,t,o)=>{try{const o=te(),i=v().replace(/-/g,""),s=re(),n=e.body,a=++Ye;let l=X(n.type);if(!n||"object"==typeof(r=n)&&!Array.isArray(r)&&null!==r&&0===Object.keys(r).length)throw new Ke("The request body is required. Please ensure that your Content-Type header is correct (accepted types are application/json and multipart/form-data).",400);let c=z(n.infile||n.options||n.data);if(!c&&!n.svg)throw F(2,`The request with ID ${i} from ${e.headers["x-forwarded-for"]||e.connection.remoteAddress} was incorrect:\n Content-Type: ${e.headers["content-type"]}. \n Chart constructor: ${n.constr}.\n Dimensions: ${n.width}x${n.height} @ ${n.scale} scale.\n Type: ${l}.\n Is SVG set? ${void 0!==n.svg}.\n B64? ${void 0!==n.b64}.\n No download? ${void 0!==n.noDownload}.\n\n Payload received: ${JSON.stringify(n.infile||n.options||n.data||n.svg)}\n\n `),new Ke("No correct chart data found. Ensure that you are using either application/json or multipart/form-data headers. If sending JSON, make sure the chart data is in the 'infile', 'options', or 'data' attribute. If sending SVG, ensure it is in the 'svg' attribute.",400);let p=!1;if(p=et(Ze,e,t,{id:a,uniqueId:i,type:l,body:n}),!0!==p)return t.send(p);let h=!1;e.socket.on("close",(e=>{e&&(h=!0)})),F(4,`[export] Got an incoming HTTP request with ID ${i}.`),n.constr="string"==typeof n.constr&&n.constr||"chart";const u={export:{instr:c,type:l,constr:n.constr[0].toLowerCase()+n.constr.substr(1),height:n.height,width:n.width,scale:n.scale||s.export.scale,globalOptions:z(n.globalOptions,!0),themeOptions:z(n.themeOptions,!0)},customLogic:{allowCodeExecution:De,allowFileResources:!1,resources:z(n.resources,!0),callback:n.callback,customCode:n.customCode}};c&&(u.export.instr=Y(c,u.customLogic.allowCodeExecution));const d=ie(s,u);if(d.export.options=c,d.payload={svg:n.svg||!1,b64:n.b64||!1,noDownload:n.noDownload||!1,requestId:i},n.svg&&(e=>[/xlink:href="(?:http:\/\/|https:\/\/)?localhost\b/,/xlink:href="(?:http:\/\/|https:\/\/)?10\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/,/xlink:href="(?:http:\/\/|https:\/\/)?127\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/,/xlink:href="(?:http:\/\/|https:\/\/)?172\.(1[6-9]|2[0-9]|3[0-1])\.\d{1,3}\.\d{1,3}\b/,/xlink:href="(?:http:\/\/|https:\/\/)?192\.168\.\d{1,3}\.\d{1,3}\b/].some((t=>t.test(e))))(d.payload.svg))throw new Ke("SVG potentially contain at least one forbidden URL in xlink:href element. Please review the SVG content and ensure that all referenced URLs comply with security policies.",400);await Ge(d,((r,c)=>{if(e.socket.removeAllListeners("close"),s.server.benchmarking&&F(5,`[benchmark] Request with ID ${i} - After the whole exporting process: ${o()}ms.`),h)return F(3,"[export] The client closed the connection before the chart finished processing.");if(r)throw r;if(!c||!c.result)throw new Ke(`Unexpected return from chart generation. Please check your request data. For the request with ID ${i}, the result is ${c.result}.`,400);return l=c.options.export.type,et(Qe,e,t,{id:a,body:c.result}),c.result?n.b64?"pdf"===l||"svg"==l?t.send(Buffer.from(c.result,"utf8").toString("base64")):t.send(c.result):(t.header("Content-Type",Je[l]||"image/png"),n.noDownload||t.attachment(`${e.params.filename||e.body.filename||"chart"}.${l||"png"}`),"svg"===l?t.send(c.result):t.send(Buffer.from(c.result,"base64"))):void 0}))}catch(e){o(e)}var r};const ot=JSON.parse(r(a(B,"package.json"))),rt=new Date,it=[];function st(e){if(!e)return!1;var t;t=setInterval((()=>{const e=He(),t=0===e.exportAttempts?1:e.performedExports/e.exportAttempts*100;it.push(t),it.length>30&&it.shift()}),6e4),Ve.push(t),e.get("/health",((e,t)=>{const o=He(),r=it.length,i=it.reduce(((e,t)=>e+t),0)/it.length;F(4,"[health.js] GET /health [200] - returning server health."),t.send({status:"OK",bootTime:rt,uptime:Math.floor(((new Date).getTime()-rt.getTime())/1e3/60)+" minutes",version:ot.version,highchartsVersion:fe(),averageProcessingTime:o.spentAverage,performedExports:o.performedExports,failedExports:o.droppedExports,exportAttempts:o.exportAttempts,sucessRatio:o.performedExports/o.exportAttempts*100,pool:$e(),period:r,movingAverage:i,message:isNaN(i)||!it.length?"Too early to report. No exports made yet. Please check back soon.":`Last ${r} minutes had a success rate of ${i.toFixed(2)}%.`,svgExportAttempts:o.exportFromSvgAttempts,jsonExportAttempts:o.performedExports-o.exportFromSvgAttempts})}))}const nt=new Map,at=T();at.disable("x-powered-by"),at.use(E()),at.use(((e,t,o)=>{t.set("Accept-Ranges","none"),o()}));const lt=e=>{e.on("clientError",((e,t)=>{V(1,e,`[server] Client error: ${e.message}, destroying socket.`),t.destroy()})),e.on("error",(e=>{V(1,e,`[server] Server error: ${e.message}`)})),e.on("connection",(e=>{e.on("error",(e=>{V(1,e,`[server] Socket error: ${e.message}`)}))}))},ct=async e=>{try{const t=1024*(e.maxUploadSize||3)*1024,o=S.memoryStorage(),r=S({storage:o,limits:{fieldSize:t}});if(at.use(T.json({limit:t})),at.use(T.urlencoded({extended:!0,limit:t})),at.use(r.none()),!e.enable)return!1;if(!e.ssl.force){const t=g.createServer(at);lt(t),t.listen(e.port,e.host),nt.set(e.port,t),F(3,`[server] Started HTTP server on ${e.host}:${e.port}.`)}if(e.ssl.enable){let t,o;try{t=await i.readFile(l.join(e.ssl.certPath,"server.key"),"utf8"),o=await i.readFile(l.join(e.ssl.certPath,"server.crt"),"utf8")}catch(t){F(2,`[server] Unable to load key/certificate from the '${e.ssl.certPath}' path. Could not run secured layer server.`)}if(t&&o){const r=m.createServer({key:t,cert:o},at);lt(r),r.listen(e.ssl.port,e.host),nt.set(e.ssl.port,r),F(3,`[server] Started HTTPS server on ${e.host}:${e.ssl.port}.`)}}e.rateLimiting&&e.rateLimiting.enable&&![0,NaN].includes(e.rateLimiting.maxRequests)&&Xe(at,e.rateLimiting),at.use(T.static(l.join(B,"public"))),st(at),(e=>{e.post("/",tt),e.post("/:filename",tt)})(at),(e=>{!!e&&e.get("/",((e,t)=>{t.sendFile(a(B,"public","index.html"),{acceptRanges:!1})}))})(at),ze(at),(e=>{e.use(qe),e.use(Be)})(at)}catch(e){throw new ce("[server] Could not configure and start the server.").setError(e)}},pt=()=>{F(4,"[server] Closing all servers.");for(const[e,t]of nt)t.close((()=>{nt.delete(e),F(4,`[server] Closed server on port: ${e}.`)}))};var ht={startServer:ct,closeServers:pt,getServers:()=>nt,enableRateLimiting:e=>Xe(at,e),getExpress:()=>T,getApp:()=>at,use:(e,...t)=>{at.use(e,...t)},get:(e,...t)=>{at.get(e,...t)},post:(e,...t)=>{at.post(e,...t)}};const ut=async e=>{await Promise.allSettled([We(),pt(),Ce()]),process.exit(e)};var dt={server:ht,startServer:ct,initExport:async e=>{var t;return t=e.customLogic&&e.customLogic.allowCodeExecution,De=Q(t),(e=>{for(const[t,o]of Object.entries(e))M[t]=o;W(e&&parseInt(e.level)),e&&e.dest&&e.toFile&&q(e.dest,e.file||"highcharts-export-server.log")})(e.logging),e.other.listenToProcessExits&&(F(3,"[process] Attaching exit listeners to the process."),process.on("exit",(e=>{F(4,`Process exited with code ${e}.`)})),process.on("SIGINT",(async(e,t)=>{F(4,`The ${e} event with code: ${t}.`),await ut(0)})),process.on("SIGTERM",(async(e,t)=>{F(4,`The ${e} event with code: ${t}.`),await ut(0)})),process.on("SIGHUP",(async(e,t)=>{F(4,`The ${e} event with code: ${t}.`),await ut(0)})),process.on("uncaughtException",(async(e,t)=>{V(1,e,`The ${t} error.`),await ut(1)}))),await ge(e),await Ie({pool:e.pool||{minWorkers:1,maxWorkers:1},puppeteerArgs:e.puppeteer.args||[]}),e},singleExport:async e=>{e.export.instr=e.export.instr||e.export.options,await Ge(e,(async(e,t)=>{if(e)throw e;const{outfile:o,type:r}=t.options.export;s(o||`chart.${r}`,"svg"!==r?Buffer.from(t.result,"base64"):t.result),await Ce()}))},batchExport:async e=>{const t=[];for(let o of e.export.batch.split(";"))o=o.split("="),2===o.length&&t.push(Ge({...e,export:{...e.export,infile:o[0],outfile:o[1]}},((e,t)=>{if(e)throw e;s(t.options.export.outfile,"svg"!==t.options.export.type?Buffer.from(t.result,"base64"):t.result)})));try{await Promise.all(t),await Ce()}catch(e){throw new ce("[chart] Error encountered during batch export.").setError(e)}},startExport:Ge,initPool:Ie,killPool:Ce,setOptions:(e,t)=>(t?.length&&(oe=function(e){const t=e.findIndex((e=>"loadConfig"===e.replace(/-/g,"")));if(t>-1&&e[t+1]){const o=e[t+1];try{if(o&&o.endsWith(".json"))return JSON.parse(r(o))}catch(e){V(2,e,`[config] Unable to load the configuration from the ${o} file.`)}}return{}}(t)),se(_,oe),oe=ne(_),e&&(oe=ie(oe,e,L)),t?.length&&(oe=function(e,t,o){let r=!1;for(let i=0;i(n.length-1===o&&(a=e[t].type),e[t])),o),n.reduce(((e,o,l)=>(n.length-1===l&&void 0!==e[o]&&(t[++i]?"boolean"===a?e[o]=Q(t[i]):"number"===a?e[o]=+t[i]:a.indexOf("]")>=0?e[o]=t[i].split(","):e[o]=t[i]:(F(2,`[config] Missing value for the '${s}' argument. Using the default value.`),r=!0)),e[o])),e)}r&&Z();return e}(oe,t,_)),oe),shutdownCleanUp:ut,log:F,logWithStack:V,setLogLevel:W,enableFileLogging:q,mapToNewConfig:e=>{const t={};for(const[o,r]of Object.entries(e)){const e=k[o]?k[o].split("."):[];e.reduce(((t,o,i)=>t[o]=e.length-1===i?r:t[o]||{}),t)}return t},manualConfig:async t=>{let o={};e(t)&&(o=JSON.parse(r(t,"utf8")));const s=Object.keys(O).map((e=>({title:`${e} options`,value:e})));return p({type:"multiselect",name:"category",message:"Which category do you want to configure?",hint:"Space: Select specific, A: Select all, Enter: Confirm.",instructions:"",choices:s},{onSubmit:async(e,r)=>{let s=0,n=[];for(const e of r)O[e]=O[e].map((t=>({...t,section:e}))),n=[...n,...O[e]];return await p(n,{onSubmit:async(e,r)=>{if("moduleScripts"===e.name?(r=r.length?r.map((t=>e.choices[t])):e.choices,o[e.section][e.name]=r):o[e.section]=ae(Object.assign({},o[e.section]||{}),e.name.split("."),e.choices?e.choices[r]:r),++s===n.length){try{await i.writeFile(t,JSON.stringify(o,null,2),"utf8")}catch(e){V(1,e,`[config] An error occurred while creating the ${t} file.`)}return!0}}}),!0}})},printLogo:e=>{const t=JSON.parse(r(a(B,"package.json"))).version;e?console.log(`Starting Highcharts Export Server v${t}...`):console.log(r(B+"/msg/startup.msg").toString().bold.yellow,`v${t}\n`.bold)},printUsage:Z};export{dt as default}; +import"colors";import{existsSync as e,mkdirSync as t,appendFile as o,readFileSync as r,promises as i,writeFileSync as s}from"fs";import n,{join as a,posix as l}from"path";import{HttpsProxyAgent as c}from"https-proxy-agent";import p from"prompts";import h from"dotenv";import{z as u}from"zod";import{fileURLToPath as d}from"url";import g from"http";import m from"https";import{Pool as f}from"tarn";import{v4 as v}from"uuid";import y from"puppeteer";import{JSDOM as b}from"jsdom";import w from"dompurify";import E from"cors";import T from"express";import S from"multer";import x from"express-rate-limit";const R={core:["highcharts","highcharts-more","highcharts-3d"],modules:["stock","map","gantt","exporting","parallel-coordinates","accessibility","boost-canvas","boost","data","data-tools","draggable-points","static-scale","broken-axis","heatmap","tilemap","tiledwebmap","timeline","treemap","treegraph","item-series","drilldown","histogram-bellcurve","bullet","funnel","funnel3d","geoheatmap","pyramid3d","networkgraph","overlapping-datalabels","pareto","pattern-fill","pictorial","price-indicator","sankey","arc-diagram","dependency-wheel","series-label","series-on-point","solid-gauge","sonification","streamgraph","sunburst","variable-pie","variwide","vector","venn","windbarb","wordcloud","xrange","no-data-to-display","drag-panes","debugger","dumbbell","lollipop","cylinder","organization","dotplot","marker-clusters","hollowcandlestick","heikinashi","flowmap","export-data","navigator","textpath"],indicators:["indicators-all"],custom:["https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.30.1/moment.min.js","https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.45/moment-timezone-with-data.min.js"]},_={puppeteer:{args:{value:["--allow-running-insecure-content","--ash-no-nudges","--autoplay-policy=user-gesture-required","--block-new-web-contents","--disable-accelerated-2d-canvas","--disable-background-networking","--disable-background-timer-throttling","--disable-backgrounding-occluded-windows","--disable-breakpad","--disable-checker-imaging","--disable-client-side-phishing-detection","--disable-component-extensions-with-background-pages","--disable-component-update","--disable-default-apps","--disable-dev-shm-usage","--disable-domain-reliability","--disable-extensions","--disable-features=CalculateNativeWinOcclusion,InterestFeedContentSuggestions,WebOTP","--disable-hang-monitor","--disable-ipc-flooding-protection","--disable-logging","--disable-notifications","--disable-offer-store-unmasked-wallet-cards","--disable-popup-blocking","--disable-print-preview","--disable-prompt-on-repost","--disable-renderer-backgrounding","--disable-search-engine-choice-screen","--disable-session-crashed-bubble","--disable-setuid-sandbox","--disable-site-isolation-trials","--disable-speech-api","--disable-sync","--enable-unsafe-webgpu","--hide-crash-restore-bubble","--hide-scrollbars","--metrics-recording-only","--mute-audio","--no-default-browser-check","--no-first-run","--no-pings","--pipe","--no-startup-window","--password-store=basic","--process-per-tab","--use-mock-keychain"],type:"string[]",description:"Arguments array to send to Puppeteer."},tempDir:{value:"./tmp/",type:"string",envLink:"PUPPETEER_TEMP_DIR",description:"The directory for Puppeteer to store temporary files."}},highcharts:{version:{value:"latest",type:"string",envLink:"HIGHCHARTS_VERSION",description:"The Highcharts version to be used."},cdnURL:{value:"https://code.highcharts.com/",type:"string",envLink:"HIGHCHARTS_CDN_URL",description:"The CDN URL for Highcharts scripts to be used."},coreScripts:{value:R.core,type:"string[]",envLink:"HIGHCHARTS_CORE_SCRIPTS",description:"The core Highcharts scripts to fetch."},moduleScripts:{value:R.modules,type:"string[]",envLink:"HIGHCHARTS_MODULE_SCRIPTS",description:"The modules of Highcharts to fetch."},indicatorScripts:{value:R.indicators,type:"string[]",envLink:"HIGHCHARTS_INDICATOR_SCRIPTS",description:"The indicators of Highcharts to fetch."},customScripts:{value:R.custom,type:"string[]",description:"Additional custom scripts or dependencies to fetch."},forceFetch:{value:!1,type:"boolean",envLink:"HIGHCHARTS_FORCE_FETCH",description:"The flag to determine whether to refetch all scripts after each server rerun."},cachePath:{value:".cache",type:"string",envLink:"HIGHCHARTS_CACHE_PATH",description:"The path to the cache directory. It is used to store the Highcharts scripts and custom scripts."}},export:{infile:{value:!1,type:"string",description:"The input file should include a name and a type (json or svg). It must be correctly formatted as a JSON or SVG file."},instr:{value:!1,type:"string",description:"Input, provided in the form of a stringified JSON or SVG file, will override the --infile option."},options:{value:!1,type:"string",description:"An alias for the --instr option."},outfile:{value:!1,type:"string",description:"The output filename along with a type (jpeg, png, pdf, or svg). This will ignore the --type flag."},type:{value:"png",type:"string",envLink:"EXPORT_TYPE",description:"The file export format. It can be jpeg, png, pdf, or svg."},constr:{value:"chart",type:"string",envLink:"EXPORT_CONSTR",description:"The constructor to use. Can be chart, stockChart, mapChart, or ganttChart."},defaultHeight:{value:400,type:"number",envLink:"EXPORT_DEFAULT_HEIGHT",description:"the default height of the exported chart. Used when no value is set."},defaultWidth:{value:600,type:"number",envLink:"EXPORT_DEFAULT_WIDTH",description:"The default width of the exported chart. Used when no value is set."},defaultScale:{value:1,type:"number",envLink:"EXPORT_DEFAULT_SCALE",description:"The default scale of the exported chart. Used when no value is set."},height:{value:!1,type:"number",description:"The height of the exported chart, overriding the option in the chart settings."},width:{value:!1,type:"number",description:"The width of the exported chart, overriding the option in the chart settings."},scale:{value:!1,type:"number",description:"The scale of the exported chart, overriding the option in the chart settings. Ranges between 0.1 and 5.0."},globalOptions:{value:!1,type:"string",description:"Either a stringified JSON or a filename containing options to be passed into the Highcharts.setOptions."},themeOptions:{value:!1,type:"string",description:"Either a stringified JSON or a filename containing theme options to be passed into the Highcharts.setOptions."},batch:{value:!1,type:"string",description:'Initiates a batch job with a string containing input/output pairs: "in=out;in=out;...".'},rasterizationTimeout:{value:1500,type:"number",envLink:"EXPORT_RASTERIZATION_TIMEOUT",description:"The duration in milliseconds to wait for rendering a webpage."}},customLogic:{allowCodeExecution:{value:!1,type:"boolean",envLink:"CUSTOM_LOGIC_ALLOW_CODE_EXECUTION",description:"Controls whether the execution of arbitrary code is allowed during the exporting process."},allowFileResources:{value:!1,type:"boolean",envLink:"CUSTOM_LOGIC_ALLOW_FILE_RESOURCES",description:"Controls the ability to inject resources from the filesystem. This setting has no effect when running as a server."},customCode:{value:!1,type:"string",description:"Custom code to execute before chart initialization. It can be a function, code wrapped within a function, or a filename with the .js extension."},callback:{value:!1,type:"string",description:"JavaScript code to run during construction. It can be a function or a filename with the .js extension."},resources:{value:!1,type:"string",description:"Additional resource in the form of a stringified JSON, which may contain files, js, and css sections."},loadConfig:{value:!1,type:"string",legacyName:"fromFile",description:"A file containing a pre-defined configuration to use."},createConfig:{value:!1,type:"string",description:"Enables setting options through a prompt and saving them in a provided config file."}},server:{maxUploadSize:{value:3,type:"number",envLink:"SERVER_MAX_UPLOAD_SIZE",description:"The maximum upload size, in MB, for the server."},enable:{value:!1,type:"boolean",envLink:"SERVER_ENABLE",cliName:"enableServer",description:"When set to true, the server starts on the local IP address 0.0.0.0."},host:{value:"0.0.0.0",type:"string",envLink:"SERVER_HOST",description:"The hostname of the server. Additionally, it starts a server on the provided hostname."},port:{value:7801,type:"number",envLink:"SERVER_PORT",description:"The server port when enabled."},benchmarking:{value:!1,type:"boolean",envLink:"SERVER_BENCHMARKING",cliName:"serverBenchmarking",description:"Indicates whether to display the duration, in milliseconds, of specific actions that occur on the server while serving a request."},proxy:{host:{value:!1,type:"string",envLink:"SERVER_PROXY_HOST",cliName:"proxyHost",description:"The host of the proxy server to use, if it exists."},port:{value:8080,type:"number",envLink:"SERVER_PROXY_PORT",cliName:"proxyPort",description:"The port of the proxy server to use, if it exists."},username:{value:!1,type:"string",envLink:"SERVER_PROXY_USERNAME",cliName:"proxyUsername",description:"The username for the proxy server, if it exists."},password:{value:!1,type:"string",envLink:"SERVER_PROXY_PASSWORD",cliName:"proxyPassword",description:"The password for the proxy server, if it exists."},timeout:{value:5e3,type:"number",envLink:"SERVER_PROXY_TIMEOUT",cliName:"proxyTimeout",description:"The timeout for the proxy server to use, if it exists."}},rateLimiting:{enable:{value:!1,type:"boolean",envLink:"SERVER_RATE_LIMITING_ENABLE",cliName:"enableRateLimiting",description:"Enables rate limiting for the server."},maxRequests:{value:10,type:"number",envLink:"SERVER_RATE_LIMITING_MAX_REQUESTS",legacyName:"rateLimit",description:"The maximum number of requests allowed in one minute."},window:{value:1,type:"number",envLink:"SERVER_RATE_LIMITING_WINDOW",description:"The time window, in minutes, for the rate limiting."},delay:{value:0,type:"number",envLink:"SERVER_RATE_LIMITING_DELAY",description:"The delay duration for each successive request before reaching the maximum limit."},trustProxy:{value:!1,type:"boolean",envLink:"SERVER_RATE_LIMITING_TRUST_PROXY",description:"Set this to true if the server is behind a load balancer."},skipKey:{value:!1,type:"string",envLink:"SERVER_RATE_LIMITING_SKIP_KEY",description:"Allows bypassing the rate limiter and should be provided with the skipToken argument."},skipToken:{value:!1,type:"string",envLink:"SERVER_RATE_LIMITING_SKIP_TOKEN",description:"Allows bypassing the rate limiter and should be provided with the skipKey argument."}},ssl:{enable:{value:!1,type:"boolean",envLink:"SERVER_SSL_ENABLE",cliName:"enableSsl",description:"Enables or disables the SSL protocol."},force:{value:!1,type:"boolean",envLink:"SERVER_SSL_FORCE",cliName:"sslForce",legacyName:"sslOnly",description:"When set to true, the server is forced to serve only over HTTPS."},port:{value:443,type:"number",envLink:"SERVER_SSL_PORT",cliName:"sslPort",description:"The port on which to run the SSL server."},certPath:{value:!1,type:"string",envLink:"SERVER_SSL_CERT_PATH",legacyName:"sslPath",description:"The path to the SSL certificate/key file."}}},pool:{minWorkers:{value:4,type:"number",envLink:"POOL_MIN_WORKERS",description:"The number of minimum and initial pool workers to spawn."},maxWorkers:{value:8,type:"number",envLink:"POOL_MAX_WORKERS",legacyName:"workers",description:"The number of maximum pool workers to spawn."},workLimit:{value:40,type:"number",envLink:"POOL_WORK_LIMIT",description:"The number of work pieces that can be performed before restarting the worker process."},acquireTimeout:{value:5e3,type:"number",envLink:"POOL_ACQUIRE_TIMEOUT",description:"The duration, in milliseconds, to wait for acquiring a resource."},createTimeout:{value:5e3,type:"number",envLink:"POOL_CREATE_TIMEOUT",description:"The duration, in milliseconds, to wait for creating a resource."},destroyTimeout:{value:5e3,type:"number",envLink:"POOL_DESTROY_TIMEOUT",description:"The duration, in milliseconds, to wait for destroying a resource."},idleTimeout:{value:3e4,type:"number",envLink:"POOL_IDLE_TIMEOUT",description:"The duration, in milliseconds, after which an idle resource is destroyed."},createRetryInterval:{value:200,type:"number",envLink:"POOL_CREATE_RETRY_INTERVAL",description:"The duration, in milliseconds, to wait before retrying the create process in case of a failure."},reaperInterval:{value:1e3,type:"number",envLink:"POOL_REAPER_INTERVAL",description:"The duration, in milliseconds, after which the check for idle resources to destroy is triggered."},benchmarking:{value:!1,type:"boolean",envLink:"POOL_BENCHMARKING",cliName:"poolBenchmarking",description:"Indicate whether to show statistics for the pool of resources or not."}},logging:{level:{value:4,type:"number",envLink:"LOGGING_LEVEL",cliName:"logLevel",description:"The logging level to be used."},file:{value:"highcharts-export-server.log",type:"string",envLink:"LOGGING_FILE",cliName:"logFile",description:"The name of a log file. The `logToFile` and `logDest` options also need to be set to enable file logging."},dest:{value:"log/",type:"string",envLink:"LOGGING_DEST",cliName:"logDest",description:"The path to store log files. The `logToFile` option also needs to be set to enable file logging."},toConsole:{value:!0,type:"boolean",envLink:"LOGGING_TO_CONSOLE",cliName:"logToConsole",description:"Enables or disables showing logs in the console."},toFile:{value:!0,type:"boolean",envLink:"LOGGING_TO_FILE",cliName:"logToFile",description:"Enables or disables creation of the log directory and saving the log into a .log file."}},ui:{enable:{value:!1,type:"boolean",envLink:"UI_ENABLE",cliName:"enableUi",description:"Enables or disables the user interface (UI) for the export server."},route:{value:"/",type:"string",envLink:"UI_ROUTE",cliName:"uiRoute",description:"The endpoint route to which the user interface (UI) should be attached."}},other:{nodeEnv:{value:"production",type:"string",envLink:"OTHER_NODE_ENV",description:"The type of Node.js environment."},listenToProcessExits:{value:!0,type:"boolean",envLink:"OTHER_LISTEN_TO_PROCESS_EXITS",description:"Decides whether or not to attach process.exit handlers."},noLogo:{value:!1,type:"boolean",envLink:"OTHER_NO_LOGO",description:"Skip printing the logo on a startup. Will be replaced by a simple text."},hardResetPage:{value:!1,type:"boolean",envLink:"OTHER_HARD_RESET_PAGE",description:"Decides if the page content should be reset entirely."},browserShellMode:{value:!0,type:"boolean",envLink:"OTHER_BROWSER_SHELL_MODE",description:"Decides if the browser runs in the shell mode."}},debug:{enable:{value:!1,type:"boolean",envLink:"DEBUG_ENABLE",cliName:"enableDebug",description:"Enables or disables debug mode for the underlying browser."},headless:{value:!0,type:"boolean",envLink:"DEBUG_HEADLESS",description:"Controls the mode in which the browser is launched when in the debug mode."},devtools:{value:!1,type:"boolean",envLink:"DEBUG_DEVTOOLS",description:"Decides whether to enable DevTools when the browser is in a headful state."},listenToConsole:{value:!1,type:"boolean",envLink:"DEBUG_LISTEN_TO_CONSOLE",description:"Decides whether to enable a listener for console messages sent from the browser."},dumpio:{value:!1,type:"boolean",envLink:"DEBUG_DUMPIO",description:"Redirects browser process stdout and stderr to process.stdout and process.stderr."},slowMo:{value:0,type:"number",envLink:"DEBUG_SLOW_MO",description:"Slows down Puppeteer operations by the specified number of milliseconds."},debuggingPort:{value:9222,type:"number",envLink:"DEBUG_DEBUGGING_PORT",description:"Specifies the debugging port."}}},O={puppeteer:[{type:"list",name:"args",message:"Puppeteer arguments",initial:_.puppeteer.args.value.join(","),separator:","}],highcharts:[{type:"text",name:"version",message:"Highcharts version",initial:_.highcharts.version.value},{type:"text",name:"cdnURL",message:"The URL of CDN",initial:_.highcharts.cdnURL.value},{type:"multiselect",name:"coreScripts",message:"Available core scripts",instructions:"Space: Select specific, A: Select all, Enter: Confirm.",choices:_.highcharts.coreScripts.value},{type:"multiselect",name:"moduleScripts",message:"Available module scripts",instructions:"Space: Select specific, A: Select all, Enter: Confirm.",choices:_.highcharts.moduleScripts.value},{type:"multiselect",name:"indicatorScripts",message:"Available indicator scripts",instructions:"Space: Select specific, A: Select all, Enter: Confirm.",choices:_.highcharts.indicatorScripts.value},{type:"list",name:"customScripts",message:"Custom scripts",initial:_.highcharts.customScripts.value.join(","),separator:","},{type:"toggle",name:"forceFetch",message:"Force re-fetch the scripts",initial:_.highcharts.forceFetch.value},{type:"text",name:"cachePath",message:"The path to the cache directory",initial:_.highcharts.cachePath.value}],export:[{type:"select",name:"type",message:"The default export file type",hint:`Default: ${_.export.type.value}`,initial:0,choices:["png","jpeg","pdf","svg"]},{type:"select",name:"constr",message:"The default constructor for Highcharts",hint:`Default: ${_.export.constr.value}`,initial:0,choices:["chart","stockChart","mapChart","ganttChart"]},{type:"number",name:"defaultHeight",message:"The default fallback height of the exported chart",initial:_.export.defaultHeight.value},{type:"number",name:"defaultWidth",message:"The default fallback width of the exported chart",initial:_.export.defaultWidth.value},{type:"number",name:"defaultScale",message:"The default fallback scale of the exported chart",initial:_.export.defaultScale.value,min:.1,max:5},{type:"number",name:"rasterizationTimeout",message:"The rendering webpage timeout in milliseconds",initial:_.export.rasterizationTimeout.value}],customLogic:[{type:"toggle",name:"allowCodeExecution",message:"Enable execution of custom code",initial:_.customLogic.allowCodeExecution.value},{type:"toggle",name:"allowFileResources",message:"Enable file resources",initial:_.customLogic.allowFileResources.value}],server:[{type:"toggle",name:"enable",message:"Starts the server on 0.0.0.0",initial:_.server.enable.value},{type:"text",name:"host",message:"Server hostname",initial:_.server.host.value},{type:"number",name:"port",message:"Server port",initial:_.server.port.value},{type:"toggle",name:"benchmarking",message:"Enable server benchmarking",initial:_.server.benchmarking.value},{type:"text",name:"proxy.host",message:"The host of the proxy server to use",initial:_.server.proxy.host.value},{type:"number",name:"proxy.port",message:"The port of the proxy server to use",initial:_.server.proxy.port.value},{type:"number",name:"proxy.timeout",message:"The timeout for the proxy server to use",initial:_.server.proxy.timeout.value},{type:"toggle",name:"rateLimiting.enable",message:"Enable rate limiting",initial:_.server.rateLimiting.enable.value},{type:"number",name:"rateLimiting.maxRequests",message:"The maximum requests allowed per minute",initial:_.server.rateLimiting.maxRequests.value},{type:"number",name:"rateLimiting.window",message:"The rate-limiting time window in minutes",initial:_.server.rateLimiting.window.value},{type:"number",name:"rateLimiting.delay",message:"The delay for each successive request before reaching the maximum",initial:_.server.rateLimiting.delay.value},{type:"toggle",name:"rateLimiting.trustProxy",message:"Set to true if behind a load balancer",initial:_.server.rateLimiting.trustProxy.value},{type:"text",name:"rateLimiting.skipKey",message:"Allows bypassing the rate limiter when provided with the skipToken argument",initial:_.server.rateLimiting.skipKey.value},{type:"text",name:"rateLimiting.skipToken",message:"Allows bypassing the rate limiter when provided with the skipKey argument",initial:_.server.rateLimiting.skipToken.value},{type:"toggle",name:"ssl.enable",message:"Enable SSL protocol",initial:_.server.ssl.enable.value},{type:"toggle",name:"ssl.force",message:"Force serving only over HTTPS",initial:_.server.ssl.force.value},{type:"number",name:"ssl.port",message:"SSL server port",initial:_.server.ssl.port.value},{type:"text",name:"ssl.certPath",message:"The path to find the SSL certificate/key",initial:_.server.ssl.certPath.value}],pool:[{type:"number",name:"minWorkers",message:"The initial number of workers to spawn",initial:_.pool.minWorkers.value},{type:"number",name:"maxWorkers",message:"The maximum number of workers to spawn",initial:_.pool.maxWorkers.value},{type:"number",name:"workLimit",message:"The pieces of work that can be performed before restarting a Puppeteer process",initial:_.pool.workLimit.value},{type:"number",name:"acquireTimeout",message:"The number of milliseconds to wait for acquiring a resource",initial:_.pool.acquireTimeout.value},{type:"number",name:"createTimeout",message:"The number of milliseconds to wait for creating a resource",initial:_.pool.createTimeout.value},{type:"number",name:"destroyTimeout",message:"The number of milliseconds to wait for destroying a resource",initial:_.pool.destroyTimeout.value},{type:"number",name:"idleTimeout",message:"The number of milliseconds after an idle resource is destroyed",initial:_.pool.idleTimeout.value},{type:"number",name:"createRetryInterval",message:"The retry interval in milliseconds after a create process fails",initial:_.pool.createRetryInterval.value},{type:"number",name:"reaperInterval",message:"The reaper interval in milliseconds after triggering the check for idle resources to destroy",initial:_.pool.reaperInterval.value},{type:"toggle",name:"benchmarking",message:"Enable benchmarking for a resource pool",initial:_.pool.benchmarking.value}],logging:[{type:"number",name:"level",message:"The log level (0: silent, 1: error, 2: warning, 3: notice, 4: verbose, 5: benchmark)",initial:_.logging.level.value,round:0,min:0,max:5},{type:"text",name:"file",message:"A log file name. Set with --toFile and --logDest to enable file logging",initial:_.logging.file.value},{type:"text",name:"dest",message:"The path to a log file when the file logging is enabled",initial:_.logging.dest.value},{type:"toggle",name:"toConsole",message:"Enable logging to the console",initial:_.logging.toConsole.value},{type:"toggle",name:"toFile",message:"Enables logging to a file",initial:_.logging.toFile.value}],ui:[{type:"toggle",name:"enable",message:"Enable UI for the export server",initial:_.ui.enable.value},{type:"text",name:"route",message:"A route to attach the UI",initial:_.ui.route.value}],other:[{type:"text",name:"nodeEnv",message:"The type of Node.js environment",initial:_.other.nodeEnv.value},{type:"toggle",name:"listenToProcessExits",message:"Set to false to skip attaching process.exit handlers",initial:_.other.listenToProcessExits.value},{type:"toggle",name:"noLogo",message:"Skip printing the logo on startup. Replaced by simple text",initial:_.other.noLogo.value},{type:"toggle",name:"hardResetPage",message:"Decides if the page content should be reset entirely",initial:_.other.hardResetPage.value},{type:"toggle",name:"browserShellMode",message:"Decides if the browser runs in the shell mode",initial:_.other.browserShellMode.value}],debug:[{type:"toggle",name:"enable",message:"Enables debug mode for the browser instance",initial:_.debug.enable.value},{type:"toggle",name:"headless",message:"The mode setting for the browser",initial:_.debug.headless.value},{type:"toggle",name:"devtools",message:"The DevTools for the headful browser",initial:_.debug.devtools.value},{type:"toggle",name:"listenToConsole",message:"The event listener for console messages from the browser",initial:_.debug.listenToConsole.value},{type:"toggle",name:"dumpio",message:"Redirects the browser stdout and stderr to NodeJS process",initial:_.debug.dumpio.value},{type:"number",name:"slowMo",message:"Puppeteer operations slow down in milliseconds",initial:_.debug.slowMo.value},{type:"number",name:"debuggingPort",message:"The port number for debugging",initial:_.debug.debuggingPort.value}]},L=["options","globalOptions","themeOptions","resources","payload"],k={},I=(e,t="")=>{Object.keys(e).forEach(o=>{if(!["puppeteer","highcharts"].includes(o)){const r=e[o];void 0===r.value?I(r,`${t}.${o}`):(k[r.cliName||o]=`${t}.${o}`.substring(1),void 0!==r.legacyName&&(k[r.legacyName]=`${t}.${o}`.substring(1)))}})};I(_),h.config();const C=e=>u.string().transform(t=>t.split(",").map(e=>e.trim()).filter(t=>e.includes(t))).transform(e=>e.length?e:void 0),N=()=>u.enum(["true","false",""]).transform(e=>""!==e?"true"===e:void 0),A=e=>u.enum([...e,""]).transform(e=>""!==e?e:void 0),P=()=>u.string().trim().refine(e=>!["false","undefined","null","NaN"].includes(e)||""===e,e=>({message:`The string contains forbidden values, received '${e}'`})).transform(e=>""!==e?e:void 0),$=()=>u.string().trim().refine(e=>/^(\.\/|\.\.\/|\/|[a-zA-Z]:\\|[a-zA-Z]:\/)?((?:[\w-]+)[\\/]?)+$/.test(e),{},{message:"The string is an invalid path directory string."}),H=()=>u.string().trim().refine(e=>""===e||!isNaN(parseFloat(e))&&parseFloat(e)>0,e=>({message:`The value must be numeric and positive, received '${e}'`})).transform(e=>""!==e?parseFloat(e):void 0),D=()=>u.string().trim().refine(e=>""===e||!isNaN(parseFloat(e))&&parseFloat(e)>=0,e=>({message:`The value must be numeric and non-negative, received '${e}'`})).transform(e=>""!==e?parseFloat(e):void 0),G=u.object({PUPPETEER_TEMP_DIR:$(),HIGHCHARTS_VERSION:u.string().trim().refine(e=>/^(latest|\d+(\.\d+){0,2})$/.test(e)||""===e,e=>({message:`HIGHCHARTS_VERSION must be 'latest', a major version, or in the form XX.YY.ZZ, received '${e}'`})).transform(e=>""!==e?e:void 0),HIGHCHARTS_CDN_URL:u.string().trim().refine(e=>e.startsWith("https://")||e.startsWith("http://")||""===e,e=>({message:`Invalid value for HIGHCHARTS_CDN_URL. It should start with http:// or https://, received '${e}'`})).transform(e=>""!==e?e:void 0),HIGHCHARTS_CORE_SCRIPTS:C(R.core),HIGHCHARTS_MODULE_SCRIPTS:C(R.modules),HIGHCHARTS_INDICATOR_SCRIPTS:C(R.indicators),HIGHCHARTS_FORCE_FETCH:N(),HIGHCHARTS_CACHE_PATH:P(),HIGHCHARTS_ADMIN_TOKEN:P(),EXPORT_TYPE:A(["jpeg","png","pdf","svg"]),EXPORT_CONSTR:A(["chart","stockChart","mapChart","ganttChart"]),EXPORT_DEFAULT_HEIGHT:H(),EXPORT_DEFAULT_WIDTH:H(),EXPORT_DEFAULT_SCALE:H(),EXPORT_RASTERIZATION_TIMEOUT:D(),CUSTOM_LOGIC_ALLOW_CODE_EXECUTION:N(),CUSTOM_LOGIC_ALLOW_FILE_RESOURCES:N(),SERVER_ENABLE:N(),SERVER_HOST:P(),SERVER_PORT:H(),SERVER_MAX_UPLOAD_SIZE:H(),SERVER_BENCHMARKING:N(),SERVER_PROXY_HOST:P(),SERVER_PROXY_PORT:H(),SERVER_PROXY_USERNAME:P(),SERVER_PROXY_PASSWORD:P(),SERVER_PROXY_TIMEOUT:D(),SERVER_RATE_LIMITING_ENABLE:N(),SERVER_RATE_LIMITING_MAX_REQUESTS:D(),SERVER_RATE_LIMITING_WINDOW:D(),SERVER_RATE_LIMITING_DELAY:D(),SERVER_RATE_LIMITING_TRUST_PROXY:N(),SERVER_RATE_LIMITING_SKIP_KEY:P(),SERVER_RATE_LIMITING_SKIP_TOKEN:P(),SERVER_SSL_ENABLE:N(),SERVER_SSL_FORCE:N(),SERVER_SSL_PORT:H(),SERVER_SSL_CERT_PATH:P(),POOL_MIN_WORKERS:D(),POOL_MAX_WORKERS:D(),POOL_WORK_LIMIT:H(),POOL_ACQUIRE_TIMEOUT:D(),POOL_CREATE_TIMEOUT:D(),POOL_DESTROY_TIMEOUT:D(),POOL_IDLE_TIMEOUT:D(),POOL_CREATE_RETRY_INTERVAL:D(),POOL_REAPER_INTERVAL:D(),POOL_BENCHMARKING:N(),LOGGING_LEVEL:u.string().trim().refine(e=>""===e||!isNaN(parseFloat(e))&&parseFloat(e)>=0&&parseFloat(e)<=5,e=>({message:`Invalid value for LOGGING_LEVEL. We only accept values from 0 to 5 as logging levels, received '${e}'`})).transform(e=>""!==e?parseFloat(e):void 0),LOGGING_FILE:P(),LOGGING_DEST:P(),LOGGING_TO_CONSOLE:N(),LOGGING_TO_FILE:N(),UI_ENABLE:N(),UI_ROUTE:P(),OTHER_NODE_ENV:A(["development","production","test"]),OTHER_LISTEN_TO_PROCESS_EXITS:N(),OTHER_NO_LOGO:N(),OTHER_HARD_RESET_PAGE:N(),OTHER_BROWSER_SHELL_MODE:N(),OTHER_ALLOW_XLINK:N(),DEBUG_ENABLE:N(),DEBUG_HEADLESS:N(),DEBUG_DEVTOOLS:N(),DEBUG_LISTEN_TO_CONSOLE:N(),DEBUG_DUMPIO:N(),DEBUG_SLOW_MO:D(),DEBUG_DEBUGGING_PORT:H()}).partial().parse(process.env),U=["red","yellow","blue","gray","green"];let M={toConsole:!0,toFile:!1,pathCreated:!1,levelsDesc:[{title:"error",color:U[0]},{title:"warning",color:U[1]},{title:"notice",color:U[2]},{title:"verbose",color:U[3]},{title:"benchmark",color:U[4]}],listeners:[]};const j=(r,i)=>{M.pathCreated||(!e(M.dest)&&t(M.dest),M.pathCreated=!0),o(`${M.dest}${M.file}`,[i].concat(r).join(" ")+"\n",e=>{e&&(console.log(`[logger] Unable to write to log file: ${e}`),M.toFile=!1)})},F=(...e)=>{const[t,...o]=e,{levelsDesc:r,level:i}=M;if(5!==t&&(0===t||t>i||i>r.length))return;const s=`${(new Date).toString().split("(")[0].trim()} [${r[t-1].title}] -`;M.listeners.forEach(e=>{e(s,o.join(" "))}),M.toConsole&&console.log.apply(void 0,[s.toString()[M.levelsDesc[t-1].color]].concat(o)),M.toFile&&j(o,s)},V=(e,t,o)=>{const r=o||t.message,{level:i,levelsDesc:s}=M;if(0===e||e>i||i>s.length)return;const n=`${(new Date).toString().split("(")[0].trim()} [${s[e-1].title}] -`,a=t.message!==t.stackMessage||void 0===t.stackMessage?t.stack:t.stack.split("\n").slice(1).join("\n"),l=[r,"\n",a];M.toConsole&&console.log.apply(void 0,[n.toString()[M.levelsDesc[e-1].color]].concat([r[U[e-1]],"\n",a])),M.listeners.forEach(e=>{e(n,l.join(" "))}),M.toFile&&j(l,n)},W=e=>{e>=0&&e<=M.levelsDesc.length&&(M.level=e)},q=(e,t)=>{if(M={...M,dest:e||M.dest,file:t||M.file,toFile:!0},0===M.dest.length)return F(1,"[logger] File logging initialization: no path supplied.");M.dest.endsWith("/")||(M.dest+="/")},B=d(new URL("../.",import.meta.url)),X=(e,t)=>{const o=["png","jpeg","pdf","svg"];if(t){const r=t.split(".").pop();"jpg"===r?e="jpeg":o.includes(r)&&e!==r&&(e=r)}return{"image/png":"png","image/jpeg":"jpeg","application/pdf":"pdf","image/svg+xml":"svg"}[e]||o.find(t=>t===e)||"png"},K=(e=!1,t)=>{const o=["js","css","files"];let i=e,s=!1;if(t&&e.endsWith(".json"))try{i=z(r(e,"utf8"))}catch(e){return V(2,e,"[cli] No resources found.")}else i=z(e),i&&!t&&delete i.files;for(const e in i)o.includes(e)?s||(s=!0):delete i[e];return s?(i.files&&(i.files=i.files.map(e=>e.trim()),(!i.files||i.files.length<=0)&&delete i.files),i):F(3,"[cli] No resources found.")};function z(e,t){try{const o=JSON.parse("string"!=typeof e?JSON.stringify(e):e);return"string"!=typeof o&&t?JSON.stringify(o):o}catch{return!1}}const J=e=>"object"==typeof e&&!Array.isArray(e)&&null!==e,Y=e=>{if(null===e||"object"!=typeof e)return e;const t=Array.isArray(e)?[]:{};for(const o in e)Object.prototype.hasOwnProperty.call(e,o)&&(t[o]=Y(e[o]));return t},Z=(e,t)=>JSON.stringify(e,(e,o)=>("string"==typeof o&&((o=o.trim()).startsWith("function(")||o.startsWith("function ("))&&o.endsWith("}")&&(o=t?`EXP_FUN${(o+"").replaceAll(/\n|\t|\r/g," ")}EXP_FUN`:void 0),"function"==typeof o?`EXP_FUN${(o+"").replaceAll(/\n|\t|\r/g," ")}EXP_FUN`:o)).replaceAll(/"EXP_FUN|EXP_FUN"/g,"");function Q(){console.log("\nUsage of CLI arguments:".bold,"\n------",`\nFor more detailed information, visit the readme at: ${"https://github.com/highcharts/node-export-server#readme".bold.yellow}.`);const e=t=>{for(const[o,r]of Object.entries(t))if(Object.prototype.hasOwnProperty.call(r,"value")){let e=` --${r.cliName||o} ${("<"+r.type+">").green} `;if(e.length<48)for(let t=e.length;t<48;t++)e+=".";console.log(e,r.description,`[Default: ${r.value.toString().bold}]`.blue)}else e(r)};Object.keys(_).forEach(t=>{["puppeteer","highcharts"].includes(t)||(console.log(`\n${t.toUpperCase()}`.red),e(_[t]))}),console.log("\n")}const ee=e=>!["false","undefined","null","NaN","0",""].includes(e)&&!!e,te=(e,t)=>{if(e&&"string"==typeof e)return(e=e.trim()).endsWith(".js")?!!t&&te(r(e,"utf8")):e.startsWith("function()")||e.startsWith("function ()")||e.startsWith("()=>")||e.startsWith("() =>")?`(${e})()`:e.replace(/;$/,"")},oe=()=>{const e=process.hrtime.bigint();return()=>Number(process.hrtime.bigint()-e)/1e6};let re={};const ie=()=>re,se=(e,t,o=[])=>{const r=Y(e);for(const[e,i]of Object.entries(t))r[e]=J(i)&&!o.includes(e)&&void 0!==r[e]?se(r[e],i,o):void 0!==i?i:r[e];return r};function ne(e,t={},o=""){Object.keys(e).forEach(r=>{const i=e[r],s=t&&t[r];void 0===i.value?ne(i,s,`${o}.${r}`):(void 0!==s&&(i.value=s),i.envLink in G&&void 0!==G[i.envLink]&&(i.value=G[i.envLink]))})}function ae(e){let t={};for(const[o,r]of Object.entries(e))t[o]=Object.prototype.hasOwnProperty.call(r,"value")?r.value:ae(r);return t}function le(e,t,o){for(;t.length>1;){const r=t.shift();return Object.prototype.hasOwnProperty.call(e,r)||(e[r]={}),e[r]=le(Object.assign({},e[r]),t,o),e}return e[t[0]]=o,e}async function ce(e,t={}){return new Promise((o,r)=>{const i=(e=>e.startsWith("https")?m:g)(e);i.get(e,Object.assign({headers:{"User-Agent":"highcharts/export",Referer:"highcharts.export"}},t||{}),e=>{let t="";e.on("data",e=>{t+=e}),e.on("end",()=>{t||r("Nothing was fetched from the URL."),e.text=t,o(e)})}).on("error",e=>{r(e)})})}class pe extends Error{constructor(e){super(),this.message=e,this.stackMessage=e}setError(e){return this.error=e,e.name&&(this.name=e.name),e.statusCode&&(this.statusCode=e.statusCode),e.stack&&(this.stackMessage=e.message,this.stack=e.stack),this}}const he={cdnURL:"https://code.highcharts.com/",activeManifest:{},sources:"",hcVersion:""},ue=e=>e.sources.substring(0,e.sources.indexOf("*/")).replace("/*","").replace("*/","").replace(/\n/g,"").trim(),de=async(e,t,o,r=!1)=>{e.endsWith(".js")&&(e=e.substring(0,e.length-3)),F(4,`[cache] Fetching script - ${e}.js`);const i=await ce(`${e}.js`,t);if(200===i.statusCode&&"string"==typeof i.text){if(o){o[e.replace(/(.*)\/|(.*)modules\/|stock\/(.*)indicators\/|maps\/(.*)modules\//gi,"")]=1}return i.text}if(r)throw new pe(`Could not fetch the ${e}.js. The script might not exist in the requested version (status code: ${i.statusCode}).`).setError(i);return F(2,`[cache] Could not fetch the ${e}.js. The script might not exist in the requested version.`),""},ge=async(e,t,o)=>{const r=e.version,i="latest"!==r&&r?`${r}/`:"",n=e.cdnURL||he.cdnURL;F(3,`[cache] Updating cache version to Highcharts: ${i||"latest"}.`);const a={};try{return he.sources=await(async(e,t,o,r,i)=>{let s;const{host:n,port:a,username:l,password:p}=r;if(n&&a)try{s=new c({host:n,port:a,...l&&p?{username:l,password:p}:{}})}catch(e){throw new pe("[cache] Could not create a Proxy Agent.").setError(e)}const h=s?{agent:s,timeout:G.SERVER_PROXY_TIMEOUT}:{},u=[...e.map(e=>de(`${e}`,h,i,!0)),...t.map(e=>de(`${e}`,h,i)),...o.map(e=>de(`${e}`,h))];return(await Promise.all(u)).join(";\n")})([...e.coreScripts.map(e=>`${n}${i}${e}`)],[...e.moduleScripts.map(e=>"map"===e?`${n}maps/${i}modules/${e}`:`${n}${i}modules/${e}`),...e.indicatorScripts.map(e=>`${n}stock/${i}indicators/${e}`)],e.customScripts,t,a),he.hcVersion=ue(he),s(o,he.sources),a}catch(e){throw new pe("[cache] Unable to update the local Highcharts cache.").setError(e)}},me=async o=>{const{highcharts:i,server:n}=o,l=a(B,i.cachePath);let c;const p=a(l,"manifest.json"),h=a(l,"sources.js");if(!e(l)&&t(l),!e(p)||i.forceFetch)F(3,"[cache] Fetching and caching Highcharts dependencies."),c=await ge(i,n.proxy,h);else{let e=!1;const t=JSON.parse(r(p));if(t.modules&&Array.isArray(t.modules)){const e={};t.modules.forEach(t=>e[t]=1),t.modules=e}const{coreScripts:o,moduleScripts:s,indicatorScripts:a}=i,l=o.length+s.length+a.length;t.version!==i.version?(F(2,"[cache] A Highcharts version mismatch in the cache, need to re-fetch."),e=!0):Object.keys(t.modules||{}).length!==l?(F(2,"[cache] The cache and the requested modules do not match, need to re-fetch."),e=!0):e=(s||[]).some(e=>{if(!t.modules[e])return F(2,`[cache] The ${e} is missing in the cache, need to re-fetch.`),!0}),e?c=await ge(i,n.proxy,h):(F(3,"[cache] Dependency cache is up to date, proceeding."),he.sources=r(h,"utf8"),c=t.modules,he.hcVersion=ue(he))}await(async(e,t)=>{const o={version:e.version,modules:t||{}};he.activeManifest=o,F(3,"[cache] Writing a new manifest.");try{s(a(B,e.cachePath,"manifest.json"),JSON.stringify(o),"utf8")}catch(e){throw new pe("[cache] Error writing the cache manifest.").setError(e)}})(i,c)},fe=()=>he.hcVersion;function ve(){Highcharts.animObject=function(){return{duration:0}}}async function ye(e,t,o){window._displayErrors=o;const{getOptions:r,merge:i,setOptions:s,wrap:n}=Highcharts;Highcharts.setOptionsObj=i(!1,{},r());const a={animation:!1};t.export.strInj&&(a.height=e.chart.height,a.width=e.chart.width),window.isRenderComplete=!1,n(Highcharts.Chart.prototype,"init",function(e,t,o){((t=i(t,{exporting:{enabled:!1},plotOptions:{series:{label:{enabled:!1}}},tooltip:{}})).series||[]).forEach(function(e){e.animation=!1}),window.onHighchartsRender||(window.onHighchartsRender=Highcharts.addEvent(this,"render",()=>{window.isRenderComplete=!0})),e.apply(this,[t,o])}),n(Highcharts.Series.prototype,"init",function(e,t,o){e.apply(this,[t,o])});const l=t.export.strInj?new Function(`return ${t.export.strInj}`)():e;t.customLogic.customCode&&new Function("options",t.customLogic.customCode)(l);const c=i(!1,JSON.parse(t.export.themeOptions),l,{chart:a}),p=t.customLogic.callback?new Function(`return ${t.customLogic.callback}`)():void 0,h=JSON.parse(t.export.globalOptions);h&&s(h);let u=t.export.constr||"chart";u=void 0!==Highcharts[u]?u:"chart",Highcharts[u]("container",c,p);const d=r();for(const e in d)"function"!=typeof d[e]&&delete d[e];s(Highcharts.setOptionsObj),Highcharts.setOptionsObj={}}const be=r(B+"/templates/template.html","utf8");let we;async function Ee(){if(!we)return!1;const e=await we.newPage();return await e.setCacheEnabled(!1),await Se(e),function(e){const{debug:t}=ie();t.enable&&t.listenToConsole&&e.on("console",e=>{console.log(`[debug] ${e.text()}`)});e.on("pageerror",async t=>{e.isClosed()||await e.$eval("#container",(e,t)=>{window._displayErrors&&(e.innerHTML=t)},`

Chart input data error:

${t.toString()}`)})}(e),e}async function Te(e,t){try{for(const e of t)await e.dispose();await e.evaluate(()=>{if("undefined"!=typeof Highcharts){const e=Highcharts.charts;if(Array.isArray(e)&&e.length)for(const t of e)t&&t.destroy(),Highcharts.charts.shift()}const[...e]=document.getElementsByTagName("script"),[,...t]=document.getElementsByTagName("style"),[...o]=document.getElementsByTagName("link");for(const r of[...e,...t,...o])r.remove()})}catch(e){V(2,e,"[browser] Could not clear page's resources.")}}async function Se(e){await e.setContent(be,{waitUntil:"domcontentloaded"}),await e.addScriptTag({path:`${a(B,ie().highcharts.cachePath)}/sources.js`}),await e.evaluate(ve)}const xe=async(e,t,o,r)=>{o.export.instr=null,o.export.infile=null;const i=Buffer.byteLength(o.export?.strInj?o.export?.strInj:JSON.stringify(t),"utf-8");if(F(4,`[export] The current total size of data passed to a page is around ${(i/1048576).toFixed(2)} MB`),i>=104857600)throw new pe("[export] The data passed to a page exceeded 100MB.");return e.evaluate(ye,t,o,r)};var Re=async(e,t,o)=>{let i=[];try{F(4,"[export] Determining export path.");const s=o.export,a=s?.options?.chart?.displayErrors&&he.activeManifest.modules.debugger;let l;if(t.indexOf&&(t.indexOf("=0||t.indexOf("=0)){if(F(4,"[export] Treating as SVG."),"svg"===s.type)return t;l=!0,await e.setContent((e=>`\n\n\n \n \n Highcharts Export\n \n \n \n
\n ${e}\n
\n \n\n\n`)(t),{waitUntil:"domcontentloaded"})}else F(4,"[export] Treating as config."),s.strInj?await xe(e,{chart:{height:s.height,width:s.width}},o,a):(t.chart.height=s.height,t.chart.width=s.width,await xe(e,t,o,a));i=await async function(e,t){const o=[],i=t.customLogic.resources;if(i){const s=[];if(i.js&&s.push({content:i.js}),i.files)for(const e of i.files){const t=!e.startsWith("http");s.push(t?{content:r(e,"utf8")}:{url:e})}for(const t of s)try{o.push(await e.addScriptTag(t))}catch(e){V(2,e,"[export] The JS resource cannot be loaded.")}s.length=0;const a=[];if(i.css){let r=i.css.match(/@import\s*([^;]*);/g);if(r)for(let e of r)e&&(e=e.replace("url(","").replace("@import","").replace(/"/g,"").replace(/'/g,"").replace(/;/,"").replace(/\)/g,"").trim(),e.startsWith("http")?a.push({url:e}):t.customLogic.allowFileResources&&a.push({path:n.join(B,e)}));a.push({content:i.css.replace(/@import\s*([^;]*);/g,"")||" "});for(const t of a)try{o.push(await e.addStyleTag(t))}catch(e){V(2,e,"[export] The CSS resource cannot be loaded.")}a.length=0}}return o}(e,o);const c=l?await e.evaluate(e=>{const t=document.querySelector("#chart-container svg:first-of-type"),o=t.height.baseVal.value*e,r=t.width.baseVal.value*e;return document.body.style.zoom=e,document.body.style.margin="0px",{chartHeight:o,chartWidth:r}},parseFloat(s.scale)):await e.evaluate(()=>{const{chartHeight:e,chartWidth:t}=window.Highcharts.charts[0];return document.body.style.zoom=1,{chartHeight:e,chartWidth:t}}),p=Math.abs(Math.ceil(c.chartHeight||s.height)),h=Math.abs(Math.ceil(c.chartWidth||s.width)),{x:u,y:d}=await(e=>e.$eval("#chart-container",e=>{const{x:t,y:o,width:r,height:i}=e.getBoundingClientRect();return{x:t,y:o,width:r,height:Math.trunc(i>1?i:500)}}))(e);let g;if(await e.setViewport({height:p,width:h,deviceScaleFactor:l?1:parseFloat(s.scale)}),"svg"===s.type)g=await(e=>e.$eval("#container svg:first-of-type",e=>e.outerHTML))(e);else if(["png","jpeg"].includes(s.type))g=await((e,t,o,r,i)=>Promise.race([e.screenshot({type:t,encoding:o,clip:r,captureBeyondViewport:!0,fullPage:!1,optimizeForSpeed:!0,..."png"!==t?{quality:80}:{},omitBackground:"png"==t}),new Promise((e,t)=>setTimeout(()=>t(new pe("Rasterization timeout")),i||1500))]))(e,s.type,"base64",{width:h,height:p,x:u,y:d},s.rasterizationTimeout);else{if("pdf"!==s.type)throw new pe(`[export] Unsupported output format ${s.type}.`);g=await(async(e,t,o,r,i)=>(await e.emulateMediaType("screen"),e.pdf({height:t+1,width:o,encoding:r,timeout:i||1500})))(e,p,h,"base64",s.rasterizationTimeout)}return await Te(e,i),g}catch(t){return await Te(e,i),t}};let _e=!1;const Oe={performedExports:0,exportAttempts:0,exportFromSvgAttempts:0,timeSpent:0,droppedExports:0,spentAverage:0};let Le={};const ke={create:async()=>{let e=!1;const t=v(),o=(new Date).getTime();try{if(e=await Ee(),!e||e.isClosed())throw new pe("The page is invalid or closed.");F(3,`[pool] Successfully created a worker ${t} - took ${(new Date).getTime()-o} ms.`)}catch(e){throw new pe("Error encountered when creating a new page.").setError(e)}return{id:t,page:e,workCount:Math.round(Math.random()*(Le.workLimit/2))}},validate:async e=>!(!e.page||e.page?.isClosed())&&(!(Le.workLimit&&++e.workCount>Le.workLimit)||(F(3,`[pool] Worker failed validation: exceeded work limit (limit is ${Le.workLimit}).`),!1)),destroy:async e=>{F(3,`[pool] Destroying pool entry ${e.id}.`),e.page&&!e.page.isClosed()&&await e.page.close()}},Ie=async e=>{if(Le=e&&e.pool?{...e.pool}:{},await async function(e){const{puppeteer:t,debug:o,other:r}=ie(),{enable:i,...s}=o,n={headless:!r.browserShellMode||"shell",userDataDir:t.tempDir||"./tmp/",args:e,handleSIGINT:!1,handleSIGTERM:!1,handleSIGHUP:!1,waitForInitialPage:!1,defaultViewport:null,...i&&s};if(!we){const e=25;let t=0;const o=async()=>{try{F(3,`[browser] Attempting to get a browser instance (try ${++t}).`),we=await y.launch(n)}catch(r){if(V(2,r,`[browser] Failed to launch a browser instance - retrying (attempt ${t}/${e}).`),!(t<25))throw r;F(3,`[browser] Retry to open a browser (attempt ${t}/${e}).`),await new Promise(e=>setTimeout(e,4e3)),await o()}};try{await o(),"shell"===n.headless&&F(3,"[browser] Launched browser in shell mode."),i&&F(3,"[browser] Launched browser in debug mode.")}catch(e){throw new pe("[browser] Maximum retries to open a browser instance reached.").setError(e)}if(!we)throw new pe("[browser] Cannot find a browser to open.")}return we}(e.puppeteerArgs),F(3,`[pool] Initializing pool with workers: min ${Le.minWorkers}, max ${Le.maxWorkers}.`),_e)return F(4,"[pool] Already initialized, please kill it before creating a new one.");parseInt(Le.minWorkers)>parseInt(Le.maxWorkers)&&(Le.minWorkers=Le.maxWorkers);try{_e=new f({...ke,min:parseInt(Le.minWorkers),max:parseInt(Le.maxWorkers),acquireTimeoutMillis:Le.acquireTimeout,createTimeoutMillis:Le.createTimeout,destroyTimeoutMillis:Le.destroyTimeout,idleTimeoutMillis:Le.idleTimeout,createRetryIntervalMillis:Le.createRetryInterval,reapIntervalMillis:Le.reaperInterval,propagateCreateError:!1}),_e.on("release",async e=>{const t=await async function(e,t=!1){try{if(e&&!e.isClosed())return t?(await e.goto("about:blank",{waitUntil:"domcontentloaded"}),await Se(e)):await e.evaluate(()=>{document.body.innerHTML='
'}),!0}catch(e){V(2,e,"[browser] Could not clear the content of the page.")}return!1}(e.page,!1);F(4,`[pool] Releasing a worker with ID ${e.id}. Clear page status: ${t}.`)}),_e.on("destroySuccess",(e,t)=>{F(4,`[pool] Destroyed a worker with ID ${t.id}.`),t.page=null});const e=[];for(let t=0;t{_e.release(e)}),F(3,"[pool] The pool is ready"+(e.length?` with ${e.length} initial resources waiting.`:"."))}catch(e){throw new pe("[pool] Could not create the pool of workers.").setError(e)}};async function Ce(){if(F(3,"[pool] Killing pool with all workers and closing browser."),_e){for(const e of _e.used)_e.release(e.resource);_e.destroyed||(await _e.destroy(),F(4,"[browser] Destroyed the pool of resources."))}await async function(){we?.connected&&await we.close(),F(4,"[browser] Closed the browser.")}()}const Ne=async(e,t)=>{let o;try{if(F(4,"[pool] Work received, starting to process."),++Oe.exportAttempts,Le.benchmarking&&Pe(),!_e)throw new pe("Work received, but pool has not been started.");const r=oe();try{F(4,"[pool] Acquiring a worker handle."),o=await _e.acquire().promise,t.server.benchmarking&&F(5,t.payload?.requestId?`[benchmark] Request with ID ${t.payload?.requestId} -`:"[benchmark]",`Acquired a worker handle: ${r()}ms.`)}catch(e){throw new pe((t.payload?.requestId?`For request with ID ${t.payload?.requestId} - `:"")+`Error encountered when acquiring an available entry: ${r()}ms.`).setError(e)}if(F(4,"[pool] Acquired a worker handle."),!o.page)throw new pe("Resolved worker page is invalid: the pool setup is wonky.");let i=(new Date).getTime();F(4,`[pool] Starting work on pool entry with ID ${o.id}.`);const s=oe(),n=await Re(o.page,e,t);if(n instanceof Error)throw"Rasterization timeout"===n.message&&(o.workCount=Le.workLimit+1,o.page=null),"TimeoutError"===n.name||"Rasterization timeout"===n.message?new pe("Rasterization timeout: your chart may be too complex or large, and failed to render within the allotted time.").setError(n):new pe((t.payload?.requestId?`For request with ID ${t.payload?.requestId} - `:"")+`Error encountered during export: ${s()}ms.`).setError(n);t.server.benchmarking&&F(5,t.payload?.requestId?`[benchmark] Request with ID ${t.payload?.requestId} -`:"[benchmark]",`Exported a chart sucessfully: ${s()}ms.`),_e.release(o);const a=(new Date).getTime()-i;return Oe.timeSpent+=a,Oe.spentAverage=Oe.timeSpent/++Oe.performedExports,F(4,`[pool] Work completed in ${a} ms.`),{result:n,options:t}}catch(e){throw++Oe.droppedExports,o&&_e.release(o),new pe(`[pool] In pool.postWork: ${e.message}`).setError(e)}},Ae=()=>({min:_e.min,max:_e.max,all:_e.numFree()+_e.numUsed(),available:_e.numFree(),used:_e.numUsed(),pending:_e.numPendingAcquires()});function Pe(){const{min:e,max:t,all:o,available:r,used:i,pending:s}=Ae();F(5,`[pool] The minimum number of resources allowed by pool: ${e}.`),F(5,`[pool] The maximum number of resources allowed by pool: ${t}.`),F(5,`[pool] The number of all created resources: ${o}.`),F(5,`[pool] The number of available resources: ${r}.`),F(5,`[pool] The number of acquired resources: ${i}.`),F(5,`[pool] The number of resources waiting to be acquired: ${s}.`)}var $e=Ae,He=()=>Oe;let De=!1;const Ge=async(e,t)=>{F(4,"[chart] Starting the exporting process.");const o=((e,t={})=>{let o={};return e.svg?(o=Y(t),o.export.type=e.type||e.export.type,o.export.scale=e.scale||e.export.scale,o.export.outfile=e.outfile||e.export.outfile,o.payload={svg:e.svg}):o=se(t,e,L),o.export.outfile=o.export?.outfile||`chart.${o.export?.type||"png"}`,o})(e,ie()),i=o.export;if(o.payload?.svg&&""!==o.payload.svg)try{F(4,"[chart] Attempting to export from a SVG input.");const e=Fe(function(e){const t=[];G.OTHER_ALLOW_XLINK||t.push("xlink:href");const o=new b("").window;return w(o).sanitize(e,{ADD_TAGS:["foreignObject"],FORBID_ATTR:t})}(o.payload.svg),o,t);return++Oe.exportFromSvgAttempts,e}catch(e){return t(new pe("[chart] Error loading SVG input.").setError(e))}if(i.infile&&i.infile.length)try{return F(4,"[chart] Attempting to export from an input file."),o.export.instr=r(i.infile,"utf8"),Fe(o.export.instr.trim(),o,t)}catch(e){return t(new pe("[chart] Error loading input file.").setError(e))}if(i.instr&&""!==i.instr||i.options&&""!==i.options)try{return F(4,"[chart] Attempting to export from a raw input."),i.instr=i.instr||i.options,ee(o.customLogic?.allowCodeExecution)?je(o,t):"string"==typeof i.instr?Fe(i.instr.trim(),o,t):Me(o,i.instr||i.options,t)}catch(e){return t(new pe("[chart] Error loading raw input.").setError(e))}return t(new pe("[chart] No valid input specified. Check if at least one of the following parameters is correctly set: 'infile', 'instr', 'options', or 'svg'."))},Ue=e=>{const{chart:t,exporting:o}=e.export?.options||z(e.export?.instr),r=z(e.export?.globalOptions);let i=e.export?.scale||o?.scale||r?.exporting?.scale||e.export?.defaultScale||1;i=Math.max(.1,Math.min(i,5)),i=((e,t=1)=>{const o=Math.pow(10,t||0);return Math.round(+e*o)/o})(i,2);const s={height:e.export?.height||o?.sourceHeight||t?.height||r?.exporting?.sourceHeight||r?.chart?.height||e.export?.defaultHeight||400,width:e.export?.width||o?.sourceWidth||t?.width||r?.exporting?.sourceWidth||r?.chart?.width||e.export?.defaultWidth||600,scale:i};for(let[e,t]of Object.entries(s))s[e]="string"==typeof t?+t.replace(/px|%/gi,""):t;return s},Me=async(e,t,o,i)=>{let{export:s,customLogic:n}=e;const a="boolean"==typeof n.allowCodeExecution?n.allowCodeExecution:De;if(n){if(a)if("string"==typeof e.customLogic.resources)e.customLogic.resources=K(e.customLogic.resources,ee(e.customLogic.allowFileResources));else if(!e.customLogic.resources)try{const t=r("resources.json","utf8");e.customLogic.resources=K(t,ee(e.customLogic.allowFileResources))}catch(e){F(2,"[chart] Unable to load the default resources.json file.")}}else n=e.customLogic={};if(!a&&n){if(n.callback||n.resources||n.customCode)return o(new pe("[chart] The 'callback', 'resources' and 'customCode' options have been disabled for this server."));n.callback=!1,n.resources=!1,n.customCode=!1}if(t&&(t.chart=t.chart||{},t.exporting=t.exporting||{},t.exporting.enabled=!1),s.constr=s.constr||"chart",s.type=X(s.type,s.outfile),"svg"===s.type&&(s.width=!1),["globalOptions","themeOptions"].forEach(e=>{try{s&&s[e]&&("string"==typeof s[e]&&s[e].endsWith(".json")?s[e]=z(r(s[e],"utf8"),!0):s[e]=z(s[e],!0))}catch(t){s[e]={},V(2,t,`[chart] The '${e}' cannot be loaded.`)}}),n.allowCodeExecution)try{n.customCode=te(n.customCode,n.allowFileResources)}catch(e){V(2,e,"[chart] The 'customCode' cannot be loaded.")}if(n&&n.callback&&n.callback?.indexOf("{")<0)if(n.allowFileResources)try{n.callback=r(n.callback,"utf8")}catch(e){n.callback=!1,V(2,e,"[chart] The 'callback' cannot be loaded.")}else n.callback=!1;e.export={...e.export,...Ue(e)};try{return o(!1,await Ne(s.strInj||t||i,e))}catch(e){return o(e)}},je=(e,t)=>{try{let o,r=e.export.instr||e.export.options;return"string"!=typeof r&&(o=r=Z(r,e.customLogic?.allowCodeExecution)),o=r.replaceAll(/\t|\n|\r/g,"").trim(),";"===o[o.length-1]&&(o=o.substring(0,o.length-1)),e.export.strInj=o,Me(e,!1,t)}catch(o){return t(new pe(`[chart] Malformed input detected for ${e.export?.requestId||"?"}. Please make sure that your JSON/JavaScript options are sent using the "options" attribute, and that if you're using SVG, it is unescaped.`).setError(o))}},Fe=(e,t,o)=>{const{allowCodeExecution:r}=t.customLogic;if(e.indexOf("=0||e.indexOf("=0)return F(4,"[chart] Parsing input as SVG."),Me(t,!1,o,e);try{const r=JSON.parse(e.replaceAll(/\t|\n|\r/g," "));return Me(t,r,o)}catch(e){return ee(r)?je(t,o):o(new pe("[chart] Only JSON configurations and SVG are allowed for this server. If this is your server, JavaScript custom code can be enabled by starting the server with the --allowCodeExecution flag.").setError(e))}},Ve=[],We=()=>{F(4,"[server] Clearing all registered intervals.");for(const e of Ve)clearInterval(e)},qe=(e,t,o,r)=>{V(1,e),"development"!==G.OTHER_NODE_ENV&&delete e.stack,r(e)},Be=(e,t,o,r)=>{const{statusCode:i,status:s,message:n,stack:a}=e,l=i||s||400;o.status(l).json({statusCode:l,message:n,stack:a})};var Xe=(e,t)=>{const o="Too many requests, you have been rate limited. Please try again later.",r={max:t.maxRequests||30,window:t.window||1,delay:t.delay||0,trustProxy:t.trustProxy||!1,skipKey:t.skipKey||!1,skipToken:t.skipToken||!1};r.trustProxy&&e.enable("trust proxy");const i=x({windowMs:60*r.window*1e3,max:r.max,delayMs:r.delay,handler:(e,t)=>{t.format({json:()=>{t.status(429).send({message:o})},default:()=>{t.status(429).send(o)}})},skip:e=>!1!==r.skipKey&&!1!==r.skipToken&&e.query.key===r.skipKey&&e.query.access_token===r.skipToken&&(F(4,"[rate limiting] Skipping rate limiter."),!0)});e.use(i),F(3,`[rate limiting] Enabled rate limiting with ${r.max} requests per ${r.window} minute for each IP, trusting proxy: ${r.trustProxy}.`)};class Ke extends pe{constructor(e,t){super(e),this.status=this.statusCode=t}setStatus(e){return this.status=e,this}}var ze=e=>!!e&&e.post("/version/change/:newVersion",async(e,t,o)=>{try{const o=G.HIGHCHARTS_ADMIN_TOKEN;if(!o||!o.length)throw new Ke("The server is not configured to perform run-time version changes: HIGHCHARTS_ADMIN_TOKEN is not set.",401);const r=e.get("hc-auth");if(!r||r!==o)throw new Ke("Invalid or missing token: Set the token in the hc-auth header.",401);const i=e.params.newVersion;if(!i)throw new Ke("No new version supplied.",400);try{await(async e=>{const t=ie();t?.highcharts&&(t.highcharts.version=e),await me(t)})(i)}catch(e){throw new Ke(`Version change: ${e.message}`,e.statusCode).setError(e)}t.status(200).send({statusCode:200,version:fe(),message:`Successfully updated Highcharts to version: ${i}.`})}catch(e){o(e)}});const Je={png:"image/png",jpeg:"image/jpeg",gif:"image/gif",pdf:"application/pdf",svg:"image/svg+xml"};let Ye=0;const Ze=[],Qe=[],et=(e,t,o,r)=>{let i=!0;const{id:s,uniqueId:n,type:a,body:l}=r;return e.some(e=>{if(e){let r=e(t,o,s,n,a,l);return void 0!==r&&!0!==r&&(i=r),!0}}),i},tt=async(e,t,o)=>{try{const o=oe(),i=v().replace(/-/g,""),s=ie(),n=e.body,a=++Ye;let l=X(n.type);if(!n||"object"==typeof(r=n)&&!Array.isArray(r)&&null!==r&&0===Object.keys(r).length)throw new Ke("The request body is required. Please ensure that your Content-Type header is correct (accepted types are application/json and multipart/form-data).",400);let c=z(n.infile||n.options||n.data);if(!c&&!n.svg)throw F(2,`The request with ID ${i} from ${e.headers["x-forwarded-for"]||e.connection.remoteAddress} was incorrect:\n Content-Type: ${e.headers["content-type"]}. \n Chart constructor: ${n.constr}.\n Dimensions: ${n.width}x${n.height} @ ${n.scale} scale.\n Type: ${l}.\n Is SVG set? ${void 0!==n.svg}.\n B64? ${void 0!==n.b64}.\n No download? ${void 0!==n.noDownload}.\n\n Payload received: ${JSON.stringify(n.infile||n.options||n.data||n.svg)}\n\n `),new Ke("No correct chart data found. Ensure that you are using either application/json or multipart/form-data headers. If sending JSON, make sure the chart data is in the 'infile', 'options', or 'data' attribute. If sending SVG, ensure it is in the 'svg' attribute.",400);let p=!1;if(p=et(Ze,e,t,{id:a,uniqueId:i,type:l,body:n}),!0!==p)return t.send(p);let h=!1;e.socket.on("close",e=>{e&&(h=!0)}),F(4,`[export] Got an incoming HTTP request with ID ${i}.`),n.constr="string"==typeof n.constr&&n.constr||"chart";const u={export:{instr:c,type:l,constr:n.constr[0].toLowerCase()+n.constr.substr(1),height:n.height,width:n.width,scale:n.scale||s.export.scale,globalOptions:z(n.globalOptions,!0),themeOptions:z(n.themeOptions,!0)},customLogic:{allowCodeExecution:De,allowFileResources:!1,resources:z(n.resources,!0),callback:n.callback,customCode:n.customCode}};c&&(u.export.instr=Z(c,u.customLogic.allowCodeExecution));const d=se(s,u);if(d.export.options=c,d.payload={svg:n.svg||!1,b64:n.b64||!1,noDownload:n.noDownload||!1,requestId:i},n.svg&&(e=>[/xlink:href="(?:http:\/\/|https:\/\/)?localhost\b/,/xlink:href="(?:http:\/\/|https:\/\/)?10\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/,/xlink:href="(?:http:\/\/|https:\/\/)?127\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/,/xlink:href="(?:http:\/\/|https:\/\/)?172\.(1[6-9]|2[0-9]|3[0-1])\.\d{1,3}\.\d{1,3}\b/,/xlink:href="(?:http:\/\/|https:\/\/)?192\.168\.\d{1,3}\.\d{1,3}\b/].some(t=>t.test(e)))(d.payload.svg))throw new Ke("SVG potentially contain at least one forbidden URL in xlink:href element. Please review the SVG content and ensure that all referenced URLs comply with security policies.",400);await Ge(d,(r,c)=>{if(e.socket.removeAllListeners("close"),s.server.benchmarking&&F(5,`[benchmark] Request with ID ${i} - After the whole exporting process: ${o()}ms.`),h)return F(3,"[export] The client closed the connection before the chart finished processing.");if(r)throw r;if(!c||!c.result)throw new Ke(`Unexpected return from chart generation. Please check your request data. For the request with ID ${i}, the result is ${c.result}.`,400);return l=c.options.export.type,et(Qe,e,t,{id:a,body:c.result}),c.result?n.b64?"pdf"===l||"svg"==l?t.send(Buffer.from(c.result,"utf8").toString("base64")):t.send(c.result):(t.header("Content-Type",Je[l]||"image/png"),n.noDownload||t.attachment(`${e.params.filename||e.body.filename||"chart"}.${l||"png"}`),"svg"===l?t.send(c.result):t.send(Buffer.from(c.result,"base64"))):void 0})}catch(e){o(e)}var r};const ot=JSON.parse(r(a(B,"package.json"))),rt=new Date,it=[];function st(e){if(!e)return!1;var t;t=setInterval(()=>{const e=He(),t=0===e.exportAttempts?1:e.performedExports/e.exportAttempts*100;it.push(t),it.length>30&&it.shift()},6e4),Ve.push(t),e.get("/health",(e,t)=>{const o=He(),r=it.length,i=it.reduce((e,t)=>e+t,0)/it.length;F(4,"[health.js] GET /health [200] - returning server health."),t.send({status:"OK",bootTime:rt,uptime:Math.floor(((new Date).getTime()-rt.getTime())/1e3/60)+" minutes",version:ot.version,highchartsVersion:fe(),averageProcessingTime:o.spentAverage,performedExports:o.performedExports,failedExports:o.droppedExports,exportAttempts:o.exportAttempts,sucessRatio:o.performedExports/o.exportAttempts*100,pool:$e(),period:r,movingAverage:i,message:isNaN(i)||!it.length?"Too early to report. No exports made yet. Please check back soon.":`Last ${r} minutes had a success rate of ${i.toFixed(2)}%.`,svgExportAttempts:o.exportFromSvgAttempts,jsonExportAttempts:o.performedExports-o.exportFromSvgAttempts})})}const nt=new Map,at=T();at.disable("x-powered-by"),at.use(E()),at.use((e,t,o)=>{t.set("Accept-Ranges","none"),o()});const lt=e=>{e.on("clientError",(e,t)=>{V(1,e,`[server] Client error: ${e.message}, destroying socket.`),t.destroy()}),e.on("error",e=>{V(1,e,`[server] Server error: ${e.message}`)}),e.on("connection",e=>{e.on("error",e=>{V(1,e,`[server] Socket error: ${e.message}`)})})},ct=async e=>{try{const t=1024*(e.maxUploadSize||3)*1024,o=S.memoryStorage(),r=S({storage:o,limits:{fieldSize:t}});if(at.use(T.json({limit:t})),at.use(T.urlencoded({extended:!0,limit:t})),at.use(r.none()),!e.enable)return!1;if(!e.ssl.force){const t=g.createServer(at);lt(t),t.listen(e.port,e.host),nt.set(e.port,t),F(3,`[server] Started HTTP server on ${e.host}:${e.port}.`)}if(e.ssl.enable){let t,o;try{t=await i.readFile(l.join(e.ssl.certPath,"server.key"),"utf8"),o=await i.readFile(l.join(e.ssl.certPath,"server.crt"),"utf8")}catch(t){F(2,`[server] Unable to load key/certificate from the '${e.ssl.certPath}' path. Could not run secured layer server.`)}if(t&&o){const r=m.createServer({key:t,cert:o},at);lt(r),r.listen(e.ssl.port,e.host),nt.set(e.ssl.port,r),F(3,`[server] Started HTTPS server on ${e.host}:${e.ssl.port}.`)}}e.rateLimiting&&e.rateLimiting.enable&&![0,NaN].includes(e.rateLimiting.maxRequests)&&Xe(at,e.rateLimiting),at.use(T.static(l.join(B,"public"))),st(at),(e=>{e.post("/",tt),e.post("/:filename",tt)})(at),(e=>{!!e&&e.get("/",(e,t)=>{t.sendFile(a(B,"public","index.html"),{acceptRanges:!1})})})(at),ze(at),(e=>{e.use(qe),e.use(Be)})(at)}catch(e){throw new pe("[server] Could not configure and start the server.").setError(e)}},pt=()=>{F(4,"[server] Closing all servers.");for(const[e,t]of nt)t.close(()=>{nt.delete(e),F(4,`[server] Closed server on port: ${e}.`)})};var ht={startServer:ct,closeServers:pt,getServers:()=>nt,enableRateLimiting:e=>Xe(at,e),getExpress:()=>T,getApp:()=>at,use:(e,...t)=>{at.use(e,...t)},get:(e,...t)=>{at.get(e,...t)},post:(e,...t)=>{at.post(e,...t)}};const ut=async e=>{await Promise.allSettled([We(),pt(),Ce()]),process.exit(e)};var dt={server:ht,startServer:ct,initExport:async e=>{var t;return t=e.customLogic&&e.customLogic.allowCodeExecution,De=ee(t),(e=>{for(const[t,o]of Object.entries(e))M[t]=o;W(e&&parseInt(e.level)),e&&e.dest&&e.toFile&&q(e.dest,e.file||"highcharts-export-server.log")})(e.logging),e.other.listenToProcessExits&&(F(3,"[process] Attaching exit listeners to the process."),process.on("exit",e=>{F(4,`Process exited with code ${e}.`)}),process.on("SIGINT",async(e,t)=>{F(4,`The ${e} event with code: ${t}.`),await ut(0)}),process.on("SIGTERM",async(e,t)=>{F(4,`The ${e} event with code: ${t}.`),await ut(0)}),process.on("SIGHUP",async(e,t)=>{F(4,`The ${e} event with code: ${t}.`),await ut(0)}),process.on("uncaughtException",async(e,t)=>{V(1,e,`The ${t} error.`),await ut(1)})),await me(e),await Ie({pool:e.pool||{minWorkers:1,maxWorkers:1},puppeteerArgs:e.puppeteer.args||[]}),e},singleExport:async e=>{e.export.instr=e.export.instr||e.export.options,await Ge(e,async(e,t)=>{if(e)throw e;const{outfile:o,type:r}=t.options.export;s(o||`chart.${r}`,"svg"!==r?Buffer.from(t.result,"base64"):t.result),await Ce()})},batchExport:async e=>{const t=[];for(let o of e.export.batch.split(";"))o=o.split("="),2===o.length&&t.push(Ge({...e,export:{...e.export,infile:o[0],outfile:o[1]}},(e,t)=>{if(e)throw e;s(t.options.export.outfile,"svg"!==t.options.export.type?Buffer.from(t.result,"base64"):t.result)}));try{await Promise.all(t),await Ce()}catch(e){throw new pe("[chart] Error encountered during batch export.").setError(e)}},startExport:Ge,initPool:Ie,killPool:Ce,setOptions:(e,t)=>(t?.length&&(re=function(e){const t=e.findIndex(e=>"loadConfig"===e.replace(/-/g,""));if(t>-1&&e[t+1]){const o=e[t+1];try{if(o&&o.endsWith(".json"))return JSON.parse(r(o))}catch(e){V(2,e,`[config] Unable to load the configuration from the ${o} file.`)}}return{}}(t)),ne(_,re),re=ae(_),e&&(re=se(re,e,L)),t?.length&&(re=function(e,t,o){let r=!1;for(let i=0;i(n.length-1===o&&(a=e[t].type),e[t]),o),n.reduce((e,o,l)=>(n.length-1===l&&void 0!==e[o]&&(t[++i]?"boolean"===a?e[o]=ee(t[i]):"number"===a?e[o]=+t[i]:a.indexOf("]")>=0?e[o]=t[i].split(","):e[o]=t[i]:(F(2,`[config] Missing value for the '${s}' argument. Using the default value.`),r=!0)),e[o]),e)}r&&Q();return e}(re,t,_)),re),shutdownCleanUp:ut,log:F,logWithStack:V,setLogLevel:W,enableFileLogging:q,mapToNewConfig:e=>{const t={};for(const[o,r]of Object.entries(e)){const e=k[o]?k[o].split("."):[];e.reduce((t,o,i)=>t[o]=e.length-1===i?r:t[o]||{},t)}return t},manualConfig:async t=>{let o={};e(t)&&(o=JSON.parse(r(t,"utf8")));const s=Object.keys(O).map(e=>({title:`${e} options`,value:e}));return p({type:"multiselect",name:"category",message:"Which category do you want to configure?",hint:"Space: Select specific, A: Select all, Enter: Confirm.",instructions:"",choices:s},{onSubmit:async(e,r)=>{let s=0,n=[];for(const e of r)O[e]=O[e].map(t=>({...t,section:e})),n=[...n,...O[e]];return await p(n,{onSubmit:async(e,r)=>{if("moduleScripts"===e.name?(r=r.length?r.map(t=>e.choices[t]):e.choices,o[e.section][e.name]=r):o[e.section]=le(Object.assign({},o[e.section]||{}),e.name.split("."),e.choices?e.choices[r]:r),++s===n.length){try{await i.writeFile(t,JSON.stringify(o,null,2),"utf8")}catch(e){V(1,e,`[config] An error occurred while creating the ${t} file.`)}return!0}}}),!0}})},printLogo:e=>{const t=JSON.parse(r(a(B,"package.json"))).version;e?console.log(`Starting Highcharts Export Server v${t}...`):console.log(r(B+"/msg/startup.msg").toString().bold.yellow,`v${t}\n`.bold)},printUsage:Q};export{dt as default}; //# sourceMappingURL=index.esm.js.map diff --git a/dist/index.esm.js.map b/dist/index.esm.js.map index bced50bf..9acf59da 100644 --- a/dist/index.esm.js.map +++ b/dist/index.esm.js.map @@ -1 +1 @@ -{"version":3,"file":"index.esm.js","sources":["../lib/schemas/config.js","../lib/envs.js","../lib/logger.js","../lib/utils.js","../lib/config.js","../lib/fetch.js","../lib/errors/ExportError.js","../lib/cache.js","../lib/highcharts.js","../lib/browser.js","../lib/export.js","../templates/svg_export/svg_export.js","../lib/pool.js","../lib/chart.js","../lib/sanitize.js","../lib/intervals.js","../lib/server/error.js","../lib/server/rate_limit.js","../lib/errors/HttpError.js","../lib/server/routes/change_hc_version.js","../lib/server/routes/export.js","../lib/server/routes/health.js","../lib/server/server.js","../lib/server/routes/ui.js","../lib/resource_release.js","../lib/index.js"],"sourcesContent":["/*******************************************************************************\n\nHighcharts Export Server\n\nCopyright (c) 2016-2024, Highsoft\n\nLicenced under the MIT licence.\n\nAdditionally a valid Highcharts license is required for use.\n\nSee LICENSE file in root for details.\n\n*******************************************************************************/\n\n// Possible names for Highcharts scripts\nexport const scriptsNames = {\n core: ['highcharts', 'highcharts-more', 'highcharts-3d'],\n modules: [\n 'stock',\n 'map',\n 'gantt',\n 'exporting',\n 'parallel-coordinates',\n 'accessibility',\n // 'annotations-advanced',\n 'boost-canvas',\n 'boost',\n 'data',\n 'data-tools',\n 'draggable-points',\n 'static-scale',\n 'broken-axis',\n 'heatmap',\n 'tilemap',\n 'tiledwebmap',\n 'timeline',\n 'treemap',\n 'treegraph',\n 'item-series',\n 'drilldown',\n 'histogram-bellcurve',\n 'bullet',\n 'funnel',\n 'funnel3d',\n 'geoheatmap',\n 'pyramid3d',\n 'networkgraph',\n 'overlapping-datalabels',\n 'pareto',\n 'pattern-fill',\n 'pictorial',\n 'price-indicator',\n 'sankey',\n 'arc-diagram',\n 'dependency-wheel',\n 'series-label',\n 'series-on-point',\n 'solid-gauge',\n 'sonification',\n // 'stock-tools',\n 'streamgraph',\n 'sunburst',\n 'variable-pie',\n 'variwide',\n 'vector',\n 'venn',\n 'windbarb',\n 'wordcloud',\n 'xrange',\n 'no-data-to-display',\n 'drag-panes',\n 'debugger',\n 'dumbbell',\n 'lollipop',\n 'cylinder',\n 'organization',\n 'dotplot',\n 'marker-clusters',\n 'hollowcandlestick',\n 'heikinashi',\n 'flowmap',\n 'export-data',\n 'navigator',\n 'textpath'\n ],\n indicators: ['indicators-all'],\n custom: [\n 'https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.30.1/moment.min.js',\n 'https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.45/moment-timezone-with-data.min.js'\n ]\n};\n\n// This is the configuration object with all options and their default values,\n// also from the .env file if one exists\nexport const defaultConfig = {\n puppeteer: {\n args: {\n value: [\n '--allow-running-insecure-content',\n '--ash-no-nudges',\n '--autoplay-policy=user-gesture-required',\n '--block-new-web-contents',\n '--disable-accelerated-2d-canvas',\n '--disable-background-networking',\n '--disable-background-timer-throttling',\n '--disable-backgrounding-occluded-windows',\n '--disable-breakpad',\n '--disable-checker-imaging',\n '--disable-client-side-phishing-detection',\n '--disable-component-extensions-with-background-pages',\n '--disable-component-update',\n '--disable-default-apps',\n '--disable-dev-shm-usage',\n '--disable-domain-reliability',\n '--disable-extensions',\n '--disable-features=CalculateNativeWinOcclusion,InterestFeedContentSuggestions,WebOTP',\n '--disable-hang-monitor',\n '--disable-ipc-flooding-protection',\n '--disable-logging',\n '--disable-notifications',\n '--disable-offer-store-unmasked-wallet-cards',\n '--disable-popup-blocking',\n '--disable-print-preview',\n '--disable-prompt-on-repost',\n '--disable-renderer-backgrounding',\n '--disable-search-engine-choice-screen',\n '--disable-session-crashed-bubble',\n '--disable-setuid-sandbox',\n '--disable-site-isolation-trials',\n '--disable-speech-api',\n '--disable-sync',\n '--enable-unsafe-webgpu',\n '--hide-crash-restore-bubble',\n '--hide-scrollbars',\n '--metrics-recording-only',\n '--mute-audio',\n '--no-default-browser-check',\n '--no-first-run',\n '--no-pings',\n '--pipe',\n // '--no-sandbox',\n '--no-startup-window',\n // '--no-zygote',\n '--password-store=basic',\n '--process-per-tab',\n '--use-mock-keychain'\n ],\n type: 'string[]',\n description: 'Arguments array to send to Puppeteer.'\n },\n tempDir: {\n value: './tmp/',\n type: 'string',\n envLink: 'PUPPETEER_TEMP_DIR',\n description: 'The directory for Puppeteer to store temporary files.'\n }\n },\n highcharts: {\n version: {\n value: 'latest',\n type: 'string',\n envLink: 'HIGHCHARTS_VERSION',\n description: 'The Highcharts version to be used.'\n },\n cdnURL: {\n value: 'https://code.highcharts.com/',\n type: 'string',\n envLink: 'HIGHCHARTS_CDN_URL',\n description: 'The CDN URL for Highcharts scripts to be used.'\n },\n coreScripts: {\n value: scriptsNames.core,\n type: 'string[]',\n envLink: 'HIGHCHARTS_CORE_SCRIPTS',\n description: 'The core Highcharts scripts to fetch.'\n },\n moduleScripts: {\n value: scriptsNames.modules,\n type: 'string[]',\n envLink: 'HIGHCHARTS_MODULE_SCRIPTS',\n description: 'The modules of Highcharts to fetch.'\n },\n indicatorScripts: {\n value: scriptsNames.indicators,\n type: 'string[]',\n envLink: 'HIGHCHARTS_INDICATOR_SCRIPTS',\n description: 'The indicators of Highcharts to fetch.'\n },\n customScripts: {\n value: scriptsNames.custom,\n type: 'string[]',\n description: 'Additional custom scripts or dependencies to fetch.'\n },\n forceFetch: {\n value: false,\n type: 'boolean',\n envLink: 'HIGHCHARTS_FORCE_FETCH',\n description:\n 'The flag to determine whether to refetch all scripts after each server rerun.'\n },\n cachePath: {\n value: '.cache',\n type: 'string',\n envLink: 'HIGHCHARTS_CACHE_PATH',\n description:\n 'The path to the cache directory. It is used to store the Highcharts scripts and custom scripts.'\n }\n },\n export: {\n infile: {\n value: false,\n type: 'string',\n description:\n 'The input file should include a name and a type (json or svg). It must be correctly formatted as a JSON or SVG file.'\n },\n instr: {\n value: false,\n type: 'string',\n description:\n 'Input, provided in the form of a stringified JSON or SVG file, will override the --infile option.'\n },\n options: {\n value: false,\n type: 'string',\n description: 'An alias for the --instr option.'\n },\n outfile: {\n value: false,\n type: 'string',\n description:\n 'The output filename along with a type (jpeg, png, pdf, or svg). This will ignore the --type flag.'\n },\n type: {\n value: 'png',\n type: 'string',\n envLink: 'EXPORT_TYPE',\n description: 'The file export format. It can be jpeg, png, pdf, or svg.'\n },\n constr: {\n value: 'chart',\n type: 'string',\n envLink: 'EXPORT_CONSTR',\n description:\n 'The constructor to use. Can be chart, stockChart, mapChart, or ganttChart.'\n },\n defaultHeight: {\n value: 400,\n type: 'number',\n envLink: 'EXPORT_DEFAULT_HEIGHT',\n description:\n 'the default height of the exported chart. Used when no value is set.'\n },\n defaultWidth: {\n value: 600,\n type: 'number',\n envLink: 'EXPORT_DEFAULT_WIDTH',\n description:\n 'The default width of the exported chart. Used when no value is set.'\n },\n defaultScale: {\n value: 1,\n type: 'number',\n envLink: 'EXPORT_DEFAULT_SCALE',\n description:\n 'The default scale of the exported chart. Used when no value is set.'\n },\n height: {\n value: false,\n type: 'number',\n description:\n 'The height of the exported chart, overriding the option in the chart settings.'\n },\n width: {\n value: false,\n type: 'number',\n description:\n 'The width of the exported chart, overriding the option in the chart settings.'\n },\n scale: {\n value: false,\n type: 'number',\n description:\n 'The scale of the exported chart, overriding the option in the chart settings. Ranges between 0.1 and 5.0.'\n },\n globalOptions: {\n value: false,\n type: 'string',\n description:\n 'Either a stringified JSON or a filename containing options to be passed into the Highcharts.setOptions.'\n },\n themeOptions: {\n value: false,\n type: 'string',\n description:\n 'Either a stringified JSON or a filename containing theme options to be passed into the Highcharts.setOptions.'\n },\n batch: {\n value: false,\n type: 'string',\n description:\n 'Initiates a batch job with a string containing input/output pairs: \"in=out;in=out;...\".'\n },\n rasterizationTimeout: {\n value: 1500,\n type: 'number',\n envLink: 'EXPORT_RASTERIZATION_TIMEOUT',\n description:\n 'The duration in milliseconds to wait for rendering a webpage.'\n }\n },\n customLogic: {\n allowCodeExecution: {\n value: false,\n type: 'boolean',\n envLink: 'CUSTOM_LOGIC_ALLOW_CODE_EXECUTION',\n description:\n 'Controls whether the execution of arbitrary code is allowed during the exporting process.'\n },\n allowFileResources: {\n value: false,\n type: 'boolean',\n envLink: 'CUSTOM_LOGIC_ALLOW_FILE_RESOURCES',\n description:\n 'Controls the ability to inject resources from the filesystem. This setting has no effect when running as a server.'\n },\n customCode: {\n value: false,\n type: 'string',\n description:\n 'Custom code to execute before chart initialization. It can be a function, code wrapped within a function, or a filename with the .js extension.'\n },\n callback: {\n value: false,\n type: 'string',\n description:\n 'JavaScript code to run during construction. It can be a function or a filename with the .js extension.'\n },\n resources: {\n value: false,\n type: 'string',\n description:\n 'Additional resource in the form of a stringified JSON, which may contain files, js, and css sections.'\n },\n loadConfig: {\n value: false,\n type: 'string',\n legacyName: 'fromFile',\n description: 'A file containing a pre-defined configuration to use.'\n },\n createConfig: {\n value: false,\n type: 'string',\n description:\n 'Enables setting options through a prompt and saving them in a provided config file.'\n }\n },\n server: {\n maxUploadSize: {\n value: 3,\n type: 'number',\n envLink: 'SERVER_MAX_UPLOAD_SIZE',\n description: 'The maximum upload size, in MB, for the server.'\n },\n enable: {\n value: false,\n type: 'boolean',\n envLink: 'SERVER_ENABLE',\n cliName: 'enableServer',\n description:\n 'When set to true, the server starts on the local IP address 0.0.0.0.'\n },\n host: {\n value: '0.0.0.0',\n type: 'string',\n envLink: 'SERVER_HOST',\n description:\n 'The hostname of the server. Additionally, it starts a server on the provided hostname.'\n },\n port: {\n value: 7801,\n type: 'number',\n envLink: 'SERVER_PORT',\n description: 'The server port when enabled.'\n },\n benchmarking: {\n value: false,\n type: 'boolean',\n envLink: 'SERVER_BENCHMARKING',\n cliName: 'serverBenchmarking',\n description:\n 'Indicates whether to display the duration, in milliseconds, of specific actions that occur on the server while serving a request.'\n },\n proxy: {\n host: {\n value: false,\n type: 'string',\n envLink: 'SERVER_PROXY_HOST',\n cliName: 'proxyHost',\n description: 'The host of the proxy server to use, if it exists.'\n },\n port: {\n value: 8080,\n type: 'number',\n envLink: 'SERVER_PROXY_PORT',\n cliName: 'proxyPort',\n description: 'The port of the proxy server to use, if it exists.'\n },\n username: {\n value: false,\n type: 'string',\n envLink: 'SERVER_PROXY_USERNAME',\n cliName: 'proxyUsername',\n description: 'The username for the proxy server, if it exists.'\n },\n password: {\n value: false,\n type: 'string',\n envLink: 'SERVER_PROXY_PASSWORD',\n cliName: 'proxyPassword',\n description: 'The password for the proxy server, if it exists.'\n },\n timeout: {\n value: 5000,\n type: 'number',\n envLink: 'SERVER_PROXY_TIMEOUT',\n cliName: 'proxyTimeout',\n description: 'The timeout for the proxy server to use, if it exists.'\n }\n },\n rateLimiting: {\n enable: {\n value: false,\n type: 'boolean',\n envLink: 'SERVER_RATE_LIMITING_ENABLE',\n cliName: 'enableRateLimiting',\n description: 'Enables rate limiting for the server.'\n },\n maxRequests: {\n value: 10,\n type: 'number',\n envLink: 'SERVER_RATE_LIMITING_MAX_REQUESTS',\n legacyName: 'rateLimit',\n description: 'The maximum number of requests allowed in one minute.'\n },\n window: {\n value: 1,\n type: 'number',\n envLink: 'SERVER_RATE_LIMITING_WINDOW',\n description: 'The time window, in minutes, for the rate limiting.'\n },\n delay: {\n value: 0,\n type: 'number',\n envLink: 'SERVER_RATE_LIMITING_DELAY',\n description:\n 'The delay duration for each successive request before reaching the maximum limit.'\n },\n trustProxy: {\n value: false,\n type: 'boolean',\n envLink: 'SERVER_RATE_LIMITING_TRUST_PROXY',\n description: 'Set this to true if the server is behind a load balancer.'\n },\n skipKey: {\n value: false,\n type: 'string',\n envLink: 'SERVER_RATE_LIMITING_SKIP_KEY',\n description:\n 'Allows bypassing the rate limiter and should be provided with the skipToken argument.'\n },\n skipToken: {\n value: false,\n type: 'string',\n envLink: 'SERVER_RATE_LIMITING_SKIP_TOKEN',\n description:\n 'Allows bypassing the rate limiter and should be provided with the skipKey argument.'\n }\n },\n ssl: {\n enable: {\n value: false,\n type: 'boolean',\n envLink: 'SERVER_SSL_ENABLE',\n cliName: 'enableSsl',\n description: 'Enables or disables the SSL protocol.'\n },\n force: {\n value: false,\n type: 'boolean',\n envLink: 'SERVER_SSL_FORCE',\n cliName: 'sslForce',\n legacyName: 'sslOnly',\n description:\n 'When set to true, the server is forced to serve only over HTTPS.'\n },\n port: {\n value: 443,\n type: 'number',\n envLink: 'SERVER_SSL_PORT',\n cliName: 'sslPort',\n description: 'The port on which to run the SSL server.'\n },\n certPath: {\n value: false,\n type: 'string',\n envLink: 'SERVER_SSL_CERT_PATH',\n legacyName: 'sslPath',\n description: 'The path to the SSL certificate/key file.'\n }\n }\n },\n pool: {\n minWorkers: {\n value: 4,\n type: 'number',\n envLink: 'POOL_MIN_WORKERS',\n description: 'The number of minimum and initial pool workers to spawn.'\n },\n maxWorkers: {\n value: 8,\n type: 'number',\n envLink: 'POOL_MAX_WORKERS',\n legacyName: 'workers',\n description: 'The number of maximum pool workers to spawn.'\n },\n workLimit: {\n value: 40,\n type: 'number',\n envLink: 'POOL_WORK_LIMIT',\n description:\n 'The number of work pieces that can be performed before restarting the worker process.'\n },\n acquireTimeout: {\n value: 5000,\n type: 'number',\n envLink: 'POOL_ACQUIRE_TIMEOUT',\n description:\n 'The duration, in milliseconds, to wait for acquiring a resource.'\n },\n createTimeout: {\n value: 5000,\n type: 'number',\n envLink: 'POOL_CREATE_TIMEOUT',\n description:\n 'The duration, in milliseconds, to wait for creating a resource.'\n },\n destroyTimeout: {\n value: 5000,\n type: 'number',\n envLink: 'POOL_DESTROY_TIMEOUT',\n description:\n 'The duration, in milliseconds, to wait for destroying a resource.'\n },\n idleTimeout: {\n value: 30000,\n type: 'number',\n envLink: 'POOL_IDLE_TIMEOUT',\n description:\n 'The duration, in milliseconds, after which an idle resource is destroyed.'\n },\n createRetryInterval: {\n value: 200,\n type: 'number',\n envLink: 'POOL_CREATE_RETRY_INTERVAL',\n description:\n 'The duration, in milliseconds, to wait before retrying the create process in case of a failure.'\n },\n reaperInterval: {\n value: 1000,\n type: 'number',\n envLink: 'POOL_REAPER_INTERVAL',\n description:\n 'The duration, in milliseconds, after which the check for idle resources to destroy is triggered.'\n },\n benchmarking: {\n value: false,\n type: 'boolean',\n envLink: 'POOL_BENCHMARKING',\n cliName: 'poolBenchmarking',\n description:\n 'Indicate whether to show statistics for the pool of resources or not.'\n }\n },\n logging: {\n level: {\n value: 4,\n type: 'number',\n envLink: 'LOGGING_LEVEL',\n cliName: 'logLevel',\n description: 'The logging level to be used.'\n },\n file: {\n value: 'highcharts-export-server.log',\n type: 'string',\n envLink: 'LOGGING_FILE',\n cliName: 'logFile',\n description:\n 'The name of a log file. The `logToFile` and `logDest` options also need to be set to enable file logging.'\n },\n dest: {\n value: 'log/',\n type: 'string',\n envLink: 'LOGGING_DEST',\n cliName: 'logDest',\n description:\n 'The path to store log files. The `logToFile` option also needs to be set to enable file logging.'\n },\n toConsole: {\n value: true,\n type: 'boolean',\n envLink: 'LOGGING_TO_CONSOLE',\n cliName: 'logToConsole',\n description: 'Enables or disables showing logs in the console.'\n },\n toFile: {\n value: true,\n type: 'boolean',\n envLink: 'LOGGING_TO_FILE',\n cliName: 'logToFile',\n description:\n 'Enables or disables creation of the log directory and saving the log into a .log file.'\n }\n },\n ui: {\n enable: {\n value: false,\n type: 'boolean',\n envLink: 'UI_ENABLE',\n cliName: 'enableUi',\n description:\n 'Enables or disables the user interface (UI) for the export server.'\n },\n route: {\n value: '/',\n type: 'string',\n envLink: 'UI_ROUTE',\n cliName: 'uiRoute',\n description:\n 'The endpoint route to which the user interface (UI) should be attached.'\n }\n },\n other: {\n nodeEnv: {\n value: 'production',\n type: 'string',\n envLink: 'OTHER_NODE_ENV',\n description: 'The type of Node.js environment.'\n },\n listenToProcessExits: {\n value: true,\n type: 'boolean',\n envLink: 'OTHER_LISTEN_TO_PROCESS_EXITS',\n description: 'Decides whether or not to attach process.exit handlers.'\n },\n noLogo: {\n value: false,\n type: 'boolean',\n envLink: 'OTHER_NO_LOGO',\n description:\n 'Skip printing the logo on a startup. Will be replaced by a simple text.'\n },\n hardResetPage: {\n value: false,\n type: 'boolean',\n envLink: 'OTHER_HARD_RESET_PAGE',\n description: 'Decides if the page content should be reset entirely.'\n },\n browserShellMode: {\n value: true,\n type: 'boolean',\n envLink: 'OTHER_BROWSER_SHELL_MODE',\n description: 'Decides if the browser runs in the shell mode.'\n }\n },\n debug: {\n enable: {\n value: false,\n type: 'boolean',\n envLink: 'DEBUG_ENABLE',\n cliName: 'enableDebug',\n description: 'Enables or disables debug mode for the underlying browser.'\n },\n headless: {\n value: true,\n type: 'boolean',\n envLink: 'DEBUG_HEADLESS',\n description:\n 'Controls the mode in which the browser is launched when in the debug mode.'\n },\n devtools: {\n value: false,\n type: 'boolean',\n envLink: 'DEBUG_DEVTOOLS',\n description:\n 'Decides whether to enable DevTools when the browser is in a headful state.'\n },\n listenToConsole: {\n value: false,\n type: 'boolean',\n envLink: 'DEBUG_LISTEN_TO_CONSOLE',\n description:\n 'Decides whether to enable a listener for console messages sent from the browser.'\n },\n dumpio: {\n value: false,\n type: 'boolean',\n envLink: 'DEBUG_DUMPIO',\n description:\n 'Redirects browser process stdout and stderr to process.stdout and process.stderr.'\n },\n slowMo: {\n value: 0,\n type: 'number',\n envLink: 'DEBUG_SLOW_MO',\n description:\n 'Slows down Puppeteer operations by the specified number of milliseconds.'\n },\n debuggingPort: {\n value: 9222,\n type: 'number',\n envLink: 'DEBUG_DEBUGGING_PORT',\n description: 'Specifies the debugging port.'\n }\n }\n};\n\n// The config descriptions object for the prompts functionality. It contains\n// information like:\n// * Type of a prompt\n// * Name of an option\n// * Short description of a chosen option\n// * Initial value\nexport const promptsConfig = {\n puppeteer: [\n {\n type: 'list',\n name: 'args',\n message: 'Puppeteer arguments',\n initial: defaultConfig.puppeteer.args.value.join(','),\n separator: ','\n }\n ],\n highcharts: [\n {\n type: 'text',\n name: 'version',\n message: 'Highcharts version',\n initial: defaultConfig.highcharts.version.value\n },\n {\n type: 'text',\n name: 'cdnURL',\n message: 'The URL of CDN',\n initial: defaultConfig.highcharts.cdnURL.value\n },\n {\n type: 'multiselect',\n name: 'coreScripts',\n message: 'Available core scripts',\n instructions: 'Space: Select specific, A: Select all, Enter: Confirm.',\n choices: defaultConfig.highcharts.coreScripts.value\n },\n {\n type: 'multiselect',\n name: 'moduleScripts',\n message: 'Available module scripts',\n instructions: 'Space: Select specific, A: Select all, Enter: Confirm.',\n choices: defaultConfig.highcharts.moduleScripts.value\n },\n {\n type: 'multiselect',\n name: 'indicatorScripts',\n message: 'Available indicator scripts',\n instructions: 'Space: Select specific, A: Select all, Enter: Confirm.',\n choices: defaultConfig.highcharts.indicatorScripts.value\n },\n {\n type: 'list',\n name: 'customScripts',\n message: 'Custom scripts',\n initial: defaultConfig.highcharts.customScripts.value.join(','),\n separator: ','\n },\n {\n type: 'toggle',\n name: 'forceFetch',\n message: 'Force re-fetch the scripts',\n initial: defaultConfig.highcharts.forceFetch.value\n },\n {\n type: 'text',\n name: 'cachePath',\n message: 'The path to the cache directory',\n initial: defaultConfig.highcharts.cachePath.value\n }\n ],\n export: [\n {\n type: 'select',\n name: 'type',\n message: 'The default export file type',\n hint: `Default: ${defaultConfig.export.type.value}`,\n initial: 0,\n choices: ['png', 'jpeg', 'pdf', 'svg']\n },\n {\n type: 'select',\n name: 'constr',\n message: 'The default constructor for Highcharts',\n hint: `Default: ${defaultConfig.export.constr.value}`,\n initial: 0,\n choices: ['chart', 'stockChart', 'mapChart', 'ganttChart']\n },\n {\n type: 'number',\n name: 'defaultHeight',\n message: 'The default fallback height of the exported chart',\n initial: defaultConfig.export.defaultHeight.value\n },\n {\n type: 'number',\n name: 'defaultWidth',\n message: 'The default fallback width of the exported chart',\n initial: defaultConfig.export.defaultWidth.value\n },\n {\n type: 'number',\n name: 'defaultScale',\n message: 'The default fallback scale of the exported chart',\n initial: defaultConfig.export.defaultScale.value,\n min: 0.1,\n max: 5\n },\n {\n type: 'number',\n name: 'rasterizationTimeout',\n message: 'The rendering webpage timeout in milliseconds',\n initial: defaultConfig.export.rasterizationTimeout.value\n }\n ],\n customLogic: [\n {\n type: 'toggle',\n name: 'allowCodeExecution',\n message: 'Enable execution of custom code',\n initial: defaultConfig.customLogic.allowCodeExecution.value\n },\n {\n type: 'toggle',\n name: 'allowFileResources',\n message: 'Enable file resources',\n initial: defaultConfig.customLogic.allowFileResources.value\n }\n ],\n server: [\n {\n type: 'toggle',\n name: 'enable',\n message: 'Starts the server on 0.0.0.0',\n initial: defaultConfig.server.enable.value\n },\n {\n type: 'text',\n name: 'host',\n message: 'Server hostname',\n initial: defaultConfig.server.host.value\n },\n {\n type: 'number',\n name: 'port',\n message: 'Server port',\n initial: defaultConfig.server.port.value\n },\n {\n type: 'toggle',\n name: 'benchmarking',\n message: 'Enable server benchmarking',\n initial: defaultConfig.server.benchmarking.value\n },\n {\n type: 'text',\n name: 'proxy.host',\n message: 'The host of the proxy server to use',\n initial: defaultConfig.server.proxy.host.value\n },\n {\n type: 'number',\n name: 'proxy.port',\n message: 'The port of the proxy server to use',\n initial: defaultConfig.server.proxy.port.value\n },\n {\n type: 'number',\n name: 'proxy.timeout',\n message: 'The timeout for the proxy server to use',\n initial: defaultConfig.server.proxy.timeout.value\n },\n {\n type: 'toggle',\n name: 'rateLimiting.enable',\n message: 'Enable rate limiting',\n initial: defaultConfig.server.rateLimiting.enable.value\n },\n {\n type: 'number',\n name: 'rateLimiting.maxRequests',\n message: 'The maximum requests allowed per minute',\n initial: defaultConfig.server.rateLimiting.maxRequests.value\n },\n {\n type: 'number',\n name: 'rateLimiting.window',\n message: 'The rate-limiting time window in minutes',\n initial: defaultConfig.server.rateLimiting.window.value\n },\n {\n type: 'number',\n name: 'rateLimiting.delay',\n message:\n 'The delay for each successive request before reaching the maximum',\n initial: defaultConfig.server.rateLimiting.delay.value\n },\n {\n type: 'toggle',\n name: 'rateLimiting.trustProxy',\n message: 'Set to true if behind a load balancer',\n initial: defaultConfig.server.rateLimiting.trustProxy.value\n },\n {\n type: 'text',\n name: 'rateLimiting.skipKey',\n message:\n 'Allows bypassing the rate limiter when provided with the skipToken argument',\n initial: defaultConfig.server.rateLimiting.skipKey.value\n },\n {\n type: 'text',\n name: 'rateLimiting.skipToken',\n message:\n 'Allows bypassing the rate limiter when provided with the skipKey argument',\n initial: defaultConfig.server.rateLimiting.skipToken.value\n },\n {\n type: 'toggle',\n name: 'ssl.enable',\n message: 'Enable SSL protocol',\n initial: defaultConfig.server.ssl.enable.value\n },\n {\n type: 'toggle',\n name: 'ssl.force',\n message: 'Force serving only over HTTPS',\n initial: defaultConfig.server.ssl.force.value\n },\n {\n type: 'number',\n name: 'ssl.port',\n message: 'SSL server port',\n initial: defaultConfig.server.ssl.port.value\n },\n {\n type: 'text',\n name: 'ssl.certPath',\n message: 'The path to find the SSL certificate/key',\n initial: defaultConfig.server.ssl.certPath.value\n }\n ],\n pool: [\n {\n type: 'number',\n name: 'minWorkers',\n message: 'The initial number of workers to spawn',\n initial: defaultConfig.pool.minWorkers.value\n },\n {\n type: 'number',\n name: 'maxWorkers',\n message: 'The maximum number of workers to spawn',\n initial: defaultConfig.pool.maxWorkers.value\n },\n {\n type: 'number',\n name: 'workLimit',\n message:\n 'The pieces of work that can be performed before restarting a Puppeteer process',\n initial: defaultConfig.pool.workLimit.value\n },\n {\n type: 'number',\n name: 'acquireTimeout',\n message: 'The number of milliseconds to wait for acquiring a resource',\n initial: defaultConfig.pool.acquireTimeout.value\n },\n {\n type: 'number',\n name: 'createTimeout',\n message: 'The number of milliseconds to wait for creating a resource',\n initial: defaultConfig.pool.createTimeout.value\n },\n {\n type: 'number',\n name: 'destroyTimeout',\n message: 'The number of milliseconds to wait for destroying a resource',\n initial: defaultConfig.pool.destroyTimeout.value\n },\n {\n type: 'number',\n name: 'idleTimeout',\n message: 'The number of milliseconds after an idle resource is destroyed',\n initial: defaultConfig.pool.idleTimeout.value\n },\n {\n type: 'number',\n name: 'createRetryInterval',\n message:\n 'The retry interval in milliseconds after a create process fails',\n initial: defaultConfig.pool.createRetryInterval.value\n },\n {\n type: 'number',\n name: 'reaperInterval',\n message:\n 'The reaper interval in milliseconds after triggering the check for idle resources to destroy',\n initial: defaultConfig.pool.reaperInterval.value\n },\n {\n type: 'toggle',\n name: 'benchmarking',\n message: 'Enable benchmarking for a resource pool',\n initial: defaultConfig.pool.benchmarking.value\n }\n ],\n logging: [\n {\n type: 'number',\n name: 'level',\n message:\n 'The log level (0: silent, 1: error, 2: warning, 3: notice, 4: verbose, 5: benchmark)',\n initial: defaultConfig.logging.level.value,\n round: 0,\n min: 0,\n max: 5\n },\n {\n type: 'text',\n name: 'file',\n message:\n 'A log file name. Set with --toFile and --logDest to enable file logging',\n initial: defaultConfig.logging.file.value\n },\n {\n type: 'text',\n name: 'dest',\n message: 'The path to a log file when the file logging is enabled',\n initial: defaultConfig.logging.dest.value\n },\n {\n type: 'toggle',\n name: 'toConsole',\n message: 'Enable logging to the console',\n initial: defaultConfig.logging.toConsole.value\n },\n {\n type: 'toggle',\n name: 'toFile',\n message: 'Enables logging to a file',\n initial: defaultConfig.logging.toFile.value\n }\n ],\n ui: [\n {\n type: 'toggle',\n name: 'enable',\n message: 'Enable UI for the export server',\n initial: defaultConfig.ui.enable.value\n },\n {\n type: 'text',\n name: 'route',\n message: 'A route to attach the UI',\n initial: defaultConfig.ui.route.value\n }\n ],\n other: [\n {\n type: 'text',\n name: 'nodeEnv',\n message: 'The type of Node.js environment',\n initial: defaultConfig.other.nodeEnv.value\n },\n {\n type: 'toggle',\n name: 'listenToProcessExits',\n message: 'Set to false to skip attaching process.exit handlers',\n initial: defaultConfig.other.listenToProcessExits.value\n },\n {\n type: 'toggle',\n name: 'noLogo',\n message: 'Skip printing the logo on startup. Replaced by simple text',\n initial: defaultConfig.other.noLogo.value\n },\n {\n type: 'toggle',\n name: 'hardResetPage',\n message: 'Decides if the page content should be reset entirely',\n initial: defaultConfig.other.hardResetPage.value\n },\n {\n type: 'toggle',\n name: 'browserShellMode',\n message: 'Decides if the browser runs in the shell mode',\n initial: defaultConfig.other.browserShellMode.value\n }\n ],\n debug: [\n {\n type: 'toggle',\n name: 'enable',\n message: 'Enables debug mode for the browser instance',\n initial: defaultConfig.debug.enable.value\n },\n {\n type: 'toggle',\n name: 'headless',\n message: 'The mode setting for the browser',\n initial: defaultConfig.debug.headless.value\n },\n {\n type: 'toggle',\n name: 'devtools',\n message: 'The DevTools for the headful browser',\n initial: defaultConfig.debug.devtools.value\n },\n {\n type: 'toggle',\n name: 'listenToConsole',\n message: 'The event listener for console messages from the browser',\n initial: defaultConfig.debug.listenToConsole.value\n },\n {\n type: 'toggle',\n name: 'dumpio',\n message: 'Redirects the browser stdout and stderr to NodeJS process',\n initial: defaultConfig.debug.dumpio.value\n },\n {\n type: 'number',\n name: 'slowMo',\n message: 'Puppeteer operations slow down in milliseconds',\n initial: defaultConfig.debug.slowMo.value\n },\n {\n type: 'number',\n name: 'debuggingPort',\n message: 'The port number for debugging',\n initial: defaultConfig.debug.debuggingPort.value\n }\n ]\n};\n\n// Absolute props that, in case of merging recursively, need to be force merged\nexport const absoluteProps = [\n 'options',\n 'globalOptions',\n 'themeOptions',\n 'resources',\n 'payload'\n];\n\n// Argument nesting level of all export server options\nexport const nestedArgs = {};\n\n/**\n * Recursively creates a chain of nested arguments from an object.\n *\n * @param {Object} obj - The object containing nested arguments.\n * @param {string} propChain - The current chain of nested properties\n * (used internally during recursion).\n */\nconst createNestedArgs = (obj, propChain = '') => {\n Object.keys(obj).forEach((k) => {\n if (!['puppeteer', 'highcharts'].includes(k)) {\n const entry = obj[k];\n if (typeof entry.value === 'undefined') {\n // Go deeper in the nested arguments\n createNestedArgs(entry, `${propChain}.${k}`);\n } else {\n // Create the chain of nested arguments\n nestedArgs[entry.cliName || k] = `${propChain}.${k}`.substring(1);\n\n // Support for the legacy, PhantomJS properties names\n if (entry.legacyName !== undefined) {\n nestedArgs[entry.legacyName] = `${propChain}.${k}`.substring(1);\n }\n }\n }\n });\n};\n\ncreateNestedArgs(defaultConfig);\n","/**\n * @fileoverview\n * This file is responsible for parsing the environment variables with the 'zod'\n * library. The parsed environment variables are then exported to be used\n * in the application as \"envs\". We should not use process.env directly\n * in the application as these would not be parsed properly.\n *\n * The environment variables are parsed and validated only once when\n * the application starts. We should write a custom validator or a transformer\n * for each of the options.\n */\n\nimport dotenv from 'dotenv';\nimport { z } from 'zod';\n\nimport { scriptsNames } from './schemas/config.js';\n\n// Load .env into environment variables\ndotenv.config();\n\n// Object with custom validators and transformers, to avoid repetition\n// in the Config object\nconst v = {\n // Splits string value into elements in an array, trims every element, checks\n // if an array is correct, if it is empty, and if it is, returns undefined\n array: (filterArray) =>\n z\n .string()\n .transform((value) =>\n value\n .split(',')\n .map((value) => value.trim())\n .filter((value) => filterArray.includes(value))\n )\n .transform((value) => (value.length ? value : undefined)),\n\n // Allows only true, false and correctly parse the value to boolean\n // or no value in which case the returned value will be undefined\n boolean: () =>\n z\n .enum(['true', 'false', ''])\n .transform((value) => (value !== '' ? value === 'true' : undefined)),\n\n // Allows passed values or no value in which case the returned value will\n // be undefined\n enum: (values) =>\n z\n .enum([...values, ''])\n .transform((value) => (value !== '' ? value : undefined)),\n\n // Trims the string value and checks if it is empty or contains stringified\n // values such as false, undefined, null, NaN, if it does, returns undefined\n string: () =>\n z\n .string()\n .trim()\n .refine(\n (value) =>\n !['false', 'undefined', 'null', 'NaN'].includes(value) ||\n value === '',\n (value) => ({\n message: `The string contains forbidden values, received '${value}'`\n })\n )\n .transform((value) => (value !== '' ? value : undefined)),\n\n // Checks if the string is a valid path directory (path format)\n path: () =>\n z\n .string()\n .trim()\n .refine(\n (value) => {\n // Simplified regex to match both absolute and relative paths\n return /^(\\.\\/|\\.\\.\\/|\\/|[a-zA-Z]:\\\\|[a-zA-Z]:\\/)?((?:[\\w-]+)[\\\\/]?)+$/.test(\n value\n );\n },\n {},\n {\n message: 'The string is an invalid path directory string.'\n }\n ),\n\n // Allows positive numbers or no value in which case the returned value will\n // be undefined\n positiveNum: () =>\n z\n .string()\n .trim()\n .refine(\n (value) =>\n value === '' || (!isNaN(parseFloat(value)) && parseFloat(value) > 0),\n (value) => ({\n message: `The value must be numeric and positive, received '${value}'`\n })\n )\n .transform((value) => (value !== '' ? parseFloat(value) : undefined)),\n\n // Allows non-negative numbers or no value in which case the returned value\n // will be undefined\n nonNegativeNum: () =>\n z\n .string()\n .trim()\n .refine(\n (value) =>\n value === '' || (!isNaN(parseFloat(value)) && parseFloat(value) >= 0),\n (value) => ({\n message: `The value must be numeric and non-negative, received '${value}'`\n })\n )\n .transform((value) => (value !== '' ? parseFloat(value) : undefined))\n};\n\nexport const Config = z.object({\n // puppeteer\n PUPPETEER_TEMP_DIR: v.path(),\n\n // highcharts\n HIGHCHARTS_VERSION: z\n .string()\n .trim()\n .refine(\n (value) => /^(latest|\\d+(\\.\\d+){0,2})$/.test(value) || value === '',\n (value) => ({\n message: `HIGHCHARTS_VERSION must be 'latest', a major version, or in the form XX.YY.ZZ, received '${value}'`\n })\n )\n .transform((value) => (value !== '' ? value : undefined)),\n HIGHCHARTS_CDN_URL: z\n .string()\n .trim()\n .refine(\n (value) =>\n value.startsWith('https://') ||\n value.startsWith('http://') ||\n value === '',\n (value) => ({\n message: `Invalid value for HIGHCHARTS_CDN_URL. It should start with http:// or https://, received '${value}'`\n })\n )\n .transform((value) => (value !== '' ? value : undefined)),\n HIGHCHARTS_CORE_SCRIPTS: v.array(scriptsNames.core),\n HIGHCHARTS_MODULE_SCRIPTS: v.array(scriptsNames.modules),\n HIGHCHARTS_INDICATOR_SCRIPTS: v.array(scriptsNames.indicators),\n HIGHCHARTS_FORCE_FETCH: v.boolean(),\n HIGHCHARTS_CACHE_PATH: v.string(),\n HIGHCHARTS_ADMIN_TOKEN: v.string(),\n\n // export\n EXPORT_TYPE: v.enum(['jpeg', 'png', 'pdf', 'svg']),\n EXPORT_CONSTR: v.enum(['chart', 'stockChart', 'mapChart', 'ganttChart']),\n EXPORT_DEFAULT_HEIGHT: v.positiveNum(),\n EXPORT_DEFAULT_WIDTH: v.positiveNum(),\n EXPORT_DEFAULT_SCALE: v.positiveNum(),\n EXPORT_RASTERIZATION_TIMEOUT: v.nonNegativeNum(),\n\n // custom\n CUSTOM_LOGIC_ALLOW_CODE_EXECUTION: v.boolean(),\n CUSTOM_LOGIC_ALLOW_FILE_RESOURCES: v.boolean(),\n\n // server\n SERVER_ENABLE: v.boolean(),\n SERVER_HOST: v.string(),\n SERVER_PORT: v.positiveNum(),\n SERVER_MAX_UPLOAD_SIZE: v.positiveNum(),\n SERVER_BENCHMARKING: v.boolean(),\n\n // server proxy\n SERVER_PROXY_HOST: v.string(),\n SERVER_PROXY_PORT: v.positiveNum(),\n SERVER_PROXY_USERNAME: v.string(),\n SERVER_PROXY_PASSWORD: v.string(),\n SERVER_PROXY_TIMEOUT: v.nonNegativeNum(),\n\n // server rate limiting\n SERVER_RATE_LIMITING_ENABLE: v.boolean(),\n SERVER_RATE_LIMITING_MAX_REQUESTS: v.nonNegativeNum(),\n SERVER_RATE_LIMITING_WINDOW: v.nonNegativeNum(),\n SERVER_RATE_LIMITING_DELAY: v.nonNegativeNum(),\n SERVER_RATE_LIMITING_TRUST_PROXY: v.boolean(),\n SERVER_RATE_LIMITING_SKIP_KEY: v.string(),\n SERVER_RATE_LIMITING_SKIP_TOKEN: v.string(),\n\n // server ssl\n SERVER_SSL_ENABLE: v.boolean(),\n SERVER_SSL_FORCE: v.boolean(),\n SERVER_SSL_PORT: v.positiveNum(),\n SERVER_SSL_CERT_PATH: v.string(),\n\n // pool\n POOL_MIN_WORKERS: v.nonNegativeNum(),\n POOL_MAX_WORKERS: v.nonNegativeNum(),\n POOL_WORK_LIMIT: v.positiveNum(),\n POOL_ACQUIRE_TIMEOUT: v.nonNegativeNum(),\n POOL_CREATE_TIMEOUT: v.nonNegativeNum(),\n POOL_DESTROY_TIMEOUT: v.nonNegativeNum(),\n POOL_IDLE_TIMEOUT: v.nonNegativeNum(),\n POOL_CREATE_RETRY_INTERVAL: v.nonNegativeNum(),\n POOL_REAPER_INTERVAL: v.nonNegativeNum(),\n POOL_BENCHMARKING: v.boolean(),\n\n // logger\n LOGGING_LEVEL: z\n .string()\n .trim()\n .refine(\n (value) =>\n value === '' ||\n (!isNaN(parseFloat(value)) &&\n parseFloat(value) >= 0 &&\n parseFloat(value) <= 5),\n (value) => ({\n message: `Invalid value for LOGGING_LEVEL. We only accept values from 0 to 5 as logging levels, received '${value}'`\n })\n )\n .transform((value) => (value !== '' ? parseFloat(value) : undefined)),\n LOGGING_FILE: v.string(),\n LOGGING_DEST: v.string(),\n LOGGING_TO_CONSOLE: v.boolean(),\n LOGGING_TO_FILE: v.boolean(),\n\n // ui\n UI_ENABLE: v.boolean(),\n UI_ROUTE: v.string(),\n\n // other\n OTHER_NODE_ENV: v.enum(['development', 'production', 'test']),\n OTHER_LISTEN_TO_PROCESS_EXITS: v.boolean(),\n OTHER_NO_LOGO: v.boolean(),\n OTHER_HARD_RESET_PAGE: v.boolean(),\n OTHER_BROWSER_SHELL_MODE: v.boolean(),\n OTHER_ALLOW_XLINK: v.boolean(),\n\n // debugger\n DEBUG_ENABLE: v.boolean(),\n DEBUG_HEADLESS: v.boolean(),\n DEBUG_DEVTOOLS: v.boolean(),\n DEBUG_LISTEN_TO_CONSOLE: v.boolean(),\n DEBUG_DUMPIO: v.boolean(),\n DEBUG_SLOW_MO: v.nonNegativeNum(),\n DEBUG_DEBUGGING_PORT: v.positiveNum()\n});\n\nexport const envs = Config.partial().parse(process.env);\n","/*******************************************************************************\n\nHighcharts Export Server\n\nCopyright (c) 2016-2024, Highsoft\n\nLicenced under the MIT licence.\n\nAdditionally a valid Highcharts license is required for use.\n\nSee LICENSE file in root for details.\n\n*******************************************************************************/\n\nimport { appendFile, existsSync, mkdirSync } from 'fs';\n\n// The available colors\nconst colors = ['red', 'yellow', 'blue', 'gray', 'green'];\n\n// The default logging config\nlet logging = {\n // Flags for logging status\n toConsole: true,\n toFile: false,\n pathCreated: false,\n // Log levels\n levelsDesc: [\n {\n title: 'error',\n color: colors[0]\n },\n {\n title: 'warning',\n color: colors[1]\n },\n {\n title: 'notice',\n color: colors[2]\n },\n {\n title: 'verbose',\n color: colors[3]\n },\n {\n title: 'benchmark',\n color: colors[4]\n }\n ],\n // Log listeners\n listeners: []\n};\n\n/**\n * Logs the provided texts to a file, if file logging is enabled. It creates\n * the necessary directory structure if not already created and appends the\n * content, including an optional prefix, to the specified log file.\n *\n * @param {string[]} texts - An array of texts to be logged.\n * @param {string} prefix - An optional prefix to be added to each log entry.\n */\nconst logToFile = (texts, prefix) => {\n if (!logging.pathCreated) {\n // Create if does not exist\n !existsSync(logging.dest) && mkdirSync(logging.dest);\n\n // We now assume the path is available, e.g. it's the responsibility\n // of the user to create the path with the correct access rights.\n logging.pathCreated = true;\n }\n\n // Add the content to a file\n appendFile(\n `${logging.dest}${logging.file}`,\n [prefix].concat(texts).join(' ') + '\\n',\n (error) => {\n if (error) {\n console.log(`[logger] Unable to write to log file: ${error}`);\n logging.toFile = false;\n }\n }\n );\n};\n\n/**\n * Logs a message. Accepts a variable amount of arguments. Arguments after\n * `level` will be passed directly to console.log, and/or will be joined\n * and appended to the log file.\n *\n * @param {any} args - An array of arguments where the first is the log level\n * and the rest are strings to build a message with.\n */\nexport const log = (...args) => {\n const [newLevel, ...texts] = args;\n\n // Current logging options\n const { levelsDesc, level } = logging;\n\n // Check if log level is within a correct range or is a benchmark log\n if (\n newLevel !== 5 &&\n (newLevel === 0 || newLevel > level || level > levelsDesc.length)\n ) {\n return;\n }\n\n // Get rid of the GMT text information\n const newDate = new Date().toString().split('(')[0].trim();\n\n // Create a message's prefix\n const prefix = `${newDate} [${levelsDesc[newLevel - 1].title}] -`;\n\n // Call available log listeners\n logging.listeners.forEach((fn) => {\n fn(prefix, texts.join(' '));\n });\n\n // Log to console\n if (logging.toConsole) {\n console.log.apply(\n undefined,\n [prefix.toString()[logging.levelsDesc[newLevel - 1].color]].concat(texts)\n );\n }\n\n // Log to file\n if (logging.toFile) {\n logToFile(texts, prefix);\n }\n};\n\n/**\n * Logs an error message with its stack trace. Optionally, a custom message\n * can be provided.\n *\n * @param {number} level - The log level.\n * @param {Error} error - The error object.\n * @param {string} customMessage - An optional custom message to be logged along\n * with the error.\n */\nexport const logWithStack = (newLevel, error, customMessage) => {\n // Get the main message\n const mainMessage = customMessage || error.message;\n\n // Current logging options\n const { level, levelsDesc } = logging;\n\n // Check if log level is within a correct range\n if (newLevel === 0 || newLevel > level || level > levelsDesc.length) {\n return;\n }\n\n // Get rid of the GMT text information\n const newDate = new Date().toString().split('(')[0].trim();\n\n // Create a message's prefix\n const prefix = `${newDate} [${levelsDesc[newLevel - 1].title}] -`;\n\n // If the customMessage exists, we want to display the whole stack message\n const stackMessage =\n error.message !== error.stackMessage || error.stackMessage === undefined\n ? error.stack\n : error.stack.split('\\n').slice(1).join('\\n');\n\n // Combine custom message or error message with error stack message\n const texts = [mainMessage, '\\n', stackMessage];\n\n // Log to console\n if (logging.toConsole) {\n console.log.apply(\n undefined,\n [prefix.toString()[logging.levelsDesc[newLevel - 1].color]].concat([\n mainMessage[colors[newLevel - 1]],\n '\\n',\n stackMessage\n ])\n );\n }\n\n // Call available log listeners\n logging.listeners.forEach((fn) => {\n fn(prefix, texts.join(' '));\n });\n\n // Log to file\n if (logging.toFile) {\n logToFile(texts, prefix);\n }\n};\n\n/**\n * Sets the log level to the specified value. Log levels are (0 = no logging,\n * 1 = error, 2 = warning, 3 = notice, 4 = verbose or 5 = benchmark)\n *\n * @param {number} newLevel - The new log level to be set.\n */\nexport const setLogLevel = (newLevel) => {\n if (newLevel >= 0 && newLevel <= logging.levelsDesc.length) {\n logging.level = newLevel;\n }\n};\n\n/**\n * Enables file logging with the specified destination and log file.\n *\n * @param {string} logDest - The destination path for log files.\n * @param {string} logFile - The log file name.\n */\nexport const enableFileLogging = (logDest, logFile) => {\n // Update logging options\n logging = {\n ...logging,\n dest: logDest || logging.dest,\n file: logFile || logging.file,\n toFile: true\n };\n\n if (logging.dest.length === 0) {\n return log(1, '[logger] File logging initialization: no path supplied.');\n }\n\n if (!logging.dest.endsWith('/')) {\n logging.dest += '/';\n }\n};\n\n/**\n * Initializes logging with the specified logging configuration.\n *\n * @param {Object} loggingOptions - The logging configuration object.\n */\nexport const initLogging = (loggingOptions) => {\n // Set all the logging options on our logging module object\n for (const [key, value] of Object.entries(loggingOptions)) {\n logging[key] = value;\n }\n\n // Set the log level\n setLogLevel(loggingOptions && parseInt(loggingOptions.level));\n\n // Set the log file path and name\n if (loggingOptions && loggingOptions.dest && loggingOptions.toFile) {\n enableFileLogging(\n loggingOptions.dest,\n loggingOptions.file || 'highcharts-export-server.log'\n );\n }\n};\n\n/**\n * Adds a listener function to the logging system.\n *\n * @param {function} fn - The listener function to be added.\n */\nexport const listen = (fn) => {\n logging.listeners.push(fn);\n};\n\nexport default {\n log,\n logWithStack,\n setLogLevel,\n enableFileLogging,\n initLogging,\n listen\n};\n","/*******************************************************************************\n\nHighcharts Export Server\n\nCopyright (c) 2016-2024, Highsoft\n\nLicenced under the MIT licence.\n\nAdditionally a valid Highcharts license is required for use.\n\nSee LICENSE file in root for details.\n\n*******************************************************************************/\n\nimport { readFileSync } from 'fs';\nimport { join } from 'path';\nimport { fileURLToPath } from 'url';\n\nimport { defaultConfig } from '../lib/schemas/config.js';\nimport { log, logWithStack } from './logger.js';\n\nconst MAX_BACKOFF_ATTEMPTS = 6;\n\nexport const __dirname = fileURLToPath(new URL('../.', import.meta.url));\n\n/**\n * Clears and standardizes text by replacing multiple consecutive whitespace\n * characters with a single space and trimming any leading or trailing\n * whitespace.\n *\n * @param {string} text - The input text to be cleared.\n * @param {RegExp} [rule=/\\s\\s+/g] - The regular expression rule to match\n * multiple consecutive whitespace characters.\n * @param {string} [replacer=' '] - The string used to replace multiple\n * consecutive whitespace characters.\n *\n * @returns {string} - The cleared and standardized text.\n */\nexport const clearText = (text, rule = /\\s\\s+/g, replacer = ' ') =>\n text.replaceAll(rule, replacer).trim();\n\n/**\n * Implements an exponential backoff strategy for retrying a function until\n * a certain number of attempts are reached.\n *\n * @param {Function} fn - The function to be retried.\n * @param {number} [attempt=0] - The current attempt number.\n * @param {...any} args - Arguments to be passed to the function.\n *\n * @returns {Promise} - A promise that resolves to the result of the function\n * if successful.\n *\n * @throws {Error} - Throws an error if the maximum number of attempts\n * is reached.\n */\nexport const expBackoff = async (fn, attempt = 0, ...args) => {\n try {\n // Try to call the function\n return await fn(...args);\n } catch (error) {\n // Calculate delay in ms\n const delayInMs = 2 ** attempt * 1000;\n\n // If the attempt exceeds the maximum attempts of reapeat, throw an error\n if (++attempt >= MAX_BACKOFF_ATTEMPTS) {\n throw error;\n }\n\n // Wait given amount of time\n await new Promise((response) => setTimeout(response, delayInMs));\n log(\n 3,\n `[pool] Waited ${delayInMs}ms until next call for the resource id: ${args[0]}.`\n );\n\n // Try again\n return expBackoff(fn, attempt, ...args);\n }\n};\n\n/**\n * Fixes the export type based on MIME types and file extensions.\n *\n * @param {string} type - The original export type.\n * @param {string} outfile - The file path or name.\n *\n * @returns {string} - The corrected export type.\n */\nexport const fixType = (type, outfile) => {\n // MIME types\n const mimeTypes = {\n 'image/png': 'png',\n 'image/jpeg': 'jpeg',\n 'application/pdf': 'pdf',\n 'image/svg+xml': 'svg'\n };\n\n // Formats\n const formats = ['png', 'jpeg', 'pdf', 'svg'];\n\n // Check if type and outfile's extensions are the same\n if (outfile) {\n const outType = outfile.split('.').pop();\n\n if (outType === 'jpg') {\n type = 'jpeg';\n } else if (formats.includes(outType) && type !== outType) {\n type = outType;\n }\n }\n\n // Return a correct type\n return mimeTypes[type] || formats.find((t) => t === type) || 'png';\n};\n\n/**\n * Handles and validates resources for export.\n *\n * @param {Object|string} resources - The resources to be handled. Can be either\n * a JSON object, stringified JSON or a path to a JSON file.\n * @param {boolean} allowFileResources - Whether to allow loading resources from\n * files.\n *\n * @returns {Object|undefined} - The handled resources or undefined if no valid\n * resources are found.\n */\nexport const handleResources = (resources = false, allowFileResources) => {\n const allowedProps = ['js', 'css', 'files'];\n\n let handledResources = resources;\n let correctResources = false;\n\n // Try to load resources from a file\n if (allowFileResources && resources.endsWith('.json')) {\n try {\n handledResources = isCorrectJSON(readFileSync(resources, 'utf8'));\n } catch (error) {\n return logWithStack(2, error, `[cli] No resources found.`);\n }\n } else {\n // Try to get JSON\n handledResources = isCorrectJSON(resources);\n\n // Get rid of the files section\n if (handledResources && !allowFileResources) {\n delete handledResources.files;\n }\n }\n\n // Filter from unnecessary properties\n for (const propName in handledResources) {\n if (!allowedProps.includes(propName)) {\n delete handledResources[propName];\n } else if (!correctResources) {\n correctResources = true;\n }\n }\n\n // Check if at least one of allowed properties is present\n if (!correctResources) {\n return log(3, `[cli] No resources found.`);\n }\n\n // Handle files section\n if (handledResources.files) {\n handledResources.files = handledResources.files.map((item) => item.trim());\n if (!handledResources.files || handledResources.files.length <= 0) {\n delete handledResources.files;\n }\n }\n\n // Return resources\n return handledResources;\n};\n\n/**\n * Validates and parses JSON data. Checks if provided data is or can\n * be a correct JSON. If a primitive is provided, it is stringified and returned.\n *\n * @param {Object|string} data - The JSON data to be validated and parsed.\n * @param {boolean} toString - Whether to return a stringified representation\n * of the parsed JSON.\n *\n * @returns {Object|string|boolean} - The parsed JSON object, stringified JSON,\n * or false if validation fails.\n */\nexport function isCorrectJSON(data, toString) {\n try {\n // Get the string representation if not already before parsing\n const parsedData = JSON.parse(\n typeof data !== 'string' ? JSON.stringify(data) : data\n );\n\n // Return a stringified representation of a JSON if required\n if (typeof parsedData !== 'string' && toString) {\n return JSON.stringify(parsedData);\n }\n\n // Return a JSON\n return parsedData;\n } catch {\n return false;\n }\n}\n\n/**\n * Checks if the given item is an object.\n *\n * @param {any} item - The item to be checked.\n *\n * @returns {boolean} - True if the item is an object, false otherwise.\n */\nexport const isObject = (item) =>\n typeof item === 'object' && !Array.isArray(item) && item !== null;\n\n/**\n * Checks if the given object is empty.\n *\n * @param {Object} item - The object to be checked.\n *\n * @returns {boolean} - True if the object is empty, false otherwise.\n */\nexport const isObjectEmpty = (item) =>\n typeof item === 'object' &&\n !Array.isArray(item) &&\n item !== null &&\n Object.keys(item).length === 0;\n\n/**\n * Checks if a private IP range URL is found in the given string.\n *\n * @param {string} item - The string to be checked for a private IP range URL.\n *\n * @returns {boolean} - True if a private IP range URL is found, false\n * otherwise.\n */\nexport const isPrivateRangeUrlFound = (item) => {\n const regexPatterns = [\n /xlink:href=\"(?:http:\\/\\/|https:\\/\\/)?localhost\\b/,\n /xlink:href=\"(?:http:\\/\\/|https:\\/\\/)?10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b/,\n /xlink:href=\"(?:http:\\/\\/|https:\\/\\/)?127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b/,\n /xlink:href=\"(?:http:\\/\\/|https:\\/\\/)?172\\.(1[6-9]|2[0-9]|3[0-1])\\.\\d{1,3}\\.\\d{1,3}\\b/,\n /xlink:href=\"(?:http:\\/\\/|https:\\/\\/)?192\\.168\\.\\d{1,3}\\.\\d{1,3}\\b/\n ];\n\n return regexPatterns.some((pattern) => pattern.test(item));\n};\n\n/**\n * Creates a deep copy of the given object or array.\n *\n * @param {Object|Array} obj - The object or array to be deeply copied.\n *\n * @returns {Object|Array} - The deep copy of the provided object or array.\n */\nexport const deepCopy = (obj) => {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n\n const copy = Array.isArray(obj) ? [] : {};\n\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n copy[key] = deepCopy(obj[key]);\n }\n }\n\n return copy;\n};\n\n/**\n * Converts the provided options object to a JSON-formatted string with the\n * option to preserve functions.\n *\n * @param {Object} options - The options object to be converted to a string.\n * @param {boolean} allowFunctions - If set to true, functions are preserved\n * in the output.\n *\n * @returns {string} - The JSON-formatted string representing the options.\n */\nexport const optionsStringify = (options, allowFunctions) => {\n const replacerCallback = (name, value) => {\n if (typeof value === 'string') {\n value = value.trim();\n\n // If allowFunctions is set to true, preserve functions\n if (\n (value.startsWith('function(') || value.startsWith('function (')) &&\n value.endsWith('}')\n ) {\n value = allowFunctions\n ? `EXP_FUN${(value + '').replaceAll(/\\n|\\t|\\r/g, ' ')}EXP_FUN`\n : undefined;\n }\n }\n\n return typeof value === 'function'\n ? `EXP_FUN${(value + '').replaceAll(/\\n|\\t|\\r/g, ' ')}EXP_FUN`\n : value;\n };\n\n // Stringify options and if required, replace special functions marks\n return JSON.stringify(options, replacerCallback).replaceAll(\n /\"EXP_FUN|EXP_FUN\"/g,\n ''\n );\n};\n\n/**\n * Prints the Highcharts Export Server logo and version information.\n *\n * @param {boolean} noLogo - If true, only prints version information without\n * the logo.\n */\nexport const printLogo = (noLogo) => {\n // Get package version either from env or from package.json\n const packageVersion = JSON.parse(\n readFileSync(join(__dirname, 'package.json'))\n ).version;\n\n // Print text only\n if (noLogo) {\n console.log(`Starting Highcharts Export Server v${packageVersion}...`);\n return;\n }\n\n // Print the logo\n console.log(\n readFileSync(__dirname + '/msg/startup.msg').toString().bold.yellow,\n `v${packageVersion}\\n`.bold\n );\n};\n\n/**\n * Prints the usage information for CLI arguments. If required, it can list\n * properties recursively\n */\nexport function printUsage() {\n const pad = 48;\n const readme = 'https://github.com/highcharts/node-export-server#readme';\n\n // Display readme information\n console.log(\n '\\nUsage of CLI arguments:'.bold,\n '\\n------',\n `\\nFor more detailed information, visit the readme at: ${readme.bold.yellow}.`\n );\n\n const cycleCategories = (options) => {\n for (const [name, option] of Object.entries(options)) {\n // If category has more levels, go further\n if (!Object.prototype.hasOwnProperty.call(option, 'value')) {\n cycleCategories(option);\n } else {\n let descName = ` --${option.cliName || name} ${\n ('<' + option.type + '>').green\n } `;\n if (descName.length < pad) {\n for (let i = descName.length; i < pad; i++) {\n descName += '.';\n }\n }\n\n // Display correctly aligned messages\n console.log(\n descName,\n option.description,\n `[Default: ${option.value.toString().bold}]`.blue\n );\n }\n }\n };\n\n // Cycle through options of each categories and display the usage info\n Object.keys(defaultConfig).forEach((category) => {\n // Only puppeteer and highcharts categories cannot be configured through CLI\n if (!['puppeteer', 'highcharts'].includes(category)) {\n console.log(`\\n${category.toUpperCase()}`.red);\n cycleCategories(defaultConfig[category]);\n }\n });\n console.log('\\n');\n}\n\n/**\n * Rounds a number to the specified precision.\n *\n * @param {number} value - The number to be rounded.\n * @param {number} precision - The number of decimal places to round to.\n *\n * @returns {number} - The rounded number.\n */\nexport const roundNumber = (value, precision = 1) => {\n const multiplier = Math.pow(10, precision || 0);\n return Math.round(+value * multiplier) / multiplier;\n};\n\n/**\n * Converts a value to a boolean.\n *\n * @param {any} item - The value to be converted to a boolean.\n *\n * @returns {boolean} - The boolean representation of the input value.\n */\nexport const toBoolean = (item) =>\n ['false', 'undefined', 'null', 'NaN', '0', ''].includes(item)\n ? false\n : !!item;\n\n/**\n * Wraps custom code to execute it safely.\n *\n * @param {string} customCode - The custom code to be wrapped.\n * @param {boolean} allowFileResources - Flag to allow loading code from a file.\n *\n * @returns {string|boolean} - The wrapped custom code or false if wrapping\n * fails.\n */\nexport const wrapAround = (customCode, allowFileResources) => {\n if (customCode && typeof customCode === 'string') {\n customCode = customCode.trim();\n\n if (customCode.endsWith('.js')) {\n return allowFileResources\n ? wrapAround(readFileSync(customCode, 'utf8'))\n : false;\n } else if (\n customCode.startsWith('function()') ||\n customCode.startsWith('function ()') ||\n customCode.startsWith('()=>') ||\n customCode.startsWith('() =>')\n ) {\n return `(${customCode})()`;\n }\n return customCode.replace(/;$/, '');\n }\n};\n\n/**\n * Utility to measure elapsed time using the Node.js process.hrtime() method.\n *\n * @returns {function(): number} - A function to calculate the elapsed time\n * in milliseconds.\n */\nexport const measureTime = () => {\n const start = process.hrtime.bigint();\n return () => Number(process.hrtime.bigint() - start) / 1000000;\n};\n\nexport default {\n __dirname,\n clearText,\n expBackoff,\n fixType,\n handleResources,\n isCorrectJSON,\n isObject,\n isObjectEmpty,\n isPrivateRangeUrlFound,\n optionsStringify,\n printLogo,\n printUsage,\n roundNumber,\n toBoolean,\n wrapAround,\n measureTime\n};\n","/*******************************************************************************\n\nHighcharts Export Server\n\nCopyright (c) 2016-2024, Highsoft\n\nLicenced under the MIT licence.\n\nAdditionally a valid Highcharts license is required for use.\n\nSee LICENSE file in root for details.\n\n*******************************************************************************/\n\nimport { existsSync, readFileSync, promises as fsPromises } from 'fs';\n\nimport prompts from 'prompts';\n\nimport {\n absoluteProps,\n defaultConfig,\n nestedArgs,\n promptsConfig\n} from './schemas/config.js';\nimport { envs } from './envs.js';\nimport { log, logWithStack } from './logger.js';\nimport { deepCopy, isObject, printUsage, toBoolean } from './utils.js';\n\nlet generalOptions = {};\n\n/**\n * Retrieves and returns the general options for the export process.\n *\n * @returns {Object} The general options object.\n */\nexport const getOptions = () => generalOptions;\n\n/**\n * Initializes and sets the general options for the server instace, keeping\n * the principle of the options load priority. It accepts optional userOptions\n * and args from the CLI.\n *\n * @param {Object} userOptions - User-provided options for customization.\n * @param {Array} args - Command-line arguments for additional configuration\n * (CLI usage).\n *\n * @returns {Object} The updated general options object.\n */\nexport const setOptions = (userOptions, args) => {\n // Only for the CLI usage\n if (args?.length) {\n // Get the additional options from the custom JSON file\n generalOptions = loadConfigFile(args);\n }\n\n // Update the default config with a correct option values\n updateDefaultConfig(defaultConfig, generalOptions);\n\n // Set values for server's options and returns them\n generalOptions = initOptions(defaultConfig);\n\n // Apply user options if there are any\n if (userOptions) {\n // Merge user options\n generalOptions = mergeConfigOptions(\n generalOptions,\n userOptions,\n absoluteProps\n );\n }\n\n // Only for the CLI usage\n if (args?.length) {\n // Pair provided arguments\n generalOptions = pairArgumentValue(generalOptions, args, defaultConfig);\n }\n\n // Return final general options\n return generalOptions;\n};\n\n/**\n * Allows manual configuration based on specified prompts and saves\n * the configuration to a file.\n *\n * @param {string} configFileName - The name of the configuration file.\n *\n * @returns {Promise} A Promise that resolves to true once the manual\n * configuration is completed and saved.\n */\nexport const manualConfig = async (configFileName) => {\n // Prepare a config object\n let configFile = {};\n\n // Check if provided config file exists\n if (existsSync(configFileName)) {\n configFile = JSON.parse(readFileSync(configFileName, 'utf8'));\n }\n\n // Question about a configuration category\n const onSubmit = async (p, categories) => {\n let questionsCounter = 0;\n let allQuestions = [];\n\n // Create a corresponding property in the manualConfig object\n for (const section of categories) {\n // Mark each option with a section\n promptsConfig[section] = promptsConfig[section].map((option) => ({\n ...option,\n section\n }));\n\n // Collect the questions\n allQuestions = [...allQuestions, ...promptsConfig[section]];\n }\n\n await prompts(allQuestions, {\n onSubmit: async (prompt, answer) => {\n // Get the default module scripts\n if (prompt.name === 'moduleScripts') {\n answer = answer.length\n ? answer.map((module) => prompt.choices[module])\n : prompt.choices;\n\n configFile[prompt.section][prompt.name] = answer;\n } else {\n configFile[prompt.section] = recursiveProps(\n Object.assign({}, configFile[prompt.section] || {}),\n prompt.name.split('.'),\n prompt.choices ? prompt.choices[answer] : answer\n );\n }\n\n if (++questionsCounter === allQuestions.length) {\n try {\n await fsPromises.writeFile(\n configFileName,\n JSON.stringify(configFile, null, 2),\n 'utf8'\n );\n } catch (error) {\n logWithStack(\n 1,\n error,\n `[config] An error occurred while creating the ${configFileName} file.`\n );\n }\n return true;\n }\n }\n });\n\n return true;\n };\n\n // Find the categories\n const choices = Object.keys(promptsConfig).map((choice) => ({\n title: `${choice} options`,\n value: choice\n }));\n\n // Category prompt\n return prompts(\n {\n type: 'multiselect',\n name: 'category',\n message: 'Which category do you want to configure?',\n hint: 'Space: Select specific, A: Select all, Enter: Confirm.',\n instructions: '',\n choices\n },\n { onSubmit }\n );\n};\n\n/**\n * Maps old-structured (PhantomJS) options to a new configuration format\n * (Puppeteer).\n *\n * @param {Object} oldOptions - Old-structured options to be mapped.\n *\n * @returns {Object} New options structured based on the defined nestedArgs\n * mapping.\n */\nexport const mapToNewConfig = (oldOptions) => {\n const newOptions = {};\n // Cycle through old-structured options\n for (const [key, value] of Object.entries(oldOptions)) {\n const propertiesChain = nestedArgs[key] ? nestedArgs[key].split('.') : [];\n\n // Populate object in correct properties levels\n propertiesChain.reduce(\n (obj, prop, index) =>\n (obj[prop] =\n propertiesChain.length - 1 === index ? value : obj[prop] || {}),\n newOptions\n );\n }\n return newOptions;\n};\n\n/**\n * Merges two sets of configuration options, considering absolute properties.\n *\n * @param {Object} options - Original configuration options.\n * @param {Object} newOptions - New configuration options to be merged.\n * @param {Array} absoluteProps - List of properties that should\n * not be recursively merged.\n *\n * @returns {Object} Merged configuration options.\n */\nexport const mergeConfigOptions = (options, newOptions, absoluteProps = []) => {\n const mergedOptions = deepCopy(options);\n\n for (const [key, value] of Object.entries(newOptions)) {\n mergedOptions[key] =\n isObject(value) &&\n !absoluteProps.includes(key) &&\n mergedOptions[key] !== undefined\n ? mergeConfigOptions(mergedOptions[key], value, absoluteProps)\n : value !== undefined\n ? value\n : mergedOptions[key];\n }\n\n return mergedOptions;\n};\n\n/**\n * Initializes export settings based on provided exportOptions\n * and generalOptions.\n *\n * @param {Object} exportOptions - Options specific to the export process.\n * @param {Object} generalOptions - General configuration options.\n *\n * @returns {Object} Initialized export settings.\n */\nexport const initExportSettings = (exportOptions, generalOptions = {}) => {\n let options = {};\n\n if (exportOptions.svg) {\n options = deepCopy(generalOptions);\n options.export.type = exportOptions.type || exportOptions.export.type;\n options.export.scale = exportOptions.scale || exportOptions.export.scale;\n options.export.outfile =\n exportOptions.outfile || exportOptions.export.outfile;\n options.payload = {\n svg: exportOptions.svg\n };\n } else {\n options = mergeConfigOptions(\n generalOptions,\n exportOptions,\n // Omit going down recursively with the belows\n absoluteProps\n );\n }\n\n options.export.outfile =\n options.export?.outfile || `chart.${options.export?.type || 'png'}`;\n return options;\n};\n\n/**\n * Loads additional configuration from a specified file using\n * the --loadConfig option.\n *\n * @param {Array} args - Command-line arguments to check for\n * the --loadConfig option.\n *\n * @returns {Object} Additional configuration loaded from the specified file,\n * or an empty object if not found or invalid.\n */\nfunction loadConfigFile(args) {\n // Check if the --loadConfig option was used\n const configIndex = args.findIndex(\n (arg) => arg.replace(/-/g, '') === 'loadConfig'\n );\n\n // Check if the --loadConfig has a value\n if (configIndex > -1 && args[configIndex + 1]) {\n const fileName = args[configIndex + 1];\n try {\n // Check if an additional config file is a correct JSON file\n if (fileName && fileName.endsWith('.json')) {\n // Load an optional custom JSON config file\n return JSON.parse(readFileSync(fileName));\n }\n } catch (error) {\n logWithStack(\n 2,\n error,\n `[config] Unable to load the configuration from the ${fileName} file.`\n );\n }\n }\n\n // No additional options to return\n return {};\n}\n\n/**\n * Updates the default configuration object with values from a custom object\n * and environment variables.\n *\n * @param {Object} configObj - The default configuration object.\n * @param {Object} customObj - Custom configuration object to override defaults.\n * @param {string} propChain - Property chain for tracking nested properties\n * during recursion.\n */\nfunction updateDefaultConfig(configObj, customObj = {}, propChain = '') {\n Object.keys(configObj).forEach((key) => {\n const entry = configObj[key];\n const customValue = customObj && customObj[key];\n\n if (typeof entry.value === 'undefined') {\n updateDefaultConfig(entry, customValue, `${propChain}.${key}`);\n } else {\n // If a value from a custom JSON exists, it take precedence\n if (customValue !== undefined) {\n entry.value = customValue;\n }\n\n // If a value from an env variable exists, it take precedence\n if (entry.envLink in envs && envs[entry.envLink] !== undefined) {\n entry.value = envs[entry.envLink];\n }\n }\n });\n}\n\n/**\n * Initializes options object based on provided items, setting values from\n * nested properties recursively.\n *\n * @param {Object} items - Configuration items to be used for initializing\n * options.\n *\n * @returns {Object} Initialized options object.\n */\nfunction initOptions(items) {\n let options = {};\n for (const [name, item] of Object.entries(items)) {\n options[name] = Object.prototype.hasOwnProperty.call(item, 'value')\n ? item.value\n : initOptions(item);\n }\n return options;\n}\n\n/**\n * Pairs argument values with corresponding options in the configuration,\n * updating the options object.\n *\n * @param {Object} options - Configuration options object to be updated.\n * @param {Array} args - Command-line arguments containing values for specific\n * options.\n * @param {Object} defaultConfig - Default configuration object for reference.\n *\n * @returns {Object} Updated options object.\n */\nfunction pairArgumentValue(options, args, defaultConfig) {\n let showUsage = false;\n for (let i = 0; i < args.length; i++) {\n const option = args[i].replace(/-/g, '');\n\n // Find the right place for property's value\n const propertiesChain = nestedArgs[option]\n ? nestedArgs[option].split('.')\n : [];\n\n // Get the correct type for CLI args which are passed as strings\n let argumentType;\n propertiesChain.reduce((obj, prop, index) => {\n if (propertiesChain.length - 1 === index) {\n argumentType = obj[prop].type;\n }\n return obj[prop];\n }, defaultConfig);\n\n propertiesChain.reduce((obj, prop, index) => {\n if (propertiesChain.length - 1 === index) {\n // Finds an option and set a corresponding value\n if (typeof obj[prop] !== 'undefined') {\n if (args[++i]) {\n if (argumentType === 'boolean') {\n obj[prop] = toBoolean(args[i]);\n } else if (argumentType === 'number') {\n obj[prop] = +args[i];\n } else if (argumentType.indexOf(']') >= 0) {\n obj[prop] = args[i].split(',');\n } else {\n obj[prop] = args[i];\n }\n } else {\n log(\n 2,\n `[config] Missing value for the '${option}' argument. Using the default value.`\n );\n showUsage = true;\n }\n }\n }\n return obj[prop];\n }, options);\n }\n\n // Display the usage for the reference if needed\n if (showUsage) {\n printUsage(defaultConfig);\n }\n\n return options;\n}\n\n/**\n * Recursively updates properties in an object based on nested names and assigns\n * the final value.\n *\n * @param {Object} objectToUpdate - The object to be updated.\n * @param {Array} nestedNames - Array of nested property names.\n * @param {any} value - The final value to be assigned.\n *\n * @returns {Object} Updated object with assigned values.\n */\nfunction recursiveProps(objectToUpdate, nestedNames, value) {\n while (nestedNames.length > 1) {\n const propName = nestedNames.shift();\n\n // Create a property in object if it doesn't exist\n if (!Object.prototype.hasOwnProperty.call(objectToUpdate, propName)) {\n objectToUpdate[propName] = {};\n }\n\n // Call function again if there still names to go\n objectToUpdate[propName] = recursiveProps(\n Object.assign({}, objectToUpdate[propName]),\n nestedNames,\n value\n );\n\n return objectToUpdate;\n }\n\n // Assign the final value\n objectToUpdate[nestedNames[0]] = value;\n return objectToUpdate;\n}\n\nexport default {\n getOptions,\n setOptions,\n manualConfig,\n mapToNewConfig,\n mergeConfigOptions,\n initExportSettings\n};\n","/**\n * This module exports two functions: fetch (for GET requests) and post (for POST requests).\n */\n\nimport http from 'http';\nimport https from 'https';\n\n/**\n * Returns the HTTP or HTTPS protocol module based on the provided URL.\n *\n * @param {string} url - The URL to determine the protocol.\n *\n * @returns {Object} The HTTP or HTTPS protocol module (http or https).\n */\nconst getProtocol = (url) => (url.startsWith('https') ? https : http);\n\n/**\n * Fetches data from the specified URL using either HTTP or HTTPS protocol.\n *\n * @param {string} url - The URL to fetch data from.\n * @param {Object} requestOptions - Options for the HTTP request (optional).\n *\n * @returns {Promise} Promise resolving to the HTTP response object\n * with added 'text' property or rejecting with an error.\n */\nasync function fetch(url, requestOptions = {}) {\n return new Promise((resolve, reject) => {\n const protocol = getProtocol(url);\n\n protocol\n .get(\n url,\n Object.assign(\n {\n headers: {\n 'User-Agent': 'highcharts/export',\n Referer: 'highcharts.export'\n }\n },\n requestOptions || {}\n ),\n (res) => {\n let data = '';\n\n // A chunk of data has been received.\n res.on('data', (chunk) => {\n data += chunk;\n });\n\n // The whole response has been received.\n res.on('end', () => {\n if (!data) {\n reject('Nothing was fetched from the URL.');\n }\n\n res.text = data;\n resolve(res);\n });\n }\n )\n .on('error', (error) => {\n reject(error);\n });\n });\n}\n\n/**\n * Sends a POST request to the specified URL with the provided JSON body using\n * either HTTP or HTTPS protocol.\n *\n * @param {string} url - The URL to send the POST request to.\n * @param {Object} body - The JSON body to include in the POST request\n * (optional, default is an empty object).\n * @param {Object} requestOptions - Options for the HTTP request (optional).\n *\n * @returns {Promise} Promise resolving to the HTTP response object with\n * added 'text' property or rejecting with an error.\n */\nasync function post(url, body = {}, requestOptions = {}) {\n return new Promise((resolve, reject) => {\n const protocol = getProtocol(url);\n const data = JSON.stringify(body);\n\n // Set default headers and merge with requestOptions\n const options = Object.assign(\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Content-Length': data.length\n }\n },\n requestOptions\n );\n\n const req = protocol\n .request(url, options, (res) => {\n let responseData = '';\n\n // A chunk of data has been received.\n res.on('data', (chunk) => {\n responseData += chunk;\n });\n\n // The whole response has been received.\n res.on('end', () => {\n try {\n res.text = responseData;\n resolve(res);\n } catch (error) {\n reject(error);\n }\n });\n })\n .on('error', (error) => {\n reject(error);\n });\n\n // Write the request body and end the request.\n req.write(data);\n req.end();\n });\n}\n\nexport default fetch;\nexport { fetch, post };\n","class ExportError extends Error {\n constructor(message) {\n super();\n this.message = message;\n this.stackMessage = message;\n }\n\n setError(error) {\n this.error = error;\n if (error.name) {\n this.name = error.name;\n }\n if (error.statusCode) {\n this.statusCode = error.statusCode;\n }\n if (error.stack) {\n this.stackMessage = error.message;\n this.stack = error.stack;\n }\n return this;\n }\n}\n\nexport default ExportError;\n","/*******************************************************************************\n\nHighcharts Export Server\n\nCopyright (c) 2016-2024, Highsoft\n\nLicenced under the MIT licence.\n\nAdditionally a valid Highcharts license is required for use.\n\nSee LICENSE file in root for details.\n\n*******************************************************************************/\n\n// The cache manager manages the Highcharts library and its dependencies.\n// The cache itself is stored in .cache, and is checked by the config system\n// before starting the service\n\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';\nimport { join } from 'path';\n\nimport { HttpsProxyAgent } from 'https-proxy-agent';\n\nimport { getOptions } from './config.js';\nimport { envs } from './envs.js';\nimport { fetch } from './fetch.js';\nimport { log } from './logger.js';\nimport { __dirname } from './utils.js';\n\nimport ExportError from './errors/ExportError.js';\n\nconst cache = {\n cdnURL: 'https://code.highcharts.com/',\n activeManifest: {},\n sources: '',\n hcVersion: ''\n};\n\n/**\n * Extracts and caches the Highcharts version from the sources string.\n *\n * @returns {string} The extracted Highcharts version.\n */\nexport const extractVersion = (cache) => {\n return cache.sources\n .substring(0, cache.sources.indexOf('*/'))\n .replace('/*', '')\n .replace('*/', '')\n .replace(/\\n/g, '')\n .trim();\n};\n\n/**\n * Extracts the Highcharts module name based on the scriptPath.\n */\nexport const extractModuleName = (scriptPath) => {\n return scriptPath.replace(\n /(.*)\\/|(.*)modules\\/|stock\\/(.*)indicators\\/|maps\\/(.*)modules\\//gi,\n ''\n );\n};\n\n/**\n * Saves the provided configuration and fetched modules to the cache manifest\n * file.\n *\n * @param {object} config - Highcharts-related configuration object.\n * @param {object} fetchedModules - An object that contains mapped names of\n * fetched Highcharts modules to use.\n *\n * @throws {ExportError} Throws an ExportError if an error occurs while writing\n * the cache manifest.\n */\nexport const saveConfigToManifest = async (config, fetchedModules) => {\n const newManifest = {\n version: config.version,\n modules: fetchedModules || {}\n };\n\n // Update cache object with the current modules\n cache.activeManifest = newManifest;\n\n log(3, '[cache] Writing a new manifest.');\n try {\n writeFileSync(\n join(__dirname, config.cachePath, 'manifest.json'),\n JSON.stringify(newManifest),\n 'utf8'\n );\n } catch (error) {\n throw new ExportError('[cache] Error writing the cache manifest.').setError(\n error\n );\n }\n};\n\n/**\n * Fetches a single script and updates the fetchedModules accordingly.\n *\n * @param {string} script - A path to script to get.\n * @param {Object} requestOptions - Additional options for the proxy agent\n * to use for a request.\n * @param {Object} fetchedModules - An object which tracks which Highcharts\n * modules have been fetched.\n * @param {boolean} shouldThrowError - A flag to indicate if the error should be\n * thrown. This should be used only for the core scripts.\n *\n * @returns {Promise} A Promise resolving to the text representation\n * of the fetched script.\n *\n * @throws {ExportError} Throws an ExportError if there is a problem with\n * fetching the script.\n */\nexport const fetchAndProcessScript = async (\n script,\n requestOptions,\n fetchedModules,\n shouldThrowError = false\n) => {\n // Get rid of the .js from the custom strings\n if (script.endsWith('.js')) {\n script = script.substring(0, script.length - 3);\n }\n\n log(4, `[cache] Fetching script - ${script}.js`);\n\n // Fetch the script\n const response = await fetch(`${script}.js`, requestOptions);\n\n // If OK, return its text representation\n if (response.statusCode === 200 && typeof response.text == 'string') {\n if (fetchedModules) {\n const moduleName = extractModuleName(script);\n fetchedModules[moduleName] = 1;\n }\n\n return response.text;\n }\n\n if (shouldThrowError) {\n throw new ExportError(\n `Could not fetch the ${script}.js. The script might not exist in the requested version (status code: ${response.statusCode}).`\n ).setError(response);\n } else {\n log(\n 2,\n `[cache] Could not fetch the ${script}.js. The script might not exist in the requested version.`\n );\n }\n\n return '';\n};\n\n/**\n * Fetches Highcharts scripts and customScripts from the given CDNs.\n *\n * @param {string} coreScripts - Array of Highcharts core scripts to fetch.\n * @param {string} moduleScripts - Array of Highcharts modules to fetch.\n * @param {string} customScripts - Array of custom script paths to fetch\n * (full URLs).\n * @param {object} proxyOptions - Options for the proxy agent to use for\n * a request.\n * @param {object} fetchedModules - An object which tracks which Highcharts\n * modules have been fetched.\n *\n * @returns {Promise} The fetched scripts content joined.\n */\nexport const fetchScripts = async (\n coreScripts,\n moduleScripts,\n customScripts,\n proxyOptions,\n fetchedModules\n) => {\n // Configure proxy if exists\n let proxyAgent;\n const { host, port, username, password } = proxyOptions;\n\n // Try to create a Proxy Agent\n if (host && port) {\n try {\n proxyAgent = new HttpsProxyAgent({\n host,\n port,\n ...(username && password ? { username, password } : {})\n });\n } catch (error) {\n throw new ExportError('[cache] Could not create a Proxy Agent.').setError(\n error\n );\n }\n }\n\n // If exists, add proxy agent to request options\n const requestOptions = proxyAgent\n ? {\n agent: proxyAgent,\n timeout: envs.SERVER_PROXY_TIMEOUT\n }\n : {};\n\n const allFetchPromises = [\n ...coreScripts.map((script) =>\n fetchAndProcessScript(`${script}`, requestOptions, fetchedModules, true)\n ),\n ...moduleScripts.map((script) =>\n fetchAndProcessScript(`${script}`, requestOptions, fetchedModules)\n ),\n ...customScripts.map((script) =>\n fetchAndProcessScript(`${script}`, requestOptions)\n )\n ];\n\n const fetchedScripts = await Promise.all(allFetchPromises);\n return fetchedScripts.join(';\\n');\n};\n\n/**\n * Updates the local cache with Highcharts scripts and their versions.\n *\n * @param {Object} options - Object containing all options.\n * @param {string} sourcePath - The path to the source file in the cache.\n *\n * @returns {Promise} A Promise resolving to an object representing\n * the fetched modules.\n *\n * @throws {ExportError} Throws an ExportError if there is an issue updating\n * the local Highcharts cache.\n */\nexport const updateCache = async (\n highchartsOptions,\n proxyOptions,\n sourcePath\n) => {\n const version = highchartsOptions.version;\n const hcVersion = version === 'latest' || !version ? '' : `${version}/`;\n const cdnURL = highchartsOptions.cdnURL || cache.cdnURL;\n\n log(\n 3,\n `[cache] Updating cache version to Highcharts: ${hcVersion || 'latest'}.`\n );\n\n const fetchedModules = {};\n try {\n cache.sources = await fetchScripts(\n [\n ...highchartsOptions.coreScripts.map((c) => `${cdnURL}${hcVersion}${c}`)\n ],\n [\n ...highchartsOptions.moduleScripts.map((m) =>\n m === 'map'\n ? `${cdnURL}maps/${hcVersion}modules/${m}`\n : `${cdnURL}${hcVersion}modules/${m}`\n ),\n ...highchartsOptions.indicatorScripts.map(\n (i) => `${cdnURL}stock/${hcVersion}indicators/${i}`\n )\n ],\n highchartsOptions.customScripts,\n proxyOptions,\n fetchedModules\n );\n\n cache.hcVersion = extractVersion(cache);\n\n // Save the fetched modules into caches' source JSON\n writeFileSync(sourcePath, cache.sources);\n return fetchedModules;\n } catch (error) {\n throw new ExportError(\n '[cache] Unable to update the local Highcharts cache.'\n ).setError(error);\n }\n};\n\n/**\n * Updates the Highcharts version in the applied configuration and checks\n * the cache for the new version.\n *\n * @param {string} newVersion - The new Highcharts version to be applied.\n *\n * @returns {Promise<(object|boolean)>} A Promise resolving to the updated\n * configuration with the new version, or false if no applied configuration\n * exists.\n */\nexport const updateVersion = async (newVersion) => {\n const options = getOptions();\n if (options?.highcharts) {\n options.highcharts.version = newVersion;\n }\n await checkAndUpdateCache(options);\n};\n\n/**\n * Checks the cache for Highcharts dependencies, updates the cache if needed,\n * and loads the sources.\n *\n * @param {Object} options - Object containing all options.\n *\n * @returns {Promise} A Promise that resolves once the cache is checked\n * and updated.\n *\n * @throws {ExportError} Throws an ExportError if there is an issue updating\n * or reading the cache.\n */\nexport const checkAndUpdateCache = async (options) => {\n const { highcharts, server } = options;\n const cachePath = join(__dirname, highcharts.cachePath);\n\n let fetchedModules;\n // Prepare paths to manifest and sources from the .cache folder\n const manifestPath = join(cachePath, 'manifest.json');\n const sourcePath = join(cachePath, 'sources.js');\n\n // Create the cache destination if it doesn't exist already\n !existsSync(cachePath) && mkdirSync(cachePath);\n\n // Fetch all the scripts either if manifest.json does not exist\n // or if the forceFetch option is enabled\n if (!existsSync(manifestPath) || highcharts.forceFetch) {\n log(3, '[cache] Fetching and caching Highcharts dependencies.');\n fetchedModules = await updateCache(highcharts, server.proxy, sourcePath);\n } else {\n let requestUpdate = false;\n\n // Read the manifest JSON\n const manifest = JSON.parse(readFileSync(manifestPath));\n\n // Check if the modules is an array, if so, we rewrite it to a map to make\n // it easier to resolve modules.\n if (manifest.modules && Array.isArray(manifest.modules)) {\n const moduleMap = {};\n manifest.modules.forEach((m) => (moduleMap[m] = 1));\n manifest.modules = moduleMap;\n }\n\n const { coreScripts, moduleScripts, indicatorScripts } = highcharts;\n const numberOfModules =\n coreScripts.length + moduleScripts.length + indicatorScripts.length;\n\n // Compare the loaded highcharts config with the contents in cache.\n // If there are changes, fetch requested modules and products,\n // and bake them into a giant blob. Save the blob.\n if (manifest.version !== highcharts.version) {\n log(\n 2,\n '[cache] A Highcharts version mismatch in the cache, need to re-fetch.'\n );\n requestUpdate = true;\n } else if (Object.keys(manifest.modules || {}).length !== numberOfModules) {\n log(\n 2,\n '[cache] The cache and the requested modules do not match, need to re-fetch.'\n );\n requestUpdate = true;\n } else {\n // Check each module, if anything is missing refetch everything\n requestUpdate = (moduleScripts || []).some((moduleName) => {\n if (!manifest.modules[moduleName]) {\n log(\n 2,\n `[cache] The ${moduleName} is missing in the cache, need to re-fetch.`\n );\n return true;\n }\n });\n }\n\n if (requestUpdate) {\n fetchedModules = await updateCache(highcharts, server.proxy, sourcePath);\n } else {\n log(3, '[cache] Dependency cache is up to date, proceeding.');\n\n // Load the sources\n cache.sources = readFileSync(sourcePath, 'utf8');\n\n // Get current modules map\n fetchedModules = manifest.modules;\n\n cache.hcVersion = extractVersion(cache);\n }\n }\n\n // Finally, save the new manifest, which is basically our current config\n // in a slightly different format\n await saveConfigToManifest(highcharts, fetchedModules);\n};\n\nexport const getCachePath = () =>\n join(__dirname, getOptions().highcharts.cachePath);\n\nexport const getCache = () => cache;\n\nexport const highcharts = () => cache.sources;\n\nexport const version = () => cache.hcVersion;\n\nexport default {\n checkAndUpdateCache,\n getCachePath,\n updateVersion,\n getCache,\n highcharts,\n version\n};\n","/*******************************************************************************\n\nHighcharts Export Server\n\nCopyright (c) 2016-2024, Highsoft\n\nLicenced under the MIT licence.\n\nAdditionally a valid Highcharts license is required for use.\n\nSee LICENSE file in root for details.\n\n*******************************************************************************/\n\n/* eslint-disable no-undef */\n\n/**\n * Setting the animObject. Called when initing the page.\n */\nexport function setupHighcharts() {\n Highcharts.animObject = function () {\n return { duration: 0 };\n };\n}\n\n/**\n * Creates the actual chart.\n *\n * @param {object} chartOptions - The options for the Highcharts chart.\n * @param {object} options - The export options.\n * @param {boolean} displayErrors - A flag indicating whether to display errors.\n */\nexport async function triggerExport(chartOptions, options, displayErrors) {\n // Display errors flag taken from chart options nad debugger module\n window._displayErrors = displayErrors;\n\n // Get required functions\n const { getOptions, merge, setOptions, wrap } = Highcharts;\n\n // Create a separate object for a potential setOptions usages in order to\n // prevent from polluting other exports that can happen on the same page\n Highcharts.setOptionsObj = merge(false, {}, getOptions());\n\n // By default animation is disabled\n const chart = {\n animation: false\n };\n\n // When straight inject, the size is set through CSS only\n if (options.export.strInj) {\n chart.height = chartOptions.chart.height;\n chart.width = chartOptions.chart.width;\n }\n\n // NOTE: Is this used for anything useful?\n window.isRenderComplete = false;\n wrap(Highcharts.Chart.prototype, 'init', function (proceed, userOptions, cb) {\n // Override userOptions with image friendly options\n userOptions = merge(userOptions, {\n exporting: {\n enabled: false\n },\n plotOptions: {\n series: {\n label: {\n enabled: false\n }\n }\n },\n /* Expects tooltip in userOptions when forExport is true.\n https://github.com/highcharts/highcharts/blob/3ad430a353b8056b9e764aa4e5cd6828aa479db2/js/parts/Chart.js#L241\n */\n tooltip: {}\n });\n\n (userOptions.series || []).forEach(function (series) {\n series.animation = false;\n });\n\n // Add flag to know if chart render has been called.\n if (!window.onHighchartsRender) {\n window.onHighchartsRender = Highcharts.addEvent(this, 'render', () => {\n window.isRenderComplete = true;\n });\n }\n\n proceed.apply(this, [userOptions, cb]);\n });\n\n wrap(Highcharts.Series.prototype, 'init', function (proceed, chart, options) {\n proceed.apply(this, [chart, options]);\n });\n\n // Get the user options\n const userOptions = options.export.strInj\n ? new Function(`return ${options.export.strInj}`)()\n : chartOptions;\n\n // Trigger custom code\n if (options.customLogic.customCode) {\n new Function('options', options.customLogic.customCode)(userOptions);\n }\n\n // Merge the globalOptions, themeOptions, options from the wrapped\n // setOptions function and user options to create the final options object\n const finalOptions = merge(\n false,\n JSON.parse(options.export.themeOptions),\n userOptions,\n // Placed it here instead in the init because of the size issues\n { chart }\n );\n\n const finalCallback = options.customLogic.callback\n ? new Function(`return ${options.customLogic.callback}`)()\n : undefined;\n\n // Set the global options if exist\n const globalOptions = JSON.parse(options.export.globalOptions);\n if (globalOptions) {\n setOptions(globalOptions);\n }\n\n let constr = options.export.constr || 'chart';\n constr = typeof Highcharts[constr] !== 'undefined' ? constr : 'chart';\n\n Highcharts[constr]('container', finalOptions, finalCallback);\n\n // Get the current global options\n const defaultOptions = getOptions();\n\n // Clear it just in case (e.g. the setOptions was used in the customCode)\n for (const prop in defaultOptions) {\n if (typeof defaultOptions[prop] !== 'function') {\n delete defaultOptions[prop];\n }\n }\n\n // Set the default options back\n setOptions(Highcharts.setOptionsObj);\n\n // Empty the custom global options object\n Highcharts.setOptionsObj = {};\n}\n","/*******************************************************************************\n\nHighcharts Export Server\n\nCopyright (c) 2016-2024, Highsoft\n\nLicenced under the MIT licence.\n\nAdditionally a valid Highcharts license is required for use.\n\nSee LICENSE file in root for details.\n\n*******************************************************************************/\n\nimport { readFileSync } from 'fs';\nimport path from 'path';\n\nimport puppeteer from 'puppeteer';\n\nimport { getCachePath } from './cache.js';\nimport { getOptions } from './config.js';\nimport { setupHighcharts } from './highcharts.js';\nimport { log, logWithStack } from './logger.js';\nimport { __dirname } from './utils.js';\n\nimport ExportError from './errors/ExportError.js';\n\n// Get the template for the page\nconst template = readFileSync(__dirname + '/templates/template.html', 'utf8');\n\nlet browser;\n\n/**\n * Retrieves the existing Puppeteer browser instance.\n *\n * @returns {Promise} A Promise resolving to the Puppeteer browser\n * instance.\n *\n * @throws {ExportError} Throws an ExportError if no valid browser has been\n * created.\n */\nexport function get() {\n if (!browser) {\n throw new ExportError('[browser] No valid browser has been created.');\n }\n return browser;\n}\n\n/**\n * Creates a Puppeteer browser instance with the specified arguments.\n *\n * @param {Array} puppeteerArgs - Additional arguments for Puppeteer launch.\n *\n * @returns {Promise} A Promise resolving to the Puppeteer browser\n * instance.\n *\n * @throws {ExportError} Throws an ExportError if max retries to open a browser\n * instance are reached, or if no browser instance is found after retries.\n */\nexport async function create(puppeteerArgs) {\n // Get debug and other options\n const { puppeteer: puppeteerOptions, debug, other } = getOptions();\n\n // Get the debug options\n const { enable: enabledDebug, ...debugOptions } = debug;\n\n const launchOptions = {\n headless: other.browserShellMode ? 'shell' : true,\n userDataDir: puppeteerOptions.tempDir || './tmp/',\n args: puppeteerArgs,\n handleSIGINT: false,\n handleSIGTERM: false,\n handleSIGHUP: false,\n waitForInitialPage: false,\n defaultViewport: null,\n ...(enabledDebug && debugOptions)\n };\n\n // Create a browser\n if (!browser) {\n const maxTries = 25;\n let tryCount = 0;\n\n const open = async () => {\n try {\n log(\n 3,\n `[browser] Attempting to get a browser instance (try ${++tryCount}).`\n );\n browser = await puppeteer.launch(launchOptions);\n } catch (error) {\n // This isn't a full error yet as puppeteer sometimes takes time to\n // initialize properly.\n logWithStack(\n 2,\n error,\n `[browser] Failed to launch a browser instance - retrying (attempt ${tryCount}/${maxTries}).`\n );\n\n // Retry to launch browser until reaching max attempts\n if (tryCount < 25) {\n log(\n 3,\n `[browser] Retry to open a browser (attempt ${tryCount}/${maxTries}).`\n );\n await new Promise((response) => setTimeout(response, 4000));\n await open();\n } else {\n //... now it's an error, which is caught by the caller\n throw error;\n }\n }\n };\n\n try {\n await open();\n\n // Shell mode inform\n if (launchOptions.headless === 'shell') {\n log(3, `[browser] Launched browser in shell mode.`);\n }\n\n // Debug mode inform\n if (enabledDebug) {\n log(3, `[browser] Launched browser in debug mode.`);\n }\n } catch (error) {\n throw new ExportError(\n '[browser] Maximum retries to open a browser instance reached.'\n ).setError(error);\n }\n\n if (!browser) {\n throw new ExportError('[browser] Cannot find a browser to open.');\n }\n }\n\n // Return a browser promise\n return browser;\n}\n\n/**\n * Closes the Puppeteer browser instance if it is connected.\n *\n * @returns {Promise} A Promise resolving to true after the browser\n * is closed.\n */\nexport async function close() {\n // Close the browser when connnected\n if (browser?.connected) {\n await browser.close();\n }\n log(4, '[browser] Closed the browser.');\n}\n\n/**\n * Creates a new Puppeteer Page within an existing browser instance.\n *\n * If the browser instance is not available, returns false.\n *\n * The function creates a new page, disables caching, sets content using\n * setPageContent(), and returns the created Puppeteer Page.\n *\n * @returns {(boolean|object)} Returns false if the browser instance is not\n * available, or a Puppeteer Page object representing the newly created page.\n */\nexport async function newPage() {\n if (!browser) {\n return false;\n }\n\n // Create a page\n const page = await browser.newPage();\n\n // Disable cache\n await page.setCacheEnabled(false);\n\n // Set the content\n await setPageContent(page);\n\n // Set page events\n setPageEvents(page);\n\n return page;\n}\n\n/**\n * Clears the content of a Puppeteer Page based on the specified mode.\n *\n * @param {Object} page - The Puppeteer Page object to be cleared.\n * @param {boolean} hardReset - A flag indicating the type of clearing\n * to be performed. If true, navigates to 'about:blank' and resets content\n * and scripts. If false, clears the body content by setting a predefined HTML\n * structure.\n *\n * @throws {Error} Logs thrown error if clearing the page content fails.\n */\nexport async function clearPage(page, hardReset = false) {\n try {\n if (page && !page.isClosed()) {\n if (hardReset) {\n // Navigate to about:blank\n await page.goto('about:blank', { waitUntil: 'domcontentloaded' });\n\n // Set the content and and scripts again\n await setPageContent(page);\n } else {\n // Clear body content\n await page.evaluate(() => {\n document.body.innerHTML =\n '
';\n });\n }\n return true;\n }\n } catch (error) {\n logWithStack(\n 2,\n error,\n '[browser] Could not clear the content of the page.'\n );\n }\n\n return false;\n}\n\n/**\n * Adds custom JS and CSS resources to a Puppeteer Page based on the specified\n * options.\n *\n * @param {Object} page - The Puppeteer Page object to which resources will be\n * added.\n * @param {Object} options - All options and configuration.\n *\n * @returns {Promise>} - Promise resolving to an array of injected\n * resources.\n */\nexport async function addPageResources(page, options) {\n // Injected resources array\n const injectedResources = [];\n\n // Use resources\n const resources = options.customLogic.resources;\n if (resources) {\n const injectedJs = [];\n\n // Load custom JS code\n if (resources.js) {\n injectedJs.push({\n content: resources.js\n });\n }\n\n // Load scripts from all custom files\n if (resources.files) {\n for (const file of resources.files) {\n const isLocal = !file.startsWith('http') ? true : false;\n\n // Add each custom script from resources' files\n injectedJs.push(\n isLocal\n ? {\n content: readFileSync(file, 'utf8')\n }\n : {\n url: file\n }\n );\n }\n }\n\n for (const jsResource of injectedJs) {\n try {\n injectedResources.push(await page.addScriptTag(jsResource));\n } catch (error) {\n logWithStack(2, error, `[export] The JS resource cannot be loaded.`);\n }\n }\n injectedJs.length = 0;\n\n // Load CSS\n const injectedCss = [];\n if (resources.css) {\n let cssImports = resources.css.match(/@import\\s*([^;]*);/g);\n if (cssImports) {\n // Handle css section\n for (let cssImportPath of cssImports) {\n if (cssImportPath) {\n cssImportPath = cssImportPath\n .replace('url(', '')\n .replace('@import', '')\n .replace(/\"/g, '')\n .replace(/'/g, '')\n .replace(/;/, '')\n .replace(/\\)/g, '')\n .trim();\n\n // Add each custom css from resources\n if (cssImportPath.startsWith('http')) {\n injectedCss.push({\n url: cssImportPath\n });\n } else if (options.customLogic.allowFileResources) {\n injectedCss.push({\n path: path.join(__dirname, cssImportPath)\n });\n }\n }\n }\n }\n\n // The rest of the CSS section will be content by now\n injectedCss.push({\n content: resources.css.replace(/@import\\s*([^;]*);/g, '') || ' '\n });\n\n for (const cssResource of injectedCss) {\n try {\n injectedResources.push(await page.addStyleTag(cssResource));\n } catch (error) {\n logWithStack(2, error, `[export] The CSS resource cannot be loaded.`);\n }\n }\n injectedCss.length = 0;\n }\n }\n return injectedResources;\n}\n\n/**\n * Clears out all state set on the page with addScriptTag/addStyleTag. Removes\n * injected resources and resets CSS and script tags on the page. Additionally,\n * it destroys previously existing charts.\n *\n * @param {Object} page - The Puppeteer Page object from which resources will\n * be cleared.\n * @param {Array} injectedResources - Array of injected resources\n * to be cleared.\n */\nexport async function clearPageResources(page, injectedResources) {\n try {\n for (const resource of injectedResources) {\n await resource.dispose();\n }\n\n // Destroy old charts after export is done and reset all CSS and script tags\n await page.evaluate(() => {\n // We are not guaranteed that Highcharts is loaded, e,g, when doing SVG\n // exports\n if (typeof Highcharts !== 'undefined') {\n // eslint-disable-next-line no-undef\n const oldCharts = Highcharts.charts;\n\n // Check in any already existing charts\n if (Array.isArray(oldCharts) && oldCharts.length) {\n // Destroy old charts\n for (const oldChart of oldCharts) {\n oldChart && oldChart.destroy();\n // eslint-disable-next-line no-undef\n Highcharts.charts.shift();\n }\n }\n }\n\n // eslint-disable-next-line no-undef\n const [...scriptsToRemove] = document.getElementsByTagName('script');\n // eslint-disable-next-line no-undef\n const [, ...stylesToRemove] = document.getElementsByTagName('style');\n // eslint-disable-next-line no-undef\n const [...linksToRemove] = document.getElementsByTagName('link');\n\n // Remove tags\n for (const element of [\n ...scriptsToRemove,\n ...stylesToRemove,\n ...linksToRemove\n ]) {\n element.remove();\n }\n });\n } catch (error) {\n logWithStack(2, error, `[browser] Could not clear page's resources.`);\n }\n}\n\n/**\n * Sets the content for a Puppeteer Page using a predefined template\n * and additional scripts. Also, sets the pageerror in order to catch\n * and display errors from the window context.\n *\n * @param {Object} page - The Puppeteer Page object for which the content\n * is being set.\n */\nasync function setPageContent(page) {\n await page.setContent(template, { waitUntil: 'domcontentloaded' });\n\n // Add all registered Higcharts scripts, quite demanding\n await page.addScriptTag({ path: `${getCachePath()}/sources.js` });\n\n // Set the initial animObject\n await page.evaluate(setupHighcharts);\n}\n\n/**\n * Set events for a Puppeteer Page.\n *\n * @param {Object} page - The Puppeteer Page object to set events to.\n */\nfunction setPageEvents(page) {\n // Get debug options\n const { debug } = getOptions();\n\n // Set the console listener, if needed\n if (debug.enable && debug.listenToConsole) {\n page.on('console', (message) => {\n console.log(`[debug] ${message.text()}`);\n });\n }\n\n // Set the pageerror listener\n page.on('pageerror', async (error) => {\n // It would seem like this may fire at the same time or shortly before\n // a page is closed.\n if (page.isClosed()) {\n return;\n }\n\n // TODO: Consider adding a switch here that turns on log(0) logging\n // on page errors.\n await page.$eval(\n '#container',\n (element, errorMessage) => {\n // eslint-disable-next-line no-undef\n if (window._displayErrors) {\n element.innerHTML = errorMessage;\n }\n },\n `

Chart input data error:

${error.toString()}`\n );\n });\n}\n\nexport default {\n get,\n create,\n close,\n newPage,\n clearPage,\n addPageResources,\n clearPageResources\n};\n","/*******************************************************************************\n\nHighcharts Export Server\n\nCopyright (c) 2016-2024, Highsoft\n\nLicenced under the MIT licence.\n\nAdditionally a valid Highcharts license is required for use.\n\nSee LICENSE file in root for details.\n\n*******************************************************************************/\n\nimport { addPageResources, clearPageResources } from './browser.js';\nimport { getCache } from './cache.js';\nimport { triggerExport } from './highcharts.js';\nimport { log } from './logger.js';\n\nimport svgTemplate from './../templates/svg_export/svg_export.js';\n\nimport ExportError from './errors/ExportError.js';\n\n/**\n * Retrieves the clipping region coordinates of the specified page element with\n * the id 'chart-container'.\n *\n * @param {Object} page - Puppeteer page object.\n *\n * @returns {Promise} Promise resolving to an object containing\n * x, y, width, and height properties.\n */\nconst getClipRegion = (page) =>\n page.$eval('#chart-container', (element) => {\n const { x, y, width, height } = element.getBoundingClientRect();\n return {\n x,\n y,\n width,\n height: Math.trunc(height > 1 ? height : 500)\n };\n });\n\n/**\n * Creates an image using Puppeteer's page screenshot functionality with\n * specified options.\n *\n * @param {Object} page - Puppeteer page object.\n * @param {string} type - Image type.\n * @param {string} encoding - Image encoding.\n * @param {Object} clip - Clipping region coordinates.\n * @param {number} rasterizationTimeout - Timeout for rasterization\n * in milliseconds.\n *\n * @returns {Promise} Promise resolving to the image buffer or rejecting\n * with an ExportError for timeout.\n */\nconst createImage = (page, type, encoding, clip, rasterizationTimeout) =>\n Promise.race([\n page.screenshot({\n type,\n encoding,\n clip,\n captureBeyondViewport: true,\n fullPage: false,\n optimizeForSpeed: true,\n ...(type !== 'png' ? { quality: 80 } : {}),\n\n // #447, #463 - always render on a transparent page if the expected type\n // format is PNG\n omitBackground: type == 'png'\n }),\n new Promise((_resolve, reject) =>\n setTimeout(\n () => reject(new ExportError('Rasterization timeout')),\n rasterizationTimeout || 1500\n )\n )\n ]);\n\n/**\n * Creates a PDF using Puppeteer's page pdf functionality with specified\n * options.\n *\n * @param {Object} page - Puppeteer page object.\n * @param {number} height - PDF height.\n * @param {number} width - PDF width.\n * @param {string} encoding - PDF encoding.\n *\n * @returns {Promise} Promise resolving to the PDF buffer.\n */\nconst createPDF = async (\n page,\n height,\n width,\n encoding,\n rasterizationTimeout\n) => {\n await page.emulateMediaType('screen');\n\n return page.pdf({\n // This will remove an extra empty page in PDF exports\n height: height + 1,\n width,\n encoding,\n timeout: rasterizationTimeout || 1500\n });\n};\n\n/**\n * Creates an SVG string by evaluating the outerHTML of the first 'svg' element\n * inside an element with the id 'container'.\n *\n * @param {Object} page - Puppeteer page object.\n *\n * @returns {Promise} Promise resolving to the SVG string.\n */\nconst createSVG = (page) =>\n page.$eval('#container svg:first-of-type', (element) => element.outerHTML);\n\n/**\n * Sets the specified chart and options as configuration into the triggerExport\n * function within the window context using page.evaluate.\n *\n * @param {Object} page - Puppeteer page object.\n * @param {any} chart - The chart object to be configured.\n * @param {Object} options - Configuration options for the chart.\n *\n * @returns {Promise} Promise resolving after the configuration is set.\n */\nconst setAsConfig = async (page, chart, options, displayErrors) => {\n // Get rid of the redunant string data\n options.export.instr = null;\n options.export.infile = null;\n\n // Get the size of the export input\n const totalSize = Buffer.byteLength(\n options.export?.strInj ? options.export?.strInj : JSON.stringify(chart),\n 'utf-8'\n );\n\n // Log the size in MB\n log(\n 4,\n `[export] The current total size of data passed to a page is around ${(\n totalSize /\n (1024 * 1024)\n ).toFixed(2)} MB`\n );\n\n // Check the size of data passed to the page\n if (totalSize >= 100 * 1024 * 1024) {\n throw new ExportError(`[export] The data passed to a page exceeded 100MB.`);\n }\n\n // Trigger the Highcharts chart creation\n return page.evaluate(triggerExport, chart, options, displayErrors);\n};\n\n/**\n * Exports to a chart from a page using Puppeteer.\n *\n * @param {Object} page - Puppeteer page object.\n * @param {any} chart - The chart object or SVG configuration to be exported.\n * @param {Object} options - Export options and configuration.\n *\n * @returns {Promise} Promise resolving to\n * the exported data or rejecting with an ExportError.\n */\nexport default async (page, chart, options) => {\n // Injected resources array (additional JS and CSS)\n let injectedResources = [];\n\n try {\n log(4, '[export] Determining export path.');\n\n const exportOptions = options.export;\n\n // Decide whether display error or debbuger wrapper around it\n const displayErrors =\n exportOptions?.options?.chart?.displayErrors &&\n getCache().activeManifest.modules.debugger;\n\n let isSVG;\n if (\n chart.indexOf &&\n (chart.indexOf('= 0 || chart.indexOf('= 0)\n ) {\n // SVG input handling\n log(4, '[export] Treating as SVG.');\n\n // If input is also SVG, just return it\n if (exportOptions.type === 'svg') {\n return chart;\n }\n\n isSVG = true;\n await page.setContent(svgTemplate(chart), {\n waitUntil: 'domcontentloaded'\n });\n } else {\n // JSON config handling\n log(4, '[export] Treating as config.');\n\n // Need to perform straight inject\n if (exportOptions.strInj) {\n // Injection based configuration export\n await setAsConfig(\n page,\n {\n chart: {\n height: exportOptions.height,\n width: exportOptions.width\n }\n },\n options,\n displayErrors\n );\n } else {\n // Basic configuration export\n chart.chart.height = exportOptions.height;\n chart.chart.width = exportOptions.width;\n\n await setAsConfig(page, chart, options, displayErrors);\n }\n }\n\n // Keeps track of all resources added on the page with addXXXTag. etc\n // It's VITAL that all added resources ends up here so we can clear things\n // out when doing a new export in the same page!\n injectedResources = await addPageResources(page, options);\n\n // Get the real chart size and set the zoom accordingly\n const size = isSVG\n ? await page.evaluate((scale) => {\n const svgElement = document.querySelector(\n '#chart-container svg:first-of-type'\n );\n\n // Get the values correctly scaled\n const chartHeight = svgElement.height.baseVal.value * scale;\n const chartWidth = svgElement.width.baseVal.value * scale;\n\n // In case of SVG the zoom must be set directly for body\n // Set the zoom as scale\n // eslint-disable-next-line no-undef\n document.body.style.zoom = scale;\n\n // Set the margin to 0px\n // eslint-disable-next-line no-undef\n document.body.style.margin = '0px';\n\n return {\n chartHeight,\n chartWidth\n };\n }, parseFloat(exportOptions.scale))\n : await page.evaluate(() => {\n // eslint-disable-next-line no-undef\n const { chartHeight, chartWidth } = window.Highcharts.charts[0];\n\n // No need for such scale manipulation in case of other types of exports\n // Reset the zoom for other exports than to SVGs\n // eslint-disable-next-line no-undef\n document.body.style.zoom = 1;\n\n return {\n chartHeight,\n chartWidth\n };\n });\n\n // Set final height and width for viewport\n const viewportHeight = Math.abs(\n Math.ceil(size.chartHeight || exportOptions.height)\n );\n const viewportWidth = Math.abs(\n Math.ceil(size.chartWidth || exportOptions.width)\n );\n\n // Get the clip region for the page\n const { x, y } = await getClipRegion(page);\n\n // Set the final viewport now that we have the real height\n await page.setViewport({\n height: viewportHeight,\n width: viewportWidth,\n deviceScaleFactor: isSVG ? 1 : parseFloat(exportOptions.scale)\n });\n\n let data;\n // Rasterization process\n if (exportOptions.type === 'svg') {\n // SVG\n data = await createSVG(page);\n } else if (['png', 'jpeg'].includes(exportOptions.type)) {\n // PNG or JPEG\n data = await createImage(\n page,\n exportOptions.type,\n 'base64',\n {\n width: viewportWidth,\n height: viewportHeight,\n x,\n y\n },\n exportOptions.rasterizationTimeout\n );\n } else if (exportOptions.type === 'pdf') {\n // PDF\n data = await createPDF(\n page,\n viewportHeight,\n viewportWidth,\n 'base64',\n exportOptions.rasterizationTimeout\n );\n } else {\n throw new ExportError(\n `[export] Unsupported output format ${exportOptions.type}.`\n );\n }\n\n // Clear previously injected JS and CSS resources\n await clearPageResources(page, injectedResources);\n return data;\n } catch (error) {\n await clearPageResources(page, injectedResources);\n return error;\n }\n};\n","/*******************************************************************************\n\nHighcharts Export Server\n\nCopyright (c) 2016-2024, Highsoft\n\nLicenced under the MIT licence.\n\nAdditionally a valid Highcharts license is required for use.\n\nSee LICENSE file in root for details.\n\n*******************************************************************************/\n\nimport cssTemplate from './css.js';\n\nexport default (chart) => `\n\n\n \n \n Highcharts Export\n \n \n \n
\n ${chart}\n
\n \n\n\n`;\n","/*******************************************************************************\n\nHighcharts Export Server\n\nCopyright (c) 2016-2024, Highsoft\n\nLicenced under the MIT licence.\n\nAdditionally a valid Highcharts license is required for use.\n\nSee LICENSE file in root for details.\n\n*******************************************************************************/\n\nimport { Pool } from 'tarn';\nimport { v4 as uuid } from 'uuid';\n\nimport {\n create as createBrowser,\n close as closeBrowser,\n newPage,\n clearPage\n} from './browser.js';\nimport puppeteerExport from './export.js';\nimport { log, logWithStack } from './logger.js';\nimport { measureTime } from './utils.js';\n\nimport ExportError from './errors/ExportError.js';\n\n// The pool instance\nlet pool = false;\n\n// Pool statistics\nexport const stats = {\n performedExports: 0,\n exportAttempts: 0,\n exportFromSvgAttempts: 0,\n timeSpent: 0,\n droppedExports: 0,\n spentAverage: 0\n};\n\nlet poolConfig = {};\n\nconst factory = {\n /**\n * Creates a new worker page for the export pool.\n *\n * @returns {Object} - An object containing the worker ID, a reference to the\n * browser page, and initial work count.\n *\n * @throws {ExportError} - If there's an error during the creation of the new\n * page.\n */\n create: async () => {\n let page = false;\n\n const id = uuid();\n const startDate = new Date().getTime();\n\n try {\n page = await newPage();\n\n if (!page || page.isClosed()) {\n throw new ExportError('The page is invalid or closed.');\n }\n\n log(\n 3,\n `[pool] Successfully created a worker ${id} - took ${\n new Date().getTime() - startDate\n } ms.`\n );\n } catch (error) {\n throw new ExportError(\n 'Error encountered when creating a new page.'\n ).setError(error);\n }\n\n return {\n id,\n page,\n // Try to distribute the initial work count\n workCount: Math.round(Math.random() * (poolConfig.workLimit / 2))\n };\n },\n\n /**\n * Validates a worker page in the export pool, checking if it has exceeded\n * the work limit.\n *\n * @param {Object} workerHandle - The handle to the worker, containing the\n * worker's ID, a reference to the browser page, and work count.\n *\n * @returns {boolean} - Returns true if the worker is valid and within\n * the work limit; otherwise, returns false.\n */\n validate: async (workerHandle) => {\n // NOTE: In certain cases acquiring throws a TargetCloseError, which may\n // be caused by two things:\n // - The page is closed and attempted to be reused.\n // - Lost contact with the browser\n // What we're seeing in logs is that successive exports typically\n // succeeds, and the server recovers, indicating that it's likely\n // the first case. This is an attempt at allievating the issue by\n // simply not validating the worker if the page is null or closed.\n //\n // The actual result from when this happened, was that a worker would\n // be completely locked, stopping it from being acquired until\n // its work count reached the limit.\n if (!workerHandle.page || workerHandle.page?.isClosed()) {\n return false;\n }\n\n if (\n poolConfig.workLimit &&\n ++workerHandle.workCount > poolConfig.workLimit\n ) {\n log(\n 3,\n `[pool] Worker failed validation: exceeded work limit (limit is ${poolConfig.workLimit}).`\n );\n return false;\n }\n return true;\n },\n\n /**\n * Destroys a worker entry in the export pool, closing its associated page.\n *\n * @param {Object} workerHandle - The handle to the worker, containing\n * the worker's ID and a reference to the browser page.\n */\n destroy: async (workerHandle) => {\n log(3, `[pool] Destroying pool entry ${workerHandle.id}.`);\n\n if (workerHandle.page && !workerHandle.page.isClosed()) {\n await workerHandle.page.close();\n }\n }\n\n // log: (message, level) => log(1, '[tarn] ' + message)\n};\n\n/**\n * Initializes the export pool with the provided configuration, creating\n * a browser instance and setting up worker resources.\n *\n * @param {Object} config - Configuration options for the export pool along\n * with custom puppeteer arguments for the puppeteer.launch function.\n */\nexport const initPool = async (config) => {\n // For the module scope usage\n poolConfig = config && config.pool ? { ...config.pool } : {};\n\n // Create a browser instance with the puppeteer arguments\n await createBrowser(config.puppeteerArgs);\n\n log(\n 3,\n `[pool] Initializing pool with workers: min ${poolConfig.minWorkers}, max ${poolConfig.maxWorkers}.`\n );\n\n if (pool) {\n return log(\n 4,\n '[pool] Already initialized, please kill it before creating a new one.'\n );\n }\n\n if (parseInt(poolConfig.minWorkers) > parseInt(poolConfig.maxWorkers)) {\n poolConfig.minWorkers = poolConfig.maxWorkers;\n }\n\n try {\n // Create a pool along with a minimal number of resources\n pool = new Pool({\n // Get the create/validate/destroy/log functions\n ...factory,\n min: parseInt(poolConfig.minWorkers),\n max: parseInt(poolConfig.maxWorkers),\n acquireTimeoutMillis: poolConfig.acquireTimeout,\n createTimeoutMillis: poolConfig.createTimeout,\n destroyTimeoutMillis: poolConfig.destroyTimeout,\n idleTimeoutMillis: poolConfig.idleTimeout,\n createRetryIntervalMillis: poolConfig.createRetryInterval,\n reapIntervalMillis: poolConfig.reaperInterval,\n propagateCreateError: false\n });\n\n // Set events\n pool.on('release', async (resource) => {\n // Clear page\n const r = await clearPage(resource.page, false);\n log(\n 4,\n `[pool] Releasing a worker with ID ${resource.id}. Clear page status: ${r}.`\n );\n });\n\n pool.on('destroySuccess', (eventId, resource) => {\n log(4, `[pool] Destroyed a worker with ID ${resource.id}.`);\n resource.page = null;\n });\n\n const initialResources = [];\n // Create an initial number of resources\n for (let i = 0; i < poolConfig.minWorkers; i++) {\n try {\n const resource = await pool.acquire().promise;\n initialResources.push(resource);\n } catch (error) {\n logWithStack(2, error, '[pool] Could not create an initial resource.');\n }\n }\n\n // Release the initial number of resources back to the pool\n initialResources.forEach((resource) => {\n pool.release(resource);\n });\n\n log(\n 3,\n `[pool] The pool is ready${initialResources.length ? ` with ${initialResources.length} initial resources waiting.` : '.'}`\n );\n } catch (error) {\n throw new ExportError(\n '[pool] Could not create the pool of workers.'\n ).setError(error);\n }\n};\n\n/**\n * Kills all workers in the pool, destroys the pool, and closes the browser\n * instance.\n *\n * @returns {Promise} A promise that resolves after the workers are\n * killed, the pool is destroyed, and the browser is closed.\n */\nexport async function killPool() {\n log(3, '[pool] Killing pool with all workers and closing browser.');\n\n // If still alive, destroy the pool of pages before closing a browser\n if (pool) {\n // Free up not released workers\n for (const worker of pool.used) {\n pool.release(worker.resource);\n }\n\n // Destroy the pool if it is still available\n if (!pool.destroyed) {\n await pool.destroy();\n log(4, '[browser] Destroyed the pool of resources.');\n }\n }\n\n // Close the browser instance\n await closeBrowser();\n}\n\n/**\n * Processes the export work using a worker from the pool. Acquires a worker\n * handle from the pool, performs the export using puppeteer, and releases\n * the worker handle back to the pool.\n *\n * @param {string} chart - The chart data or configuration to be exported.\n * @param {Object} options - Export options and configuration.\n *\n * @returns {Promise} A promise that resolves with the export resultand\n * options.\n *\n * @throws {ExportError} If an error occurs during the export process.\n */\nexport const postWork = async (chart, options) => {\n let workerHandle;\n\n try {\n log(4, '[pool] Work received, starting to process.');\n\n ++stats.exportAttempts;\n if (poolConfig.benchmarking) {\n getPoolInfo();\n }\n\n if (!pool) {\n throw new ExportError('Work received, but pool has not been started.');\n }\n\n // Acquire the worker along with the id of resource and work count\n const acquireCounter = measureTime();\n try {\n log(4, '[pool] Acquiring a worker handle.');\n workerHandle = await pool.acquire().promise;\n\n // Check the page acquire time\n if (options.server.benchmarking) {\n log(\n 5,\n options.payload?.requestId\n ? `[benchmark] Request with ID ${options.payload?.requestId} -`\n : '[benchmark]',\n `Acquired a worker handle: ${acquireCounter()}ms.`\n );\n }\n } catch (error) {\n throw new ExportError(\n (options.payload?.requestId\n ? `For request with ID ${options.payload?.requestId} - `\n : '') +\n `Error encountered when acquiring an available entry: ${acquireCounter()}ms.`\n ).setError(error);\n }\n log(4, '[pool] Acquired a worker handle.');\n\n if (!workerHandle.page) {\n throw new ExportError(\n 'Resolved worker page is invalid: the pool setup is wonky.'\n );\n }\n\n // Save the start time\n let workStart = new Date().getTime();\n\n log(4, `[pool] Starting work on pool entry with ID ${workerHandle.id}.`);\n\n // Perform an export on a puppeteer level\n const exportCounter = measureTime();\n const result = await puppeteerExport(workerHandle.page, chart, options);\n\n // Check if it's an error\n if (result instanceof Error) {\n // NOTE: If there's a rasterization timeout, we want need to flush the page.\n // This is because the page may be in a state where it's waiting for\n // the screenshot to finish even though the timeout has occured.\n // Which of course causes a lot of issues with the event system,\n // and page consistency.\n //\n // NOTE: Only page.screenshot will throw this, timeouts for PDF's are\n // handled by the page.pdf function itself.\n //\n // ...yes, this is ugly.\n if (result.message === 'Rasterization timeout') {\n workerHandle.workCount = poolConfig.workLimit + 1;\n workerHandle.page = null;\n }\n\n if (\n result.name === 'TimeoutError' ||\n result.message === 'Rasterization timeout'\n ) {\n throw new ExportError(\n 'Rasterization timeout: your chart may be too complex or large, and failed to render within the allotted time.'\n ).setError(result);\n } else {\n throw new ExportError(\n (options.payload?.requestId\n ? `For request with ID ${options.payload?.requestId} - `\n : '') + `Error encountered during export: ${exportCounter()}ms.`\n ).setError(result);\n }\n }\n\n // Check the Puppeteer export time\n if (options.server.benchmarking) {\n log(\n 5,\n options.payload?.requestId\n ? `[benchmark] Request with ID ${options.payload?.requestId} -`\n : '[benchmark]',\n `Exported a chart sucessfully: ${exportCounter()}ms.`\n );\n }\n\n // Release the resource back to the pool\n pool.release(workerHandle);\n\n // Used for statistics in averageTime and processedWorkCount, which\n // in turn is used by the /health route.\n const workEnd = new Date().getTime();\n const exportTime = workEnd - workStart;\n stats.timeSpent += exportTime;\n stats.spentAverage = stats.timeSpent / ++stats.performedExports;\n\n log(4, `[pool] Work completed in ${exportTime} ms.`);\n\n // Otherwise return the result\n return {\n result,\n options\n };\n } catch (error) {\n ++stats.droppedExports;\n\n if (workerHandle) {\n pool.release(workerHandle);\n }\n\n throw new ExportError(`[pool] In pool.postWork: ${error.message}`).setError(\n error\n );\n }\n};\n\n/**\n * Retrieves the current pool instance.\n *\n * @returns {Object|null} The current pool instance if initialized, or null\n * if the pool has not been created.\n */\nexport const getPool = () => pool;\n\n/**\n * Retrieves pool information in JSON format, including minimum and maximum\n * workers, available workers, workers in use, and pending acquire requests.\n *\n * @returns {Object} Pool information in JSON format.\n */\nexport const getPoolInfoJSON = () => ({\n min: pool.min,\n max: pool.max,\n all: pool.numFree() + pool.numUsed(),\n available: pool.numFree(),\n used: pool.numUsed(),\n pending: pool.numPendingAcquires()\n});\n\n/**\n * Logs information about the current state of the pool, including the minimum\n * and maximum workers, available workers, workers in use, and pending acquire\n * requests.\n */\nexport function getPoolInfo() {\n const { min, max, all, available, used, pending } = getPoolInfoJSON();\n\n log(5, `[pool] The minimum number of resources allowed by pool: ${min}.`);\n log(5, `[pool] The maximum number of resources allowed by pool: ${max}.`);\n log(5, `[pool] The number of all created resources: ${all}.`);\n log(5, `[pool] The number of available resources: ${available}.`);\n log(5, `[pool] The number of acquired resources: ${used}.`);\n log(5, `[pool] The number of resources waiting to be acquired: ${pending}.`);\n}\n\nexport default {\n initPool,\n killPool,\n postWork,\n getPool,\n getPoolInfo,\n getPoolInfoJSON,\n getStats: () => stats\n};\n","/*******************************************************************************\n\nHighcharts Export Server\n\nCopyright (c) 2016-2024, Highsoft\n\nLicenced under the MIT licence.\n\nAdditionally a valid Highcharts license is required for use.\n\nSee LICENSE file in root for details.\n\n*******************************************************************************/\n\nimport { readFileSync, writeFileSync } from 'fs';\n\nimport { getOptions, initExportSettings } from './config.js';\nimport { log, logWithStack } from './logger.js';\nimport { killPool, postWork, stats } from './pool.js';\nimport {\n fixType,\n handleResources,\n isCorrectJSON,\n optionsStringify,\n roundNumber,\n toBoolean,\n wrapAround\n} from './utils.js';\nimport { sanitize } from './sanitize.js';\nimport ExportError from './errors/ExportError.js';\n\nlet allowCodeExecution = false;\n\n/**\n * Starts an export process. The `settings` contains final options gathered\n * from all possible sources (config, env, cli, json). The `endCallback` is\n * called when the export is completed, with an error object as the first\n * argument and the second containing the base64 respresentation of a chart.\n *\n * @param {Object} settings - The settings object containing export\n * configuration.\n * @param {function} endCallback - The callback function to be invoked upon\n * finalizing work or upon error occurance of the exporting process.\n *\n * @returns {void} This function does not return a value directly; instead,\n * it communicates results via the endCallback.\n */\nexport const startExport = async (settings, endCallback) => {\n // Starting exporting process message\n log(4, '[chart] Starting the exporting process.');\n\n // Initialize options\n const options = initExportSettings(settings, getOptions());\n\n // Get the export options\n const exportOptions = options.export;\n\n // If SVG is an input (argument can be sent only by the request)\n if (options.payload?.svg && options.payload.svg !== '') {\n try {\n log(4, '[chart] Attempting to export from a SVG input.');\n\n const result = exportAsString(\n sanitize(options.payload.svg), // #209\n options,\n endCallback\n );\n\n ++stats.exportFromSvgAttempts;\n return result;\n } catch (error) {\n return endCallback(\n new ExportError('[chart] Error loading SVG input.').setError(error)\n );\n }\n }\n\n // Export using options from the file\n if (exportOptions.infile && exportOptions.infile.length) {\n // Try to read the file to get the string representation\n try {\n log(4, '[chart] Attempting to export from an input file.');\n options.export.instr = readFileSync(exportOptions.infile, 'utf8');\n return exportAsString(options.export.instr.trim(), options, endCallback);\n } catch (error) {\n return endCallback(\n new ExportError('[chart] Error loading input file.').setError(error)\n );\n }\n }\n\n // Export with options from the raw representation\n if (\n (exportOptions.instr && exportOptions.instr !== '') ||\n (exportOptions.options && exportOptions.options !== '')\n ) {\n try {\n log(4, '[chart] Attempting to export from a raw input.');\n\n // Use whichever one is available\n exportOptions.instr = exportOptions.instr || exportOptions.options;\n\n // Perform a direct inject when forced\n if (toBoolean(options.customLogic?.allowCodeExecution)) {\n return doStraightInject(options, endCallback);\n }\n\n // Either try to parse to JSON first or do the direct export\n return typeof exportOptions.instr === 'string'\n ? exportAsString(exportOptions.instr.trim(), options, endCallback)\n : doExport(\n options,\n exportOptions.instr || exportOptions.options,\n endCallback\n );\n } catch (error) {\n return endCallback(\n new ExportError('[chart] Error loading raw input.').setError(error)\n );\n }\n }\n\n // No input specified, pass an error message to the callback\n return endCallback(\n new ExportError(\n `[chart] No valid input specified. Check if at least one of the following parameters is correctly set: 'infile', 'instr', 'options', or 'svg'.`\n )\n );\n};\n\n/**\n * Starts a batch export process for multiple charts based on the information\n * in the batch option. The batch is a string in the following format:\n * \"infile1.json=outfile1.png;infile2.json=outfile2.png;...\"\n *\n * @param {Object} options - The options object containing configuration for\n * a batch export.\n *\n * @returns {Promise} A Promise that resolves once the batch export\n * process is completed.\n *\n * @throws {ExportError} Throws an ExportError if an error occurs during\n * any of the batch export process.\n */\nexport const batchExport = async (options) => {\n const batchFunctions = [];\n\n // Split and pair the --batch arguments\n for (let pair of options.export.batch.split(';')) {\n pair = pair.split('=');\n if (pair.length === 2) {\n batchFunctions.push(\n startExport(\n {\n ...options,\n export: {\n ...options.export,\n infile: pair[0],\n outfile: pair[1]\n }\n },\n (error, info) => {\n // Throw an error\n if (error) {\n throw error;\n }\n\n // Save the base64 from a buffer to a correct image file\n writeFileSync(\n info.options.export.outfile,\n info.options.export.type !== 'svg'\n ? Buffer.from(info.result, 'base64')\n : info.result\n );\n }\n )\n );\n }\n }\n\n try {\n // Await all exports are done\n await Promise.all(batchFunctions);\n\n // Kill pool and close browser after finishing batch export\n await killPool();\n } catch (error) {\n throw new ExportError(\n '[chart] Error encountered during batch export.'\n ).setError(error);\n }\n};\n\n/**\n * Starts a single export process based on the specified options.\n *\n * @param {Object} options - The options object containing configuration for\n * a single export.\n *\n * @returns {Promise} A Promise that resolves once the single export\n * process is completed.\n *\n * @throws {ExportError} Throws an ExportError if an error occurs during\n * the single export process.\n */\nexport const singleExport = async (options) => {\n // Use instr or its alias, options\n options.export.instr = options.export.instr || options.export.options;\n\n // Perform an export\n await startExport(options, async (error, info) => {\n // Exit process when error\n if (error) {\n throw error;\n }\n\n const { outfile, type } = info.options.export;\n\n // Save the base64 from a buffer to a correct image file\n writeFileSync(\n outfile || `chart.${type}`,\n type !== 'svg' ? Buffer.from(info.result, 'base64') : info.result\n );\n\n // Kill pool and close browser after finishing single export\n await killPool();\n });\n};\n\n/**\n * Determines the size and scale for chart export based on the provided options.\n *\n * @param {Object} options - The options object containing configuration for\n * chart export.\n *\n * @returns {Object} An object containing the calculated height, width,\n * and scale for the chart export.\n */\nexport const findChartSize = (options) => {\n const { chart, exporting } =\n options.export?.options || isCorrectJSON(options.export?.instr);\n\n // See if globalOptions holds chart or exporting size\n const globalOptions = isCorrectJSON(options.export?.globalOptions);\n\n // Secure scale value\n let scale =\n options.export?.scale ||\n exporting?.scale ||\n globalOptions?.exporting?.scale ||\n options.export?.defaultScale ||\n 1;\n\n // the scale cannot be lower than 0.1 and cannot be higher than 5.0\n scale = Math.max(0.1, Math.min(scale, 5.0));\n\n // we want to round the numbers like 0.23234 -> 0.23\n scale = roundNumber(scale, 2);\n\n // Find chart size and scale\n const size = {\n height:\n options.export?.height ||\n exporting?.sourceHeight ||\n chart?.height ||\n globalOptions?.exporting?.sourceHeight ||\n globalOptions?.chart?.height ||\n options.export?.defaultHeight ||\n 400,\n width:\n options.export?.width ||\n exporting?.sourceWidth ||\n chart?.width ||\n globalOptions?.exporting?.sourceWidth ||\n globalOptions?.chart?.width ||\n options.export?.defaultWidth ||\n 600,\n scale\n };\n\n // Get rid of potential px and %\n for (let [param, value] of Object.entries(size)) {\n size[param] =\n typeof value === 'string' ? +value.replace(/px|%/gi, '') : value;\n }\n return size;\n};\n\n/**\n * Function for finalizing options before export.\n *\n * @param {Object} options - The options object containing configuration for\n * the export process.\n * @param {Object} chartJson - The JSON representation of the chart.\n * @param {Function} endCallback - The callback function to be called upon\n * completion or error.\n * @param {string} svg - The SVG representation of the chart.\n *\n * @returns {Promise} A Promise that resolves once the export process\n * is completed.\n */\nconst doExport = async (options, chartJson, endCallback, svg) => {\n let { export: exportOptions, customLogic: customLogicOptions } = options;\n\n const allowCodeExecutionScoped =\n typeof customLogicOptions.allowCodeExecution === 'boolean'\n ? customLogicOptions.allowCodeExecution\n : allowCodeExecution;\n\n if (!customLogicOptions) {\n customLogicOptions = options.customLogic = {};\n } else if (allowCodeExecutionScoped) {\n if (typeof options.customLogic.resources === 'string') {\n // Process resources\n options.customLogic.resources = handleResources(\n options.customLogic.resources,\n toBoolean(options.customLogic.allowFileResources)\n );\n } else if (!options.customLogic.resources) {\n try {\n const resources = readFileSync('resources.json', 'utf8');\n options.customLogic.resources = handleResources(\n resources,\n toBoolean(options.customLogic.allowFileResources)\n );\n } catch (error) {\n log(2, `[chart] Unable to load the default resources.json file.`);\n }\n }\n }\n\n // If the allowCodeExecution flag isn't set, we should refuse the usage\n // of callback, resources, and custom code. Additionally, the worker will\n // refuse to run arbitrary JavaScript. Prioritized should be the scoped\n // option, then we should take a look at the overall pool option.\n if (!allowCodeExecutionScoped && customLogicOptions) {\n if (\n customLogicOptions.callback ||\n customLogicOptions.resources ||\n customLogicOptions.customCode\n ) {\n // Send back a friendly message saying that the exporter does not support\n // these settings.\n return endCallback(\n new ExportError(\n `[chart] The 'callback', 'resources' and 'customCode' options have been disabled for this server.`\n )\n );\n }\n\n // Reset all additional custom code\n customLogicOptions.callback = false;\n customLogicOptions.resources = false;\n customLogicOptions.customCode = false;\n }\n\n // Clean properties to keep it lean and mean\n if (chartJson) {\n chartJson.chart = chartJson.chart || {};\n chartJson.exporting = chartJson.exporting || {};\n chartJson.exporting.enabled = false;\n }\n\n exportOptions.constr = exportOptions.constr || 'chart';\n exportOptions.type = fixType(exportOptions.type, exportOptions.outfile);\n if (exportOptions.type === 'svg') {\n exportOptions.width = false;\n }\n\n // Prepare global and theme options\n ['globalOptions', 'themeOptions'].forEach((optionsName) => {\n try {\n if (exportOptions && exportOptions[optionsName]) {\n if (\n typeof exportOptions[optionsName] === 'string' &&\n exportOptions[optionsName].endsWith('.json')\n ) {\n exportOptions[optionsName] = isCorrectJSON(\n readFileSync(exportOptions[optionsName], 'utf8'),\n true\n );\n } else {\n exportOptions[optionsName] = isCorrectJSON(\n exportOptions[optionsName],\n true\n );\n }\n }\n } catch (error) {\n exportOptions[optionsName] = {};\n logWithStack(2, error, `[chart] The '${optionsName}' cannot be loaded.`);\n }\n });\n\n // Prepare the customCode\n if (customLogicOptions.allowCodeExecution) {\n try {\n customLogicOptions.customCode = wrapAround(\n customLogicOptions.customCode,\n customLogicOptions.allowFileResources\n );\n } catch (error) {\n logWithStack(2, error, `[chart] The 'customCode' cannot be loaded.`);\n }\n }\n\n // Get the callback\n if (\n customLogicOptions &&\n customLogicOptions.callback &&\n customLogicOptions.callback?.indexOf('{') < 0\n ) {\n // The allowFileResources is always set to false for HTTP requests to avoid\n // injecting arbitrary files from the fs\n if (customLogicOptions.allowFileResources) {\n try {\n customLogicOptions.callback = readFileSync(\n customLogicOptions.callback,\n 'utf8'\n );\n } catch (error) {\n customLogicOptions.callback = false;\n logWithStack(2, error, `[chart] The 'callback' cannot be loaded.`);\n }\n } else {\n customLogicOptions.callback = false;\n }\n }\n\n // Size search\n options.export = {\n ...options.export,\n ...findChartSize(options)\n };\n\n // Post the work to the pool\n try {\n const result = await postWork(\n exportOptions.strInj || chartJson || svg,\n options\n );\n return endCallback(false, result);\n } catch (error) {\n return endCallback(error);\n }\n};\n\n/**\n * Performs a direct inject of options before export. The function attempts\n * to stringify the provided options and removes unnecessary characters,\n * ensuring a clean and formatted input. The resulting string is saved as\n * a \"stright inject\" string in the export options. It then invokes the\n * doExport function with the updated options.\n *\n * IMPORTANT: Dangerous and must be used deliberately by someone who sets up\n * a server (see the --allowCodeExecution option).\n *\n * @param {Object} options - The export options containing the input\n * to be injected.\n * @param {function} endCallback - The callback function to be invoked\n * at the end of the process.\n *\n * @returns {Promise} A Promise that resolves with the result of the export\n * operation or rejects with an error if any issues occur during the process.\n */\nconst doStraightInject = (options, endCallback) => {\n try {\n let strInj;\n let instr = options.export.instr || options.export.options;\n\n if (typeof instr !== 'string') {\n // Try to stringify options\n strInj = instr = optionsStringify(\n instr,\n options.customLogic?.allowCodeExecution\n );\n }\n strInj = instr.replaceAll(/\\t|\\n|\\r/g, '').trim();\n\n // Get rid of the ;\n if (strInj[strInj.length - 1] === ';') {\n strInj = strInj.substring(0, strInj.length - 1);\n }\n\n // Save as stright inject string\n options.export.strInj = strInj;\n return doExport(options, false, endCallback);\n } catch (error) {\n return endCallback(\n new ExportError(\n `[chart] Malformed input detected for ${options.export?.requestId || '?'}. Please make sure that your JSON/JavaScript options are sent using the \"options\" attribute, and that if you're using SVG, it is unescaped.`\n ).setError(error)\n );\n }\n};\n\n/**\n * Exports a string based on the provided options and invokes an end callback.\n *\n * @param {string} stringToExport - The string content to be exported.\n * @param {Object} options - Export options, including customLogic with\n * allowCodeExecution flag.\n * @param {Function} endCallback - Callback function to be invoked at the end\n * of the export process.\n *\n * @returns {any} Result of the export process or an error if encountered.\n */\nconst exportAsString = (stringToExport, options, endCallback) => {\n const { allowCodeExecution } = options.customLogic;\n\n // Check if it is SVG\n if (\n stringToExport.indexOf('= 0 ||\n stringToExport.indexOf('= 0\n ) {\n log(4, '[chart] Parsing input as SVG.');\n return doExport(options, false, endCallback, stringToExport);\n }\n\n try {\n // Try to parse to JSON and call the doExport function\n const chartJSON = JSON.parse(stringToExport.replaceAll(/\\t|\\n|\\r/g, ' '));\n\n // If a correct JSON, do the export\n return doExport(options, chartJSON, endCallback);\n } catch (error) {\n // Not a valid JSON\n if (toBoolean(allowCodeExecution)) {\n return doStraightInject(options, endCallback);\n } else {\n // Do not allow straight injection without the allowCodeExecution flag\n return endCallback(\n new ExportError(\n '[chart] Only JSON configurations and SVG are allowed for this server. If this is your server, JavaScript custom code can be enabled by starting the server with the --allowCodeExecution flag.'\n ).setError(error)\n );\n }\n }\n};\n\n/**\n * Retrieves and returns the current status of code execution permission.\n *\n * @returns {any} The value of allowCodeExecution.\n */\nexport const getAllowCodeExecution = () => allowCodeExecution;\n\n/**\n * Sets the code execution permission based on the provided boolean value.\n *\n * @param {any} value - The value to be converted and assigned\n * to allowCodeExecution.\n */\nexport const setAllowCodeExecution = (value) => {\n allowCodeExecution = toBoolean(value);\n};\n\nexport default {\n batchExport,\n singleExport,\n getAllowCodeExecution,\n setAllowCodeExecution,\n startExport,\n findChartSize\n};\n","/*******************************************************************************\n\nHighcharts Export Server\n\nCopyright (c) 2016-2024, Highsoft\n\nLicenced under the MIT licence.\n\nAdditionally a valid Highcharts license is required for use.\n\nSee LICENSE file in root for details.\n\n*******************************************************************************/\n\n/**\n * @overview Used to sanitize the strings coming from the exporting module\n * to prevent XSS attacks (with the DOMPurify library).\n **/\n\nimport { JSDOM } from 'jsdom';\nimport DOMPurify from 'dompurify';\n\nimport { envs } from './envs.js';\n/**\n * Sanitizes a given HTML string by removing tags and any content within them.\n *\n * @param {string} input The HTML string to be sanitized.\n * @returns {string} The sanitized HTML string.\n */\nexport function sanitize(input) {\n const forbidden = [];\n\n if (!envs.OTHER_ALLOW_XLINK) {\n forbidden.push('xlink:href');\n }\n\n const window = new JSDOM('').window;\n const purify = DOMPurify(window);\n return purify.sanitize(input, {\n ADD_TAGS: ['foreignObject'],\n FORBID_ATTR: forbidden\n });\n}\n\nexport default sanitize;\n","/*******************************************************************************\n\nHighcharts Export Server\n\nCopyright (c) 2016-2024, Highsoft\n\nLicenced under the MIT licence.\n\nAdditionally a valid Highcharts license is required for use.\n\nSee LICENSE file in root for details.\n\n*******************************************************************************/\n\nimport { log } from './logger.js';\n\n// Array that contains ids of all ongoing intervals\nconst intervalIds = [];\n\n/**\n * Adds id of a setInterval to the intervalIds array.\n *\n * @param {NodeJS.Timeout} id - Id of an interval.\n */\nexport const addInterval = (id) => {\n intervalIds.push(id);\n};\n\n/**\n * Clears all of ongoing intervals by ids gathered in the intervalIds array.\n */\nexport const clearAllIntervals = () => {\n log(4, `[server] Clearing all registered intervals.`);\n for (const id of intervalIds) {\n clearInterval(id);\n }\n};\n\nexport default {\n addInterval,\n clearAllIntervals\n};\n","import { envs } from '../envs.js';\nimport { logWithStack } from '../logger.js';\n\n/**\n * Middleware for logging errors with stack trace and handling error response.\n *\n * @param {Error} error - The error object.\n * @param {Express.Request} req - The Express request object.\n * @param {Express.Response} res - The Express response object.\n * @param {Function} next - The next middleware function.\n */\nconst logErrorMiddleware = (error, req, res, next) => {\n // Display the error with stack in a correct format\n logWithStack(1, error);\n\n // Delete the stack for the environment other than the development\n if (envs.OTHER_NODE_ENV !== 'development') {\n delete error.stack;\n }\n\n // Call the returnErrorMiddleware\n next(error);\n};\n\n/**\n * Middleware for returning error response.\n *\n * @param {Error} error - The error object.\n * @param {Express.Request} req - The Express request object.\n * @param {Express.Response} res - The Express response object.\n * @param {Function} next - The next middleware function.\n */\nconst returnErrorMiddleware = (error, req, res, next) => {\n // Gather all requied information for the response\n const { statusCode: stCode, status, message, stack } = error;\n const statusCode = stCode || status || 400;\n\n // Set and return response\n res.status(statusCode).json({ statusCode, message, stack });\n};\n\nexport default (app) => {\n // Add log error middleware\n app.use(logErrorMiddleware);\n\n // Add set status and return error middleware\n app.use(returnErrorMiddleware);\n};\n","/*******************************************************************************\n\nHighcharts Export Server\n\nCopyright (c) 2016-2024, Highsoft\n\nLicenced under the MIT licence.\n\nAdditionally a valid Highcharts license is required for use.\n\nSee LICENSE file in root for details.\n\n*******************************************************************************/\n\nimport rateLimit from 'express-rate-limit';\n\nimport { log } from '../logger.js';\n\n/**\n * Middleware for enabling rate limiting on the specified Express app.\n *\n * @param {Express} app - The Express app instance.\n * @param {Object} limitConfig - Configuration options for rate limiting.\n */\nexport default (app, limitConfig) => {\n const msg =\n 'Too many requests, you have been rate limited. Please try again later.';\n\n // Options for the rate limiter\n const rateOptions = {\n max: limitConfig.maxRequests || 30,\n window: limitConfig.window || 1,\n delay: limitConfig.delay || 0,\n trustProxy: limitConfig.trustProxy || false,\n skipKey: limitConfig.skipKey || false,\n skipToken: limitConfig.skipToken || false\n };\n\n // Set if behind a proxy\n if (rateOptions.trustProxy) {\n app.enable('trust proxy');\n }\n\n // Create a limiter\n const limiter = rateLimit({\n windowMs: rateOptions.window * 60 * 1000,\n // Limit each IP to 100 requests per windowMs\n max: rateOptions.max,\n // Disable delaying, full speed until the max limit is reached\n delayMs: rateOptions.delay,\n handler: (request, response) => {\n response.format({\n json: () => {\n response.status(429).send({ message: msg });\n },\n default: () => {\n response.status(429).send(msg);\n }\n });\n },\n skip: (request) => {\n // Allow bypassing the limiter if a valid key/token has been sent\n if (\n rateOptions.skipKey !== false &&\n rateOptions.skipToken !== false &&\n request.query.key === rateOptions.skipKey &&\n request.query.access_token === rateOptions.skipToken\n ) {\n log(4, '[rate limiting] Skipping rate limiter.');\n return true;\n }\n return false;\n }\n });\n\n // Use a limiter as a middleware\n app.use(limiter);\n\n log(\n 3,\n `[rate limiting] Enabled rate limiting with ${rateOptions.max} requests per ${rateOptions.window} minute for each IP, trusting proxy: ${rateOptions.trustProxy}.`\n );\n};\n","import ExportError from './ExportError.js';\n\nclass HttpError extends ExportError {\n constructor(message, status) {\n super(message);\n this.status = this.statusCode = status;\n }\n\n setStatus(status) {\n this.status = status;\n return this;\n }\n}\n\nexport default HttpError;\n","/*******************************************************************************\n\nHighcharts Export Server\n\nCopyright (c) 2016-2024, Highsoft\n\nLicenced under the MIT licence.\n\nAdditionally a valid Highcharts license is required for use.\n\nSee LICENSE file in root for details.\n\n*******************************************************************************/\n\nimport { updateVersion, version } from '../../cache.js';\nimport { envs } from '../../envs.js';\n\nimport HttpError from '../../errors/HttpError.js';\n\n/**\n * Adds the POST /change_hc_version/:newVersion route that can be utilized to modify\n * the Highcharts version on the server.\n *\n * TODO: Add auth token and connect to API\n */\nexport default (app) =>\n !app\n ? false\n : app.post(\n '/version/change/:newVersion',\n async (request, response, next) => {\n try {\n const adminToken = envs.HIGHCHARTS_ADMIN_TOKEN;\n\n // Check the existence of the token\n if (!adminToken || !adminToken.length) {\n throw new HttpError(\n 'The server is not configured to perform run-time version changes: HIGHCHARTS_ADMIN_TOKEN is not set.',\n 401\n );\n }\n\n // Check if the hc-auth header contain a correct token\n const token = request.get('hc-auth');\n if (!token || token !== adminToken) {\n throw new HttpError(\n 'Invalid or missing token: Set the token in the hc-auth header.',\n 401\n );\n }\n\n // Compare versions\n const newVersion = request.params.newVersion;\n if (newVersion) {\n try {\n // eslint-disable-next-line import/no-named-as-default-member\n await updateVersion(newVersion);\n } catch (error) {\n throw new HttpError(\n `Version change: ${error.message}`,\n error.statusCode\n ).setError(error);\n }\n\n // Success\n response.status(200).send({\n statusCode: 200,\n version: version(),\n message: `Successfully updated Highcharts to version: ${newVersion}.`\n });\n } else {\n // No version specified\n throw new HttpError('No new version supplied.', 400);\n }\n } catch (error) {\n next(error);\n }\n }\n );\n","/*******************************************************************************\n\nHighcharts Export Server\n\nCopyright (c) 2016-2024, Highsoft\n\nLicenced under the MIT licence.\n\nAdditionally a valid Highcharts license is required for use.\n\nSee LICENSE file in root for details.\n\n*******************************************************************************/\n\nimport { v4 as uuid } from 'uuid';\n\nimport { getAllowCodeExecution, startExport } from '../../chart.js';\nimport { getOptions, mergeConfigOptions } from '../../config.js';\nimport { log } from '../../logger.js';\nimport {\n fixType,\n isCorrectJSON,\n isObjectEmpty,\n isPrivateRangeUrlFound,\n optionsStringify,\n measureTime\n} from '../../utils.js';\n\nimport HttpError from '../../errors/HttpError.js';\n\n// Reversed MIME types\nconst reversedMime = {\n png: 'image/png',\n jpeg: 'image/jpeg',\n gif: 'image/gif',\n pdf: 'application/pdf',\n svg: 'image/svg+xml'\n};\n\n// The requests counter\nlet requestsCounter = 0;\n\n// The array of callbacks to call before a request\nconst beforeRequest = [];\n\n// The array of callbacks to call after a request\nconst afterRequest = [];\n\n/**\n * Invokes an array of callback functions with specified parameters, allowing\n * customization of request handling.\n *\n * @param {Function[]} callbacks - An array of callback functions\n * to be executed.\n * @param {Express.Request} request - The Express request object.\n * @param {Express.Response} response - The Express response object.\n * @param {Object} data - An object containing parameters like id, uniqueId,\n * type, and body.\n *\n * @returns {boolean} - Returns a boolean indicating the overall result\n * of the callback invocations.\n */\nconst doCallbacks = (callbacks, request, response, data) => {\n let result = true;\n const { id, uniqueId, type, body } = data;\n\n callbacks.some((callback) => {\n if (callback) {\n let callResponse = callback(request, response, id, uniqueId, type, body);\n\n if (callResponse !== undefined && callResponse !== true) {\n result = callResponse;\n }\n\n return true;\n }\n });\n\n return result;\n};\n\n/**\n * Handles the export requests from the client.\n *\n * @param {Express.Request} request - The Express request object.\n * @param {Express.Response} response - The Express response object.\n * @param {Function} next - The next middleware function.\n *\n * @returns {Promise} - A promise that resolves once the export process\n * is complete.\n */\nconst exportHandler = async (request, response, next) => {\n try {\n // Start counting time\n const stopCounter = measureTime();\n\n // Create a unique ID for a request\n const uniqueId = uuid().replace(/-/g, '');\n\n // Get the current server's general options\n const defaultOptions = getOptions();\n\n const body = request.body;\n const id = ++requestsCounter;\n\n let type = fixType(body.type);\n\n // Throw 'Bad Request' if there's no body\n if (!body || isObjectEmpty(body)) {\n throw new HttpError(\n 'The request body is required. Please ensure that your Content-Type header is correct (accepted types are application/json and multipart/form-data).',\n 400\n );\n }\n\n // All of the below can be used\n let instr = isCorrectJSON(body.infile || body.options || body.data);\n\n // Throw 'Bad Request' if there's no JSON or SVG to export\n if (!instr && !body.svg) {\n log(\n 2,\n `The request with ID ${uniqueId} from ${\n request.headers['x-forwarded-for'] || request.connection.remoteAddress\n } was incorrect:\n Content-Type: ${request.headers['content-type']}. \n Chart constructor: ${body.constr}.\n Dimensions: ${body.width}x${body.height} @ ${body.scale} scale.\n Type: ${type}.\n Is SVG set? ${typeof body.svg !== 'undefined'}.\n B64? ${typeof body.b64 !== 'undefined'}.\n No download? ${typeof body.noDownload !== 'undefined'}.\n\n Payload received: ${JSON.stringify(body.infile || body.options || body.data || body.svg)}\n\n `\n );\n\n throw new HttpError(\n \"No correct chart data found. Ensure that you are using either application/json or multipart/form-data headers. If sending JSON, make sure the chart data is in the 'infile', 'options', or 'data' attribute. If sending SVG, ensure it is in the 'svg' attribute.\",\n 400\n );\n }\n\n let callResponse = false;\n\n // Call the before request functions\n callResponse = doCallbacks(beforeRequest, request, response, {\n id,\n uniqueId,\n type,\n body\n });\n\n // Block the request if one of a callbacks failed\n if (callResponse !== true) {\n return response.send(callResponse);\n }\n\n let connectionAborted = false;\n\n // In case the connection is closed, force to abort further actions\n request.socket.on('close', (hadErrors) => {\n if (hadErrors) {\n connectionAborted = true;\n }\n });\n\n log(4, `[export] Got an incoming HTTP request with ID ${uniqueId}.`);\n\n body.constr = (typeof body.constr === 'string' && body.constr) || 'chart';\n\n // Gather and organize options from the payload\n const requestOptions = {\n export: {\n instr,\n type,\n constr: body.constr[0].toLowerCase() + body.constr.substr(1),\n height: body.height,\n width: body.width,\n scale: body.scale || defaultOptions.export.scale,\n globalOptions: isCorrectJSON(body.globalOptions, true),\n themeOptions: isCorrectJSON(body.themeOptions, true)\n },\n customLogic: {\n allowCodeExecution: getAllowCodeExecution(),\n allowFileResources: false,\n resources: isCorrectJSON(body.resources, true),\n callback: body.callback,\n customCode: body.customCode\n }\n };\n\n if (instr) {\n // Stringify JSON with options\n requestOptions.export.instr = optionsStringify(\n instr,\n requestOptions.customLogic.allowCodeExecution\n );\n }\n\n // Merge the request options into default ones\n const options = mergeConfigOptions(defaultOptions, requestOptions);\n\n // Save the JSON if exists\n options.export.options = instr;\n\n // Lastly, add the server specific arguments into options as payload\n options.payload = {\n svg: body.svg || false,\n b64: body.b64 || false,\n noDownload: body.noDownload || false,\n requestId: uniqueId\n };\n\n // Test xlink:href elements from payload's SVG\n if (body.svg && isPrivateRangeUrlFound(options.payload.svg)) {\n throw new HttpError(\n 'SVG potentially contain at least one forbidden URL in xlink:href element. Please review the SVG content and ensure that all referenced URLs comply with security policies.',\n 400\n );\n }\n\n // Start the export process\n await startExport(options, (error, info) => {\n // Remove the close event from the socket\n request.socket.removeAllListeners('close');\n\n // After the whole exporting process\n if (defaultOptions.server.benchmarking) {\n log(\n 5,\n `[benchmark] Request with ID ${uniqueId} - After the whole exporting process: ${stopCounter()}ms.`\n );\n }\n\n // If the connection was closed, do nothing\n if (connectionAborted) {\n return log(\n 3,\n `[export] The client closed the connection before the chart finished processing.`\n );\n }\n\n // If error, log it and send it to the error middleware\n if (error) {\n throw error;\n }\n\n // If data is missing, log the message and send it to the error middleware\n if (!info || !info.result) {\n throw new HttpError(\n `Unexpected return from chart generation. Please check your request data. For the request with ID ${uniqueId}, the result is ${info.result}.`,\n 400\n );\n }\n\n // Get the type from options\n type = info.options.export.type;\n\n // The after request callbacks\n doCallbacks(afterRequest, request, response, { id, body: info.result });\n\n if (info.result) {\n // If only base64 is required, return it\n if (body.b64) {\n // SVG Exception for the Highcharts 11.3.0 version\n if (type === 'pdf' || type == 'svg') {\n return response.send(\n Buffer.from(info.result, 'utf8').toString('base64')\n );\n }\n\n return response.send(info.result);\n }\n\n // Set correct content type\n response.header('Content-Type', reversedMime[type] || 'image/png');\n\n // Decide whether to download or not chart file\n if (!body.noDownload) {\n response.attachment(\n `${request.params.filename || request.body.filename || 'chart'}.${\n type || 'png'\n }`\n );\n }\n\n // If SVG, return plain content\n return type === 'svg'\n ? response.send(info.result)\n : response.send(Buffer.from(info.result, 'base64'));\n }\n });\n } catch (error) {\n next(error);\n }\n};\n\nexport default (app) => {\n /**\n * Adds the POST / a route for handling POST requests at the root endpoint.\n */\n app.post('/', exportHandler);\n\n /**\n * Adds the POST /:filename a route for handling POST requests with\n * a specified filename parameter.\n */\n app.post('/:filename', exportHandler);\n};\n","/*******************************************************************************\n\nHighcharts Export Server\n\nCopyright (c) 2016-2024, Highsoft\n\nLicenced under the MIT licence.\n\nAdditionally a valid Highcharts license is required for use.\n\nSee LICENSE file in root for details.\n\n*******************************************************************************/\n\nimport { readFileSync } from 'fs';\nimport { join as pather } from 'path';\nimport { log } from '../../logger.js';\n\nimport { version } from '../../cache.js';\nimport { addInterval } from '../../intervals.js';\nimport pool from '../../pool.js';\nimport { __dirname } from '../../utils.js';\n\nconst pkgFile = JSON.parse(readFileSync(pather(__dirname, 'package.json')));\n\nconst serverStartTime = new Date();\n\nconst successRates = [];\nconst recordInterval = 60 * 1000; // record every minute\nconst windowSize = 30; // 30 minutes\n\n/**\n * Calculates moving average indicator based on the data from the successRates\n * array.\n *\n * @returns {number} - A moving average for success ratio of the server exports.\n */\nfunction calculateMovingAverage() {\n const sum = successRates.reduce((a, b) => a + b, 0);\n return sum / successRates.length;\n}\n\n/**\n * Starts the interval responsible for calculating current success rate ratio\n * and gathers\n *\n * @returns {NodeJS.Timeout} id - Id of an interval.\n */\nexport const startSuccessRate = () =>\n setInterval(() => {\n const stats = pool.getStats();\n const successRatio =\n stats.exportAttempts === 0\n ? 1\n : (stats.performedExports / stats.exportAttempts) * 100;\n\n successRates.push(successRatio);\n if (successRates.length > windowSize) {\n successRates.shift();\n }\n }, recordInterval);\n\n/**\n * Adds the /health and /success-moving-average routes\n * which output basic stats for the server.\n */\nexport default function addHealthRoutes(app) {\n if (!app) {\n return false;\n }\n\n // Start processing success rate ratio interval and save its id to the array\n // for the graceful clearing on shutdown with injected addInterval funtion\n addInterval(startSuccessRate());\n\n app.get('/health', (_, res) => {\n const stats = pool.getStats();\n const period = successRates.length;\n const movingAverage = calculateMovingAverage();\n\n log(4, '[health.js] GET /health [200] - returning server health.');\n\n res.send({\n status: 'OK',\n bootTime: serverStartTime,\n uptime:\n Math.floor(\n (new Date().getTime() - serverStartTime.getTime()) / 1000 / 60\n ) + ' minutes',\n version: pkgFile.version,\n highchartsVersion: version(),\n averageProcessingTime: stats.spentAverage,\n performedExports: stats.performedExports,\n failedExports: stats.droppedExports,\n exportAttempts: stats.exportAttempts,\n sucessRatio: (stats.performedExports / stats.exportAttempts) * 100,\n // eslint-disable-next-line import/no-named-as-default-member\n pool: pool.getPoolInfoJSON(),\n\n // Moving average\n period,\n movingAverage,\n message:\n isNaN(movingAverage) || !successRates.length\n ? 'Too early to report. No exports made yet. Please check back soon.'\n : `Last ${period} minutes had a success rate of ${movingAverage.toFixed(2)}%.`,\n\n // SVG/JSON attempts\n svgExportAttempts: stats.exportFromSvgAttempts,\n jsonExportAttempts: stats.performedExports - stats.exportFromSvgAttempts\n });\n });\n}\n","/*******************************************************************************\n\nHighcharts Export Server\n\nCopyright (c) 2016-2024, Highsoft\n\nLicenced under the MIT licence.\n\nAdditionally a valid Highcharts license is required for use.\n\nSee LICENSE file in root for details.\n\n*******************************************************************************/\n\nimport { promises as fsPromises } from 'fs';\nimport { posix } from 'path';\n\nimport cors from 'cors';\nimport express from 'express';\nimport http from 'http';\nimport https from 'https';\nimport multer from 'multer';\n\nimport errorHandler from './error.js';\nimport rateLimit from './rate_limit.js';\nimport { log, logWithStack } from '../logger.js';\nimport { __dirname } from '../utils.js';\n\nimport vSwitchRoute from './routes/change_hc_version.js';\nimport exportRoutes from './routes/export.js';\nimport healthRoute from './routes/health.js';\nimport uiRoute from './routes/ui.js';\n\nimport ExportError from '../errors/ExportError.js';\n\n// Array of an active servers\nconst activeServers = new Map();\n\n// Create express app\nconst app = express();\n\n// Disable the X-Powered-By header\napp.disable('x-powered-by');\n\n// Enable CORS support\napp.use(cors());\n\n// Getting a lot of RangeNotSatisfiableError exception.\n// Even though this is a deprecated options, let's try to set it to false.\napp.use((_req, res, next) => {\n res.set('Accept-Ranges', 'none');\n next();\n});\n\n/**\n * Attach error handlers to the server.\n *\n * @param {http.Server} server - The HTTP/HTTPS server instance.\n */\nconst attachServerErrorHandlers = (server) => {\n server.on('clientError', (error, socket) => {\n logWithStack(\n 1,\n error,\n `[server] Client error: ${error.message}, destroying socket.`\n );\n socket.destroy();\n });\n\n server.on('error', (error) => {\n logWithStack(1, error, `[server] Server error: ${error.message}`);\n });\n\n server.on('connection', (socket) => {\n socket.on('error', (error) => {\n logWithStack(1, error, `[server] Socket error: ${error.message}`);\n });\n });\n};\n\n/**\n * Starts an HTTP server based on the provided configuration. The `serverConfig`\n * object contains all server related properties (see the `server` section\n * in the `lib/schemas/config.js` file for a reference).\n *\n * @param {Object} serverConfig - The server configuration object.\n *\n * @throws {ExportError} - Throws an error if the server cannot be configured\n * and started.\n */\nexport const startServer = async (serverConfig) => {\n try {\n // TODO: Read from config/env\n // NOTE:\n // Too big limits lead to timeouts in the export process when the\n // rasterization timeout is set too low.\n const uploadLimitMiB = serverConfig.maxUploadSize || 3;\n const uploadLimitBytes = uploadLimitMiB * 1024 * 1024;\n\n // Enable parsing of form data (files) with Multer package\n const storage = multer.memoryStorage();\n const upload = multer({\n storage,\n limits: {\n fieldSize: uploadLimitBytes\n }\n });\n\n // Enable body parser\n app.use(express.json({ limit: uploadLimitBytes }));\n app.use(express.urlencoded({ extended: true, limit: uploadLimitBytes }));\n\n // Use only non-file multipart form fields\n app.use(upload.none());\n\n // Stop if not enabled\n if (!serverConfig.enable) {\n return false;\n }\n\n // Listen HTTP server\n if (!serverConfig.ssl.force) {\n // Main server instance (HTTP)\n const httpServer = http.createServer(app);\n\n // Attach error handlers and listen to the server\n attachServerErrorHandlers(httpServer);\n\n // Listen\n httpServer.listen(serverConfig.port, serverConfig.host);\n\n // Save the reference to HTTP server\n activeServers.set(serverConfig.port, httpServer);\n\n log(\n 3,\n `[server] Started HTTP server on ${serverConfig.host}:${serverConfig.port}.`\n );\n }\n\n // Listen HTTPS server\n if (serverConfig.ssl.enable) {\n // Set up an SSL server also\n let key, cert;\n\n try {\n // Get the SSL key\n key = await fsPromises.readFile(\n posix.join(serverConfig.ssl.certPath, 'server.key'),\n 'utf8'\n );\n\n // Get the SSL certificate\n cert = await fsPromises.readFile(\n posix.join(serverConfig.ssl.certPath, 'server.crt'),\n 'utf8'\n );\n } catch (error) {\n log(\n 2,\n `[server] Unable to load key/certificate from the '${serverConfig.ssl.certPath}' path. Could not run secured layer server.`\n );\n }\n\n if (key && cert) {\n // Main server instance (HTTPS)\n const httpsServer = https.createServer({ key, cert }, app);\n\n // Attach error handlers and listen to the server\n attachServerErrorHandlers(httpsServer);\n\n // Listen\n httpsServer.listen(serverConfig.ssl.port, serverConfig.host);\n\n // Save the reference to HTTPS server\n activeServers.set(serverConfig.ssl.port, httpsServer);\n\n log(\n 3,\n `[server] Started HTTPS server on ${serverConfig.host}:${serverConfig.ssl.port}.`\n );\n }\n }\n\n // Enable the rate limiter if config says so\n if (\n serverConfig.rateLimiting &&\n serverConfig.rateLimiting.enable &&\n ![0, NaN].includes(serverConfig.rateLimiting.maxRequests)\n ) {\n rateLimit(app, serverConfig.rateLimiting);\n }\n\n // Set up static folder's route\n app.use(express.static(posix.join(__dirname, 'public')));\n\n // Set up routes\n healthRoute(app);\n exportRoutes(app);\n uiRoute(app);\n vSwitchRoute(app);\n\n // Set up centralized error handler\n errorHandler(app);\n } catch (error) {\n throw new ExportError(\n '[server] Could not configure and start the server.'\n ).setError(error);\n }\n};\n\n/**\n * Closes all servers associated with Express app instance.\n */\nexport const closeServers = () => {\n log(4, `[server] Closing all servers.`);\n for (const [port, server] of activeServers) {\n server.close(() => {\n activeServers.delete(port);\n log(4, `[server] Closed server on port: ${port}.`);\n });\n }\n};\n\n/**\n * Get all servers associated with Express app instance.\n *\n * @returns {Array} - Servers associated with Express app instance.\n */\nexport const getServers = () => activeServers;\n\n/**\n * Enable rate limiting for the server.\n *\n * @param {Object} limitConfig - Configuration object for rate limiting.\n */\nexport const enableRateLimiting = (limitConfig) => rateLimit(app, limitConfig);\n\n/**\n * Get the Express instance.\n *\n * @returns {Object} - The Express instance.\n */\nexport const getExpress = () => express;\n\n/**\n * Get the Express app instance.\n *\n * @returns {Object} - The Express app instance.\n */\nexport const getApp = () => app;\n\n/**\n * Apply middleware(s) to a specific path.\n *\n * @param {string} path - The path to which the middleware(s) should be applied.\n * @param {...Function} middlewares - The middleware functions to be applied.\n */\nexport const use = (path, ...middlewares) => {\n app.use(path, ...middlewares);\n};\n\n/**\n * Set up a route with GET method and apply middleware(s).\n *\n * @param {string} path - The route path.\n * @param {...Function} middlewares - The middleware functions to be applied.\n */\nexport const get = (path, ...middlewares) => {\n app.get(path, ...middlewares);\n};\n\n/**\n * Set up a route with POST method and apply middleware(s).\n *\n * @param {string} path - The route path.\n * @param {...Function} middlewares - The middleware functions to be applied.\n */\nexport const post = (path, ...middlewares) => {\n app.post(path, ...middlewares);\n};\n\nexport default {\n startServer,\n closeServers,\n getServers,\n enableRateLimiting,\n getExpress,\n getApp,\n use,\n get,\n post\n};\n","/*******************************************************************************\n\nHighcharts Export Server\n\nCopyright (c) 2016-2024, Highsoft\n\nLicenced under the MIT licence.\n\nAdditionally a valid Highcharts license is required for use.\n\nSee LICENSE file in root for details.\n\n*******************************************************************************/\n\nimport { join } from 'path';\n\nimport { __dirname } from '../../utils.js';\n\n/**\n * Adds the GET / route for a UI when enabled on the export server.\n */\nexport default (app) =>\n !app\n ? false\n : app.get('/', (_request, response) => {\n response.sendFile(join(__dirname, 'public', 'index.html'), {\n acceptRanges: false\n });\n });\n","/*******************************************************************************\n\nHighcharts Export Server\n\nCopyright (c) 2016-2024, Highsoft\n\nLicenced under the MIT licence.\n\nAdditionally a valid Highcharts license is required for use.\n\nSee LICENSE file in root for details.\n\n*******************************************************************************/\n\nimport { clearAllIntervals } from './intervals.js';\nimport { killPool } from './pool.js';\nimport { closeServers } from './server/server.js';\n\n/**\n * Clean up function to trigger before ending process for the graceful shutdown.\n *\n * @param {number} exitCode - An exit code for the process.exit() function.\n */\nexport const shutdownCleanUp = async (exitCode) => {\n // Await freeing all resources\n await Promise.allSettled([\n // Clear all ongoing intervals\n clearAllIntervals(),\n\n // Get available server instances (HTTP/HTTPS) and close them\n closeServers(),\n\n // Close pool along with its workers and the browser instance, if exists\n killPool()\n ]);\n\n // Exit process with a correct code\n process.exit(exitCode);\n};\n\nexport default {\n shutdownCleanUp\n};\n","/*******************************************************************************\n\nHighcharts Export Server\n\nCopyright (c) 2016-2024, Highsoft\n\nLicenced under the MIT licence.\n\nAdditionally a valid Highcharts license is required for use.\n\nSee LICENSE file in root for details.\n\n*******************************************************************************/\n\nimport 'colors';\n\nimport { checkAndUpdateCache } from './cache.js';\nimport {\n batchExport,\n setAllowCodeExecution,\n singleExport,\n startExport\n} from './chart.js';\nimport { mapToNewConfig, manualConfig, setOptions } from './config.js';\nimport {\n initLogging,\n log,\n logWithStack,\n setLogLevel,\n enableFileLogging\n} from './logger.js';\nimport { initPool, killPool } from './pool.js';\nimport { shutdownCleanUp } from './resource_release.js';\nimport server, { startServer } from './server/server.js';\nimport { printLogo, printUsage } from './utils.js';\n\n/**\n * Attaches exit listeners to the process, ensuring proper cleanup of resources\n * and termination on exit signals. Handles 'exit', 'SIGINT', 'SIGTERM', and\n * 'uncaughtException' events.\n */\nconst attachProcessExitListeners = () => {\n log(3, '[process] Attaching exit listeners to the process.');\n\n // Handler for the 'exit'\n process.on('exit', (code) => {\n log(4, `Process exited with code ${code}.`);\n });\n\n // Handler for the 'SIGINT'\n process.on('SIGINT', async (name, code) => {\n log(4, `The ${name} event with code: ${code}.`);\n await shutdownCleanUp(0);\n });\n\n // Handler for the 'SIGTERM'\n process.on('SIGTERM', async (name, code) => {\n log(4, `The ${name} event with code: ${code}.`);\n await shutdownCleanUp(0);\n });\n\n // Handler for the 'SIGHUP'\n process.on('SIGHUP', async (name, code) => {\n log(4, `The ${name} event with code: ${code}.`);\n await shutdownCleanUp(0);\n });\n\n // Handler for the 'uncaughtException'\n process.on('uncaughtException', async (error, name) => {\n logWithStack(1, error, `The ${name} error.`);\n await shutdownCleanUp(1);\n });\n};\n\n/**\n * Initializes the export process. Tasks such as configuring logging, checking\n * cache and sources, and initializing the pool of resources happen during\n * this stage. Function that is required to be called before trying to export charts or setting a server. The `options` is an object that contains all options.\n *\n * @param {Object} options - All export options.\n *\n * @returns {Promise} Promise resolving to the updated export options.\n */\nconst initExport = async (options) => {\n // Set the allowCodeExecution per export module scope\n setAllowCodeExecution(\n options.customLogic && options.customLogic.allowCodeExecution\n );\n\n // Init the logging\n initLogging(options.logging);\n\n // Attach process' exit listeners\n if (options.other.listenToProcessExits) {\n attachProcessExitListeners();\n }\n\n // Check if cache needs to be updated\n await checkAndUpdateCache(options);\n\n // Init the pool\n await initPool({\n pool: options.pool || {\n minWorkers: 1,\n maxWorkers: 1\n },\n puppeteerArgs: options.puppeteer.args || []\n });\n\n // Return updated options\n return options;\n};\n\nexport default {\n // Server\n server,\n startServer,\n\n // Exporting\n initExport,\n singleExport,\n batchExport,\n startExport,\n\n // Pool\n initPool,\n killPool,\n\n // Other\n setOptions,\n shutdownCleanUp,\n\n // Logs\n log,\n logWithStack,\n setLogLevel,\n enableFileLogging,\n\n // Utils\n mapToNewConfig,\n manualConfig,\n printLogo,\n printUsage\n};\n"],"names":["scriptsNames","core","modules","indicators","custom","defaultConfig","puppeteer","args","value","type","description","tempDir","envLink","highcharts","version","cdnURL","coreScripts","moduleScripts","indicatorScripts","customScripts","forceFetch","cachePath","export","infile","instr","options","outfile","constr","defaultHeight","defaultWidth","defaultScale","height","width","scale","globalOptions","themeOptions","batch","rasterizationTimeout","customLogic","allowCodeExecution","allowFileResources","customCode","callback","resources","loadConfig","legacyName","createConfig","server","maxUploadSize","enable","cliName","host","port","benchmarking","proxy","username","password","timeout","rateLimiting","maxRequests","window","delay","trustProxy","skipKey","skipToken","ssl","force","certPath","pool","minWorkers","maxWorkers","workLimit","acquireTimeout","createTimeout","destroyTimeout","idleTimeout","createRetryInterval","reaperInterval","logging","level","file","dest","toConsole","toFile","ui","route","other","nodeEnv","listenToProcessExits","noLogo","hardResetPage","browserShellMode","debug","headless","devtools","listenToConsole","dumpio","slowMo","debuggingPort","promptsConfig","name","message","initial","join","separator","instructions","choices","hint","min","max","round","absoluteProps","nestedArgs","createNestedArgs","obj","propChain","Object","keys","forEach","k","includes","entry","substring","undefined","dotenv","config","v","filterArray","z","string","transform","split","map","trim","filter","length","enum","values","refine","test","isNaN","parseFloat","envs","object","PUPPETEER_TEMP_DIR","HIGHCHARTS_VERSION","HIGHCHARTS_CDN_URL","startsWith","HIGHCHARTS_CORE_SCRIPTS","HIGHCHARTS_MODULE_SCRIPTS","HIGHCHARTS_INDICATOR_SCRIPTS","HIGHCHARTS_FORCE_FETCH","HIGHCHARTS_CACHE_PATH","HIGHCHARTS_ADMIN_TOKEN","EXPORT_TYPE","EXPORT_CONSTR","EXPORT_DEFAULT_HEIGHT","EXPORT_DEFAULT_WIDTH","EXPORT_DEFAULT_SCALE","EXPORT_RASTERIZATION_TIMEOUT","CUSTOM_LOGIC_ALLOW_CODE_EXECUTION","CUSTOM_LOGIC_ALLOW_FILE_RESOURCES","SERVER_ENABLE","SERVER_HOST","SERVER_PORT","SERVER_MAX_UPLOAD_SIZE","SERVER_BENCHMARKING","SERVER_PROXY_HOST","SERVER_PROXY_PORT","SERVER_PROXY_USERNAME","SERVER_PROXY_PASSWORD","SERVER_PROXY_TIMEOUT","SERVER_RATE_LIMITING_ENABLE","SERVER_RATE_LIMITING_MAX_REQUESTS","SERVER_RATE_LIMITING_WINDOW","SERVER_RATE_LIMITING_DELAY","SERVER_RATE_LIMITING_TRUST_PROXY","SERVER_RATE_LIMITING_SKIP_KEY","SERVER_RATE_LIMITING_SKIP_TOKEN","SERVER_SSL_ENABLE","SERVER_SSL_FORCE","SERVER_SSL_PORT","SERVER_SSL_CERT_PATH","POOL_MIN_WORKERS","POOL_MAX_WORKERS","POOL_WORK_LIMIT","POOL_ACQUIRE_TIMEOUT","POOL_CREATE_TIMEOUT","POOL_DESTROY_TIMEOUT","POOL_IDLE_TIMEOUT","POOL_CREATE_RETRY_INTERVAL","POOL_REAPER_INTERVAL","POOL_BENCHMARKING","LOGGING_LEVEL","LOGGING_FILE","LOGGING_DEST","LOGGING_TO_CONSOLE","LOGGING_TO_FILE","UI_ENABLE","UI_ROUTE","OTHER_NODE_ENV","OTHER_LISTEN_TO_PROCESS_EXITS","OTHER_NO_LOGO","OTHER_HARD_RESET_PAGE","OTHER_BROWSER_SHELL_MODE","OTHER_ALLOW_XLINK","DEBUG_ENABLE","DEBUG_HEADLESS","DEBUG_DEVTOOLS","DEBUG_LISTEN_TO_CONSOLE","DEBUG_DUMPIO","DEBUG_SLOW_MO","DEBUG_DEBUGGING_PORT","partial","parse","process","env","colors","pathCreated","levelsDesc","title","color","listeners","logToFile","texts","prefix","existsSync","mkdirSync","appendFile","concat","error","console","log","newLevel","Date","toString","fn","apply","logWithStack","customMessage","mainMessage","stackMessage","stack","slice","setLogLevel","enableFileLogging","logDest","logFile","endsWith","__dirname","fileURLToPath","URL","url","fixType","formats","outType","pop","find","t","handleResources","allowedProps","handledResources","correctResources","isCorrectJSON","readFileSync","files","propName","item","data","parsedData","JSON","stringify","deepCopy","copy","Array","isArray","key","prototype","hasOwnProperty","call","optionsStringify","allowFunctions","replaceAll","printUsage","bold","yellow","cycleCategories","option","entries","descName","green","i","blue","category","toUpperCase","red","toBoolean","wrapAround","replace","measureTime","start","hrtime","bigint","Number","generalOptions","getOptions","mergeConfigOptions","newOptions","mergedOptions","updateDefaultConfig","configObj","customObj","customValue","initOptions","items","recursiveProps","objectToUpdate","nestedNames","shift","assign","async","fetch","requestOptions","Promise","resolve","reject","protocol","https","http","getProtocol","get","headers","Referer","res","on","chunk","text","ExportError","Error","constructor","super","this","setError","statusCode","cache","activeManifest","sources","hcVersion","extractVersion","indexOf","fetchAndProcessScript","script","fetchedModules","shouldThrowError","response","updateCache","highchartsOptions","proxyOptions","sourcePath","proxyAgent","HttpsProxyAgent","agent","allFetchPromises","all","fetchScripts","c","m","writeFileSync","checkAndUpdateCache","manifestPath","requestUpdate","manifest","moduleMap","numberOfModules","some","moduleName","newManifest","saveConfigToManifest","getCachePath","setupHighcharts","Highcharts","animObject","duration","triggerExport","chartOptions","displayErrors","_displayErrors","merge","setOptions","wrap","setOptionsObj","chart","animation","strInj","isRenderComplete","Chart","proceed","userOptions","cb","exporting","enabled","plotOptions","series","label","tooltip","onHighchartsRender","addEvent","Series","Function","finalOptions","finalCallback","defaultOptions","prop","template","browser","newPage","page","setCacheEnabled","setPageContent","isClosed","$eval","element","errorMessage","innerHTML","setPageEvents","clearPageResources","injectedResources","resource","dispose","evaluate","oldCharts","charts","oldChart","destroy","scriptsToRemove","document","getElementsByTagName","stylesToRemove","linksToRemove","remove","setContent","waitUntil","addScriptTag","path","setAsConfig","totalSize","Buffer","byteLength","toFixed","puppeteerExport","exportOptions","debugger","isSVG","svgTemplate","injectedJs","js","push","content","isLocal","jsResource","injectedCss","css","cssImports","match","cssImportPath","cssResource","addStyleTag","addPageResources","size","svgElement","querySelector","chartHeight","baseVal","chartWidth","body","style","zoom","margin","viewportHeight","Math","abs","ceil","viewportWidth","x","y","getBoundingClientRect","trunc","getClipRegion","setViewport","deviceScaleFactor","outerHTML","createSVG","encoding","clip","race","screenshot","captureBeyondViewport","fullPage","optimizeForSpeed","quality","omitBackground","_resolve","setTimeout","createImage","emulateMediaType","pdf","createPDF","stats","performedExports","exportAttempts","exportFromSvgAttempts","timeSpent","droppedExports","spentAverage","poolConfig","factory","create","id","uuid","startDate","getTime","workCount","random","validate","workerHandle","close","initPool","puppeteerArgs","puppeteerOptions","enabledDebug","debugOptions","launchOptions","userDataDir","handleSIGINT","handleSIGTERM","handleSIGHUP","waitForInitialPage","defaultViewport","maxTries","tryCount","open","launch","createBrowser","parseInt","Pool","acquireTimeoutMillis","createTimeoutMillis","destroyTimeoutMillis","idleTimeoutMillis","createRetryIntervalMillis","reapIntervalMillis","propagateCreateError","r","hardReset","goto","clearPage","eventId","initialResources","acquire","promise","release","killPool","worker","used","destroyed","connected","closeBrowser","postWork","getPoolInfo","acquireCounter","payload","requestId","workStart","exportCounter","result","exportTime","getPoolInfoJSON","numFree","numUsed","available","pending","numPendingAcquires","pool$1","startExport","settings","endCallback","svg","initExportSettings","exportAsString","input","forbidden","JSDOM","DOMPurify","sanitize","ADD_TAGS","FORBID_ATTR","doStraightInject","doExport","findChartSize","precision","multiplier","pow","roundNumber","sourceHeight","sourceWidth","param","chartJson","customLogicOptions","allowCodeExecutionScoped","optionsName","stringToExport","chartJSON","intervalIds","clearAllIntervals","clearInterval","logErrorMiddleware","req","next","returnErrorMiddleware","stCode","status","json","rateLimit","app","limitConfig","msg","rateOptions","limiter","windowMs","delayMs","handler","request","format","send","default","skip","query","access_token","use","HttpError","setStatus","vSwitchRoute","post","adminToken","token","newVersion","params","updateVersion","reversedMime","png","jpeg","gif","requestsCounter","beforeRequest","afterRequest","doCallbacks","callbacks","uniqueId","callResponse","exportHandler","stopCounter","connection","remoteAddress","b64","noDownload","connectionAborted","socket","hadErrors","toLowerCase","substr","pattern","isPrivateRangeUrlFound","info","removeAllListeners","from","header","attachment","filename","pkgFile","pather","serverStartTime","successRates","addHealthRoutes","setInterval","successRatio","_","period","movingAverage","reduce","a","b","bootTime","uptime","floor","highchartsVersion","averageProcessingTime","failedExports","sucessRatio","svgExportAttempts","jsonExportAttempts","activeServers","Map","express","disable","cors","_req","set","attachServerErrorHandlers","startServer","serverConfig","uploadLimitBytes","storage","multer","memoryStorage","upload","limits","fieldSize","limit","urlencoded","extended","none","httpServer","createServer","listen","cert","fsPromises","readFile","posix","httpsServer","NaN","static","healthRoute","exportRoutes","_request","sendFile","acceptRanges","uiRoute","errorHandler","closeServers","delete","getServers","enableRateLimiting","getExpress","getApp","middlewares","shutdownCleanUp","exitCode","allSettled","exit","index","initExport","loggingOptions","initLogging","code","singleExport","batchExport","batchFunctions","pair","configIndex","findIndex","arg","fileName","loadConfigFile","showUsage","propertiesChain","argumentType","pairArgumentValue","mapToNewConfig","oldOptions","manualConfig","configFileName","configFile","choice","prompts","onSubmit","p","categories","questionsCounter","allQuestions","section","prompt","answer","module","writeFile","printLogo","packageVersion"],"mappings":"0lBAeO,MAAMA,EAAe,CAC1BC,KAAM,CAAC,aAAc,kBAAmB,iBACxCC,QAAS,CACP,QACA,MACA,QACA,YACA,uBACA,gBAEA,eACA,QACA,OACA,aACA,mBACA,eACA,cACA,UACA,UACA,cACA,WACA,UACA,YACA,cACA,YACA,sBACA,SACA,SACA,WACA,aACA,YACA,eACA,yBACA,SACA,eACA,YACA,kBACA,SACA,cACA,mBACA,eACA,kBACA,cACA,eAEA,cACA,WACA,eACA,WACA,SACA,OACA,WACA,YACA,SACA,qBACA,aACA,WACA,WACA,WACA,WACA,eACA,UACA,kBACA,oBACA,aACA,UACA,cACA,YACA,YAEFC,WAAY,CAAC,kBACbC,OAAQ,CACN,wEACA,mGAMSC,EAAgB,CAC3BC,UAAW,CACTC,KAAM,CACJC,MAAO,CACL,mCACA,kBACA,0CACA,2BACA,kCACA,kCACA,wCACA,2CACA,qBACA,4BACA,2CACA,uDACA,6BACA,yBACA,0BACA,+BACA,uBACA,uFACA,yBACA,oCACA,oBACA,0BACA,8CACA,2BACA,0BACA,6BACA,mCACA,wCACA,mCACA,2BACA,kCACA,uBACA,iBACA,yBACA,8BACA,oBACA,2BACA,eACA,6BACA,iBACA,aACA,SAEA,sBAEA,yBACA,oBACA,uBAEFC,KAAM,WACNC,YAAa,yCAEfC,QAAS,CACPH,MAAO,SACPC,KAAM,SACNG,QAAS,qBACTF,YAAa,0DAGjBG,WAAY,CACVC,QAAS,CACPN,MAAO,SACPC,KAAM,SACNG,QAAS,qBACTF,YAAa,sCAEfK,OAAQ,CACNP,MAAO,+BACPC,KAAM,SACNG,QAAS,qBACTF,YAAa,kDAEfM,YAAa,CACXR,MAAOR,EAAaC,KACpBQ,KAAM,WACNG,QAAS,0BACTF,YAAa,yCAEfO,cAAe,CACbT,MAAOR,EAAaE,QACpBO,KAAM,WACNG,QAAS,4BACTF,YAAa,uCAEfQ,iBAAkB,CAChBV,MAAOR,EAAaG,WACpBM,KAAM,WACNG,QAAS,+BACTF,YAAa,0CAEfS,cAAe,CACbX,MAAOR,EAAaI,OACpBK,KAAM,WACN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"} \ No newline at end of file +{"version":3,"file":"index.esm.js","sources":["../lib/schemas/config.js","../lib/envs.js","../lib/logger.js","../lib/utils.js","../lib/config.js","../lib/fetch.js","../lib/errors/ExportError.js","../lib/cache.js","../lib/highcharts.js","../lib/browser.js","../lib/export.js","../templates/svg_export/svg_export.js","../lib/pool.js","../lib/chart.js","../lib/sanitize.js","../lib/intervals.js","../lib/server/error.js","../lib/server/rate_limit.js","../lib/errors/HttpError.js","../lib/server/routes/change_hc_version.js","../lib/server/routes/export.js","../lib/server/routes/health.js","../lib/server/server.js","../lib/server/routes/ui.js","../lib/resource_release.js","../lib/index.js"],"sourcesContent":["/*******************************************************************************\n\nHighcharts Export Server\n\nCopyright (c) 2016-2024, Highsoft\n\nLicenced under the MIT licence.\n\nAdditionally a valid Highcharts license is required for use.\n\nSee LICENSE file in root for details.\n\n*******************************************************************************/\n\n// Possible names for Highcharts scripts\nexport const scriptsNames = {\n core: ['highcharts', 'highcharts-more', 'highcharts-3d'],\n modules: [\n 'stock',\n 'map',\n 'gantt',\n 'exporting',\n 'parallel-coordinates',\n 'accessibility',\n // 'annotations-advanced',\n 'boost-canvas',\n 'boost',\n 'data',\n 'data-tools',\n 'draggable-points',\n 'static-scale',\n 'broken-axis',\n 'heatmap',\n 'tilemap',\n 'tiledwebmap',\n 'timeline',\n 'treemap',\n 'treegraph',\n 'item-series',\n 'drilldown',\n 'histogram-bellcurve',\n 'bullet',\n 'funnel',\n 'funnel3d',\n 'geoheatmap',\n 'pyramid3d',\n 'networkgraph',\n 'overlapping-datalabels',\n 'pareto',\n 'pattern-fill',\n 'pictorial',\n 'price-indicator',\n 'sankey',\n 'arc-diagram',\n 'dependency-wheel',\n 'series-label',\n 'series-on-point',\n 'solid-gauge',\n 'sonification',\n // 'stock-tools',\n 'streamgraph',\n 'sunburst',\n 'variable-pie',\n 'variwide',\n 'vector',\n 'venn',\n 'windbarb',\n 'wordcloud',\n 'xrange',\n 'no-data-to-display',\n 'drag-panes',\n 'debugger',\n 'dumbbell',\n 'lollipop',\n 'cylinder',\n 'organization',\n 'dotplot',\n 'marker-clusters',\n 'hollowcandlestick',\n 'heikinashi',\n 'flowmap',\n 'export-data',\n 'navigator',\n 'textpath'\n ],\n indicators: ['indicators-all'],\n custom: [\n 'https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.30.1/moment.min.js',\n 'https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.45/moment-timezone-with-data.min.js'\n ]\n};\n\n// This is the configuration object with all options and their default values,\n// also from the .env file if one exists\nexport const defaultConfig = {\n puppeteer: {\n args: {\n value: [\n '--allow-running-insecure-content',\n '--ash-no-nudges',\n '--autoplay-policy=user-gesture-required',\n '--block-new-web-contents',\n '--disable-accelerated-2d-canvas',\n '--disable-background-networking',\n '--disable-background-timer-throttling',\n '--disable-backgrounding-occluded-windows',\n '--disable-breakpad',\n '--disable-checker-imaging',\n '--disable-client-side-phishing-detection',\n '--disable-component-extensions-with-background-pages',\n '--disable-component-update',\n '--disable-default-apps',\n '--disable-dev-shm-usage',\n '--disable-domain-reliability',\n '--disable-extensions',\n '--disable-features=CalculateNativeWinOcclusion,InterestFeedContentSuggestions,WebOTP',\n '--disable-hang-monitor',\n '--disable-ipc-flooding-protection',\n '--disable-logging',\n '--disable-notifications',\n '--disable-offer-store-unmasked-wallet-cards',\n '--disable-popup-blocking',\n '--disable-print-preview',\n '--disable-prompt-on-repost',\n '--disable-renderer-backgrounding',\n '--disable-search-engine-choice-screen',\n '--disable-session-crashed-bubble',\n '--disable-setuid-sandbox',\n '--disable-site-isolation-trials',\n '--disable-speech-api',\n '--disable-sync',\n '--enable-unsafe-webgpu',\n '--hide-crash-restore-bubble',\n '--hide-scrollbars',\n '--metrics-recording-only',\n '--mute-audio',\n '--no-default-browser-check',\n '--no-first-run',\n '--no-pings',\n '--pipe',\n // '--no-sandbox',\n '--no-startup-window',\n // '--no-zygote',\n '--password-store=basic',\n '--process-per-tab',\n '--use-mock-keychain'\n ],\n type: 'string[]',\n description: 'Arguments array to send to Puppeteer.'\n },\n tempDir: {\n value: './tmp/',\n type: 'string',\n envLink: 'PUPPETEER_TEMP_DIR',\n description: 'The directory for Puppeteer to store temporary files.'\n }\n },\n highcharts: {\n version: {\n value: 'latest',\n type: 'string',\n envLink: 'HIGHCHARTS_VERSION',\n description: 'The Highcharts version to be used.'\n },\n cdnURL: {\n value: 'https://code.highcharts.com/',\n type: 'string',\n envLink: 'HIGHCHARTS_CDN_URL',\n description: 'The CDN URL for Highcharts scripts to be used.'\n },\n coreScripts: {\n value: scriptsNames.core,\n type: 'string[]',\n envLink: 'HIGHCHARTS_CORE_SCRIPTS',\n description: 'The core Highcharts scripts to fetch.'\n },\n moduleScripts: {\n value: scriptsNames.modules,\n type: 'string[]',\n envLink: 'HIGHCHARTS_MODULE_SCRIPTS',\n description: 'The modules of Highcharts to fetch.'\n },\n indicatorScripts: {\n value: scriptsNames.indicators,\n type: 'string[]',\n envLink: 'HIGHCHARTS_INDICATOR_SCRIPTS',\n description: 'The indicators of Highcharts to fetch.'\n },\n customScripts: {\n value: scriptsNames.custom,\n type: 'string[]',\n description: 'Additional custom scripts or dependencies to fetch.'\n },\n forceFetch: {\n value: false,\n type: 'boolean',\n envLink: 'HIGHCHARTS_FORCE_FETCH',\n description:\n 'The flag to determine whether to refetch all scripts after each server rerun.'\n },\n cachePath: {\n value: '.cache',\n type: 'string',\n envLink: 'HIGHCHARTS_CACHE_PATH',\n description:\n 'The path to the cache directory. It is used to store the Highcharts scripts and custom scripts.'\n }\n },\n export: {\n infile: {\n value: false,\n type: 'string',\n description:\n 'The input file should include a name and a type (json or svg). It must be correctly formatted as a JSON or SVG file.'\n },\n instr: {\n value: false,\n type: 'string',\n description:\n 'Input, provided in the form of a stringified JSON or SVG file, will override the --infile option.'\n },\n options: {\n value: false,\n type: 'string',\n description: 'An alias for the --instr option.'\n },\n outfile: {\n value: false,\n type: 'string',\n description:\n 'The output filename along with a type (jpeg, png, pdf, or svg). This will ignore the --type flag.'\n },\n type: {\n value: 'png',\n type: 'string',\n envLink: 'EXPORT_TYPE',\n description: 'The file export format. It can be jpeg, png, pdf, or svg.'\n },\n constr: {\n value: 'chart',\n type: 'string',\n envLink: 'EXPORT_CONSTR',\n description:\n 'The constructor to use. Can be chart, stockChart, mapChart, or ganttChart.'\n },\n defaultHeight: {\n value: 400,\n type: 'number',\n envLink: 'EXPORT_DEFAULT_HEIGHT',\n description:\n 'the default height of the exported chart. Used when no value is set.'\n },\n defaultWidth: {\n value: 600,\n type: 'number',\n envLink: 'EXPORT_DEFAULT_WIDTH',\n description:\n 'The default width of the exported chart. Used when no value is set.'\n },\n defaultScale: {\n value: 1,\n type: 'number',\n envLink: 'EXPORT_DEFAULT_SCALE',\n description:\n 'The default scale of the exported chart. Used when no value is set.'\n },\n height: {\n value: false,\n type: 'number',\n description:\n 'The height of the exported chart, overriding the option in the chart settings.'\n },\n width: {\n value: false,\n type: 'number',\n description:\n 'The width of the exported chart, overriding the option in the chart settings.'\n },\n scale: {\n value: false,\n type: 'number',\n description:\n 'The scale of the exported chart, overriding the option in the chart settings. Ranges between 0.1 and 5.0.'\n },\n globalOptions: {\n value: false,\n type: 'string',\n description:\n 'Either a stringified JSON or a filename containing options to be passed into the Highcharts.setOptions.'\n },\n themeOptions: {\n value: false,\n type: 'string',\n description:\n 'Either a stringified JSON or a filename containing theme options to be passed into the Highcharts.setOptions.'\n },\n batch: {\n value: false,\n type: 'string',\n description:\n 'Initiates a batch job with a string containing input/output pairs: \"in=out;in=out;...\".'\n },\n rasterizationTimeout: {\n value: 1500,\n type: 'number',\n envLink: 'EXPORT_RASTERIZATION_TIMEOUT',\n description:\n 'The duration in milliseconds to wait for rendering a webpage.'\n }\n },\n customLogic: {\n allowCodeExecution: {\n value: false,\n type: 'boolean',\n envLink: 'CUSTOM_LOGIC_ALLOW_CODE_EXECUTION',\n description:\n 'Controls whether the execution of arbitrary code is allowed during the exporting process.'\n },\n allowFileResources: {\n value: false,\n type: 'boolean',\n envLink: 'CUSTOM_LOGIC_ALLOW_FILE_RESOURCES',\n description:\n 'Controls the ability to inject resources from the filesystem. This setting has no effect when running as a server.'\n },\n customCode: {\n value: false,\n type: 'string',\n description:\n 'Custom code to execute before chart initialization. It can be a function, code wrapped within a function, or a filename with the .js extension.'\n },\n callback: {\n value: false,\n type: 'string',\n description:\n 'JavaScript code to run during construction. It can be a function or a filename with the .js extension.'\n },\n resources: {\n value: false,\n type: 'string',\n description:\n 'Additional resource in the form of a stringified JSON, which may contain files, js, and css sections.'\n },\n loadConfig: {\n value: false,\n type: 'string',\n legacyName: 'fromFile',\n description: 'A file containing a pre-defined configuration to use.'\n },\n createConfig: {\n value: false,\n type: 'string',\n description:\n 'Enables setting options through a prompt and saving them in a provided config file.'\n }\n },\n server: {\n maxUploadSize: {\n value: 3,\n type: 'number',\n envLink: 'SERVER_MAX_UPLOAD_SIZE',\n description: 'The maximum upload size, in MB, for the server.'\n },\n enable: {\n value: false,\n type: 'boolean',\n envLink: 'SERVER_ENABLE',\n cliName: 'enableServer',\n description:\n 'When set to true, the server starts on the local IP address 0.0.0.0.'\n },\n host: {\n value: '0.0.0.0',\n type: 'string',\n envLink: 'SERVER_HOST',\n description:\n 'The hostname of the server. Additionally, it starts a server on the provided hostname.'\n },\n port: {\n value: 7801,\n type: 'number',\n envLink: 'SERVER_PORT',\n description: 'The server port when enabled.'\n },\n benchmarking: {\n value: false,\n type: 'boolean',\n envLink: 'SERVER_BENCHMARKING',\n cliName: 'serverBenchmarking',\n description:\n 'Indicates whether to display the duration, in milliseconds, of specific actions that occur on the server while serving a request.'\n },\n proxy: {\n host: {\n value: false,\n type: 'string',\n envLink: 'SERVER_PROXY_HOST',\n cliName: 'proxyHost',\n description: 'The host of the proxy server to use, if it exists.'\n },\n port: {\n value: 8080,\n type: 'number',\n envLink: 'SERVER_PROXY_PORT',\n cliName: 'proxyPort',\n description: 'The port of the proxy server to use, if it exists.'\n },\n username: {\n value: false,\n type: 'string',\n envLink: 'SERVER_PROXY_USERNAME',\n cliName: 'proxyUsername',\n description: 'The username for the proxy server, if it exists.'\n },\n password: {\n value: false,\n type: 'string',\n envLink: 'SERVER_PROXY_PASSWORD',\n cliName: 'proxyPassword',\n description: 'The password for the proxy server, if it exists.'\n },\n timeout: {\n value: 5000,\n type: 'number',\n envLink: 'SERVER_PROXY_TIMEOUT',\n cliName: 'proxyTimeout',\n description: 'The timeout for the proxy server to use, if it exists.'\n }\n },\n rateLimiting: {\n enable: {\n value: false,\n type: 'boolean',\n envLink: 'SERVER_RATE_LIMITING_ENABLE',\n cliName: 'enableRateLimiting',\n description: 'Enables rate limiting for the server.'\n },\n maxRequests: {\n value: 10,\n type: 'number',\n envLink: 'SERVER_RATE_LIMITING_MAX_REQUESTS',\n legacyName: 'rateLimit',\n description: 'The maximum number of requests allowed in one minute.'\n },\n window: {\n value: 1,\n type: 'number',\n envLink: 'SERVER_RATE_LIMITING_WINDOW',\n description: 'The time window, in minutes, for the rate limiting.'\n },\n delay: {\n value: 0,\n type: 'number',\n envLink: 'SERVER_RATE_LIMITING_DELAY',\n description:\n 'The delay duration for each successive request before reaching the maximum limit.'\n },\n trustProxy: {\n value: false,\n type: 'boolean',\n envLink: 'SERVER_RATE_LIMITING_TRUST_PROXY',\n description: 'Set this to true if the server is behind a load balancer.'\n },\n skipKey: {\n value: false,\n type: 'string',\n envLink: 'SERVER_RATE_LIMITING_SKIP_KEY',\n description:\n 'Allows bypassing the rate limiter and should be provided with the skipToken argument.'\n },\n skipToken: {\n value: false,\n type: 'string',\n envLink: 'SERVER_RATE_LIMITING_SKIP_TOKEN',\n description:\n 'Allows bypassing the rate limiter and should be provided with the skipKey argument.'\n }\n },\n ssl: {\n enable: {\n value: false,\n type: 'boolean',\n envLink: 'SERVER_SSL_ENABLE',\n cliName: 'enableSsl',\n description: 'Enables or disables the SSL protocol.'\n },\n force: {\n value: false,\n type: 'boolean',\n envLink: 'SERVER_SSL_FORCE',\n cliName: 'sslForce',\n legacyName: 'sslOnly',\n description:\n 'When set to true, the server is forced to serve only over HTTPS.'\n },\n port: {\n value: 443,\n type: 'number',\n envLink: 'SERVER_SSL_PORT',\n cliName: 'sslPort',\n description: 'The port on which to run the SSL server.'\n },\n certPath: {\n value: false,\n type: 'string',\n envLink: 'SERVER_SSL_CERT_PATH',\n legacyName: 'sslPath',\n description: 'The path to the SSL certificate/key file.'\n }\n }\n },\n pool: {\n minWorkers: {\n value: 4,\n type: 'number',\n envLink: 'POOL_MIN_WORKERS',\n description: 'The number of minimum and initial pool workers to spawn.'\n },\n maxWorkers: {\n value: 8,\n type: 'number',\n envLink: 'POOL_MAX_WORKERS',\n legacyName: 'workers',\n description: 'The number of maximum pool workers to spawn.'\n },\n workLimit: {\n value: 40,\n type: 'number',\n envLink: 'POOL_WORK_LIMIT',\n description:\n 'The number of work pieces that can be performed before restarting the worker process.'\n },\n acquireTimeout: {\n value: 5000,\n type: 'number',\n envLink: 'POOL_ACQUIRE_TIMEOUT',\n description:\n 'The duration, in milliseconds, to wait for acquiring a resource.'\n },\n createTimeout: {\n value: 5000,\n type: 'number',\n envLink: 'POOL_CREATE_TIMEOUT',\n description:\n 'The duration, in milliseconds, to wait for creating a resource.'\n },\n destroyTimeout: {\n value: 5000,\n type: 'number',\n envLink: 'POOL_DESTROY_TIMEOUT',\n description:\n 'The duration, in milliseconds, to wait for destroying a resource.'\n },\n idleTimeout: {\n value: 30000,\n type: 'number',\n envLink: 'POOL_IDLE_TIMEOUT',\n description:\n 'The duration, in milliseconds, after which an idle resource is destroyed.'\n },\n createRetryInterval: {\n value: 200,\n type: 'number',\n envLink: 'POOL_CREATE_RETRY_INTERVAL',\n description:\n 'The duration, in milliseconds, to wait before retrying the create process in case of a failure.'\n },\n reaperInterval: {\n value: 1000,\n type: 'number',\n envLink: 'POOL_REAPER_INTERVAL',\n description:\n 'The duration, in milliseconds, after which the check for idle resources to destroy is triggered.'\n },\n benchmarking: {\n value: false,\n type: 'boolean',\n envLink: 'POOL_BENCHMARKING',\n cliName: 'poolBenchmarking',\n description:\n 'Indicate whether to show statistics for the pool of resources or not.'\n }\n },\n logging: {\n level: {\n value: 4,\n type: 'number',\n envLink: 'LOGGING_LEVEL',\n cliName: 'logLevel',\n description: 'The logging level to be used.'\n },\n file: {\n value: 'highcharts-export-server.log',\n type: 'string',\n envLink: 'LOGGING_FILE',\n cliName: 'logFile',\n description:\n 'The name of a log file. The `logToFile` and `logDest` options also need to be set to enable file logging.'\n },\n dest: {\n value: 'log/',\n type: 'string',\n envLink: 'LOGGING_DEST',\n cliName: 'logDest',\n description:\n 'The path to store log files. The `logToFile` option also needs to be set to enable file logging.'\n },\n toConsole: {\n value: true,\n type: 'boolean',\n envLink: 'LOGGING_TO_CONSOLE',\n cliName: 'logToConsole',\n description: 'Enables or disables showing logs in the console.'\n },\n toFile: {\n value: true,\n type: 'boolean',\n envLink: 'LOGGING_TO_FILE',\n cliName: 'logToFile',\n description:\n 'Enables or disables creation of the log directory and saving the log into a .log file.'\n }\n },\n ui: {\n enable: {\n value: false,\n type: 'boolean',\n envLink: 'UI_ENABLE',\n cliName: 'enableUi',\n description:\n 'Enables or disables the user interface (UI) for the export server.'\n },\n route: {\n value: '/',\n type: 'string',\n envLink: 'UI_ROUTE',\n cliName: 'uiRoute',\n description:\n 'The endpoint route to which the user interface (UI) should be attached.'\n }\n },\n other: {\n nodeEnv: {\n value: 'production',\n type: 'string',\n envLink: 'OTHER_NODE_ENV',\n description: 'The type of Node.js environment.'\n },\n listenToProcessExits: {\n value: true,\n type: 'boolean',\n envLink: 'OTHER_LISTEN_TO_PROCESS_EXITS',\n description: 'Decides whether or not to attach process.exit handlers.'\n },\n noLogo: {\n value: false,\n type: 'boolean',\n envLink: 'OTHER_NO_LOGO',\n description:\n 'Skip printing the logo on a startup. Will be replaced by a simple text.'\n },\n hardResetPage: {\n value: false,\n type: 'boolean',\n envLink: 'OTHER_HARD_RESET_PAGE',\n description: 'Decides if the page content should be reset entirely.'\n },\n browserShellMode: {\n value: true,\n type: 'boolean',\n envLink: 'OTHER_BROWSER_SHELL_MODE',\n description: 'Decides if the browser runs in the shell mode.'\n }\n },\n debug: {\n enable: {\n value: false,\n type: 'boolean',\n envLink: 'DEBUG_ENABLE',\n cliName: 'enableDebug',\n description: 'Enables or disables debug mode for the underlying browser.'\n },\n headless: {\n value: true,\n type: 'boolean',\n envLink: 'DEBUG_HEADLESS',\n description:\n 'Controls the mode in which the browser is launched when in the debug mode.'\n },\n devtools: {\n value: false,\n type: 'boolean',\n envLink: 'DEBUG_DEVTOOLS',\n description:\n 'Decides whether to enable DevTools when the browser is in a headful state.'\n },\n listenToConsole: {\n value: false,\n type: 'boolean',\n envLink: 'DEBUG_LISTEN_TO_CONSOLE',\n description:\n 'Decides whether to enable a listener for console messages sent from the browser.'\n },\n dumpio: {\n value: false,\n type: 'boolean',\n envLink: 'DEBUG_DUMPIO',\n description:\n 'Redirects browser process stdout and stderr to process.stdout and process.stderr.'\n },\n slowMo: {\n value: 0,\n type: 'number',\n envLink: 'DEBUG_SLOW_MO',\n description:\n 'Slows down Puppeteer operations by the specified number of milliseconds.'\n },\n debuggingPort: {\n value: 9222,\n type: 'number',\n envLink: 'DEBUG_DEBUGGING_PORT',\n description: 'Specifies the debugging port.'\n }\n }\n};\n\n// The config descriptions object for the prompts functionality. It contains\n// information like:\n// * Type of a prompt\n// * Name of an option\n// * Short description of a chosen option\n// * Initial value\nexport const promptsConfig = {\n puppeteer: [\n {\n type: 'list',\n name: 'args',\n message: 'Puppeteer arguments',\n initial: defaultConfig.puppeteer.args.value.join(','),\n separator: ','\n }\n ],\n highcharts: [\n {\n type: 'text',\n name: 'version',\n message: 'Highcharts version',\n initial: defaultConfig.highcharts.version.value\n },\n {\n type: 'text',\n name: 'cdnURL',\n message: 'The URL of CDN',\n initial: defaultConfig.highcharts.cdnURL.value\n },\n {\n type: 'multiselect',\n name: 'coreScripts',\n message: 'Available core scripts',\n instructions: 'Space: Select specific, A: Select all, Enter: Confirm.',\n choices: defaultConfig.highcharts.coreScripts.value\n },\n {\n type: 'multiselect',\n name: 'moduleScripts',\n message: 'Available module scripts',\n instructions: 'Space: Select specific, A: Select all, Enter: Confirm.',\n choices: defaultConfig.highcharts.moduleScripts.value\n },\n {\n type: 'multiselect',\n name: 'indicatorScripts',\n message: 'Available indicator scripts',\n instructions: 'Space: Select specific, A: Select all, Enter: Confirm.',\n choices: defaultConfig.highcharts.indicatorScripts.value\n },\n {\n type: 'list',\n name: 'customScripts',\n message: 'Custom scripts',\n initial: defaultConfig.highcharts.customScripts.value.join(','),\n separator: ','\n },\n {\n type: 'toggle',\n name: 'forceFetch',\n message: 'Force re-fetch the scripts',\n initial: defaultConfig.highcharts.forceFetch.value\n },\n {\n type: 'text',\n name: 'cachePath',\n message: 'The path to the cache directory',\n initial: defaultConfig.highcharts.cachePath.value\n }\n ],\n export: [\n {\n type: 'select',\n name: 'type',\n message: 'The default export file type',\n hint: `Default: ${defaultConfig.export.type.value}`,\n initial: 0,\n choices: ['png', 'jpeg', 'pdf', 'svg']\n },\n {\n type: 'select',\n name: 'constr',\n message: 'The default constructor for Highcharts',\n hint: `Default: ${defaultConfig.export.constr.value}`,\n initial: 0,\n choices: ['chart', 'stockChart', 'mapChart', 'ganttChart']\n },\n {\n type: 'number',\n name: 'defaultHeight',\n message: 'The default fallback height of the exported chart',\n initial: defaultConfig.export.defaultHeight.value\n },\n {\n type: 'number',\n name: 'defaultWidth',\n message: 'The default fallback width of the exported chart',\n initial: defaultConfig.export.defaultWidth.value\n },\n {\n type: 'number',\n name: 'defaultScale',\n message: 'The default fallback scale of the exported chart',\n initial: defaultConfig.export.defaultScale.value,\n min: 0.1,\n max: 5\n },\n {\n type: 'number',\n name: 'rasterizationTimeout',\n message: 'The rendering webpage timeout in milliseconds',\n initial: defaultConfig.export.rasterizationTimeout.value\n }\n ],\n customLogic: [\n {\n type: 'toggle',\n name: 'allowCodeExecution',\n message: 'Enable execution of custom code',\n initial: defaultConfig.customLogic.allowCodeExecution.value\n },\n {\n type: 'toggle',\n name: 'allowFileResources',\n message: 'Enable file resources',\n initial: defaultConfig.customLogic.allowFileResources.value\n }\n ],\n server: [\n {\n type: 'toggle',\n name: 'enable',\n message: 'Starts the server on 0.0.0.0',\n initial: defaultConfig.server.enable.value\n },\n {\n type: 'text',\n name: 'host',\n message: 'Server hostname',\n initial: defaultConfig.server.host.value\n },\n {\n type: 'number',\n name: 'port',\n message: 'Server port',\n initial: defaultConfig.server.port.value\n },\n {\n type: 'toggle',\n name: 'benchmarking',\n message: 'Enable server benchmarking',\n initial: defaultConfig.server.benchmarking.value\n },\n {\n type: 'text',\n name: 'proxy.host',\n message: 'The host of the proxy server to use',\n initial: defaultConfig.server.proxy.host.value\n },\n {\n type: 'number',\n name: 'proxy.port',\n message: 'The port of the proxy server to use',\n initial: defaultConfig.server.proxy.port.value\n },\n {\n type: 'number',\n name: 'proxy.timeout',\n message: 'The timeout for the proxy server to use',\n initial: defaultConfig.server.proxy.timeout.value\n },\n {\n type: 'toggle',\n name: 'rateLimiting.enable',\n message: 'Enable rate limiting',\n initial: defaultConfig.server.rateLimiting.enable.value\n },\n {\n type: 'number',\n name: 'rateLimiting.maxRequests',\n message: 'The maximum requests allowed per minute',\n initial: defaultConfig.server.rateLimiting.maxRequests.value\n },\n {\n type: 'number',\n name: 'rateLimiting.window',\n message: 'The rate-limiting time window in minutes',\n initial: defaultConfig.server.rateLimiting.window.value\n },\n {\n type: 'number',\n name: 'rateLimiting.delay',\n message:\n 'The delay for each successive request before reaching the maximum',\n initial: defaultConfig.server.rateLimiting.delay.value\n },\n {\n type: 'toggle',\n name: 'rateLimiting.trustProxy',\n message: 'Set to true if behind a load balancer',\n initial: defaultConfig.server.rateLimiting.trustProxy.value\n },\n {\n type: 'text',\n name: 'rateLimiting.skipKey',\n message:\n 'Allows bypassing the rate limiter when provided with the skipToken argument',\n initial: defaultConfig.server.rateLimiting.skipKey.value\n },\n {\n type: 'text',\n name: 'rateLimiting.skipToken',\n message:\n 'Allows bypassing the rate limiter when provided with the skipKey argument',\n initial: defaultConfig.server.rateLimiting.skipToken.value\n },\n {\n type: 'toggle',\n name: 'ssl.enable',\n message: 'Enable SSL protocol',\n initial: defaultConfig.server.ssl.enable.value\n },\n {\n type: 'toggle',\n name: 'ssl.force',\n message: 'Force serving only over HTTPS',\n initial: defaultConfig.server.ssl.force.value\n },\n {\n type: 'number',\n name: 'ssl.port',\n message: 'SSL server port',\n initial: defaultConfig.server.ssl.port.value\n },\n {\n type: 'text',\n name: 'ssl.certPath',\n message: 'The path to find the SSL certificate/key',\n initial: defaultConfig.server.ssl.certPath.value\n }\n ],\n pool: [\n {\n type: 'number',\n name: 'minWorkers',\n message: 'The initial number of workers to spawn',\n initial: defaultConfig.pool.minWorkers.value\n },\n {\n type: 'number',\n name: 'maxWorkers',\n message: 'The maximum number of workers to spawn',\n initial: defaultConfig.pool.maxWorkers.value\n },\n {\n type: 'number',\n name: 'workLimit',\n message:\n 'The pieces of work that can be performed before restarting a Puppeteer process',\n initial: defaultConfig.pool.workLimit.value\n },\n {\n type: 'number',\n name: 'acquireTimeout',\n message: 'The number of milliseconds to wait for acquiring a resource',\n initial: defaultConfig.pool.acquireTimeout.value\n },\n {\n type: 'number',\n name: 'createTimeout',\n message: 'The number of milliseconds to wait for creating a resource',\n initial: defaultConfig.pool.createTimeout.value\n },\n {\n type: 'number',\n name: 'destroyTimeout',\n message: 'The number of milliseconds to wait for destroying a resource',\n initial: defaultConfig.pool.destroyTimeout.value\n },\n {\n type: 'number',\n name: 'idleTimeout',\n message: 'The number of milliseconds after an idle resource is destroyed',\n initial: defaultConfig.pool.idleTimeout.value\n },\n {\n type: 'number',\n name: 'createRetryInterval',\n message:\n 'The retry interval in milliseconds after a create process fails',\n initial: defaultConfig.pool.createRetryInterval.value\n },\n {\n type: 'number',\n name: 'reaperInterval',\n message:\n 'The reaper interval in milliseconds after triggering the check for idle resources to destroy',\n initial: defaultConfig.pool.reaperInterval.value\n },\n {\n type: 'toggle',\n name: 'benchmarking',\n message: 'Enable benchmarking for a resource pool',\n initial: defaultConfig.pool.benchmarking.value\n }\n ],\n logging: [\n {\n type: 'number',\n name: 'level',\n message:\n 'The log level (0: silent, 1: error, 2: warning, 3: notice, 4: verbose, 5: benchmark)',\n initial: defaultConfig.logging.level.value,\n round: 0,\n min: 0,\n max: 5\n },\n {\n type: 'text',\n name: 'file',\n message:\n 'A log file name. Set with --toFile and --logDest to enable file logging',\n initial: defaultConfig.logging.file.value\n },\n {\n type: 'text',\n name: 'dest',\n message: 'The path to a log file when the file logging is enabled',\n initial: defaultConfig.logging.dest.value\n },\n {\n type: 'toggle',\n name: 'toConsole',\n message: 'Enable logging to the console',\n initial: defaultConfig.logging.toConsole.value\n },\n {\n type: 'toggle',\n name: 'toFile',\n message: 'Enables logging to a file',\n initial: defaultConfig.logging.toFile.value\n }\n ],\n ui: [\n {\n type: 'toggle',\n name: 'enable',\n message: 'Enable UI for the export server',\n initial: defaultConfig.ui.enable.value\n },\n {\n type: 'text',\n name: 'route',\n message: 'A route to attach the UI',\n initial: defaultConfig.ui.route.value\n }\n ],\n other: [\n {\n type: 'text',\n name: 'nodeEnv',\n message: 'The type of Node.js environment',\n initial: defaultConfig.other.nodeEnv.value\n },\n {\n type: 'toggle',\n name: 'listenToProcessExits',\n message: 'Set to false to skip attaching process.exit handlers',\n initial: defaultConfig.other.listenToProcessExits.value\n },\n {\n type: 'toggle',\n name: 'noLogo',\n message: 'Skip printing the logo on startup. Replaced by simple text',\n initial: defaultConfig.other.noLogo.value\n },\n {\n type: 'toggle',\n name: 'hardResetPage',\n message: 'Decides if the page content should be reset entirely',\n initial: defaultConfig.other.hardResetPage.value\n },\n {\n type: 'toggle',\n name: 'browserShellMode',\n message: 'Decides if the browser runs in the shell mode',\n initial: defaultConfig.other.browserShellMode.value\n }\n ],\n debug: [\n {\n type: 'toggle',\n name: 'enable',\n message: 'Enables debug mode for the browser instance',\n initial: defaultConfig.debug.enable.value\n },\n {\n type: 'toggle',\n name: 'headless',\n message: 'The mode setting for the browser',\n initial: defaultConfig.debug.headless.value\n },\n {\n type: 'toggle',\n name: 'devtools',\n message: 'The DevTools for the headful browser',\n initial: defaultConfig.debug.devtools.value\n },\n {\n type: 'toggle',\n name: 'listenToConsole',\n message: 'The event listener for console messages from the browser',\n initial: defaultConfig.debug.listenToConsole.value\n },\n {\n type: 'toggle',\n name: 'dumpio',\n message: 'Redirects the browser stdout and stderr to NodeJS process',\n initial: defaultConfig.debug.dumpio.value\n },\n {\n type: 'number',\n name: 'slowMo',\n message: 'Puppeteer operations slow down in milliseconds',\n initial: defaultConfig.debug.slowMo.value\n },\n {\n type: 'number',\n name: 'debuggingPort',\n message: 'The port number for debugging',\n initial: defaultConfig.debug.debuggingPort.value\n }\n ]\n};\n\n// Absolute props that, in case of merging recursively, need to be force merged\nexport const absoluteProps = [\n 'options',\n 'globalOptions',\n 'themeOptions',\n 'resources',\n 'payload'\n];\n\n// Argument nesting level of all export server options\nexport const nestedArgs = {};\n\n/**\n * Recursively creates a chain of nested arguments from an object.\n *\n * @param {Object} obj - The object containing nested arguments.\n * @param {string} propChain - The current chain of nested properties\n * (used internally during recursion).\n */\nconst createNestedArgs = (obj, propChain = '') => {\n Object.keys(obj).forEach((k) => {\n if (!['puppeteer', 'highcharts'].includes(k)) {\n const entry = obj[k];\n if (typeof entry.value === 'undefined') {\n // Go deeper in the nested arguments\n createNestedArgs(entry, `${propChain}.${k}`);\n } else {\n // Create the chain of nested arguments\n nestedArgs[entry.cliName || k] = `${propChain}.${k}`.substring(1);\n\n // Support for the legacy, PhantomJS properties names\n if (entry.legacyName !== undefined) {\n nestedArgs[entry.legacyName] = `${propChain}.${k}`.substring(1);\n }\n }\n }\n });\n};\n\ncreateNestedArgs(defaultConfig);\n","/**\n * @fileoverview\n * This file is responsible for parsing the environment variables with the 'zod'\n * library. The parsed environment variables are then exported to be used\n * in the application as \"envs\". We should not use process.env directly\n * in the application as these would not be parsed properly.\n *\n * The environment variables are parsed and validated only once when\n * the application starts. We should write a custom validator or a transformer\n * for each of the options.\n */\n\nimport dotenv from 'dotenv';\nimport { z } from 'zod';\n\nimport { scriptsNames } from './schemas/config.js';\n\n// Load .env into environment variables\ndotenv.config();\n\n// Object with custom validators and transformers, to avoid repetition\n// in the Config object\nconst v = {\n // Splits string value into elements in an array, trims every element, checks\n // if an array is correct, if it is empty, and if it is, returns undefined\n array: (filterArray) =>\n z\n .string()\n .transform((value) =>\n value\n .split(',')\n .map((value) => value.trim())\n .filter((value) => filterArray.includes(value))\n )\n .transform((value) => (value.length ? value : undefined)),\n\n // Allows only true, false and correctly parse the value to boolean\n // or no value in which case the returned value will be undefined\n boolean: () =>\n z\n .enum(['true', 'false', ''])\n .transform((value) => (value !== '' ? value === 'true' : undefined)),\n\n // Allows passed values or no value in which case the returned value will\n // be undefined\n enum: (values) =>\n z\n .enum([...values, ''])\n .transform((value) => (value !== '' ? value : undefined)),\n\n // Trims the string value and checks if it is empty or contains stringified\n // values such as false, undefined, null, NaN, if it does, returns undefined\n string: () =>\n z\n .string()\n .trim()\n .refine(\n (value) =>\n !['false', 'undefined', 'null', 'NaN'].includes(value) ||\n value === '',\n (value) => ({\n message: `The string contains forbidden values, received '${value}'`\n })\n )\n .transform((value) => (value !== '' ? value : undefined)),\n\n // Checks if the string is a valid path directory (path format)\n path: () =>\n z\n .string()\n .trim()\n .refine(\n (value) => {\n // Simplified regex to match both absolute and relative paths\n return /^(\\.\\/|\\.\\.\\/|\\/|[a-zA-Z]:\\\\|[a-zA-Z]:\\/)?((?:[\\w-]+)[\\\\/]?)+$/.test(\n value\n );\n },\n {},\n {\n message: 'The string is an invalid path directory string.'\n }\n ),\n\n // Allows positive numbers or no value in which case the returned value will\n // be undefined\n positiveNum: () =>\n z\n .string()\n .trim()\n .refine(\n (value) =>\n value === '' || (!isNaN(parseFloat(value)) && parseFloat(value) > 0),\n (value) => ({\n message: `The value must be numeric and positive, received '${value}'`\n })\n )\n .transform((value) => (value !== '' ? parseFloat(value) : undefined)),\n\n // Allows non-negative numbers or no value in which case the returned value\n // will be undefined\n nonNegativeNum: () =>\n z\n .string()\n .trim()\n .refine(\n (value) =>\n value === '' || (!isNaN(parseFloat(value)) && parseFloat(value) >= 0),\n (value) => ({\n message: `The value must be numeric and non-negative, received '${value}'`\n })\n )\n .transform((value) => (value !== '' ? parseFloat(value) : undefined))\n};\n\nexport const Config = z.object({\n // puppeteer\n PUPPETEER_TEMP_DIR: v.path(),\n\n // highcharts\n HIGHCHARTS_VERSION: z\n .string()\n .trim()\n .refine(\n (value) => /^(latest|\\d+(\\.\\d+){0,2})$/.test(value) || value === '',\n (value) => ({\n message: `HIGHCHARTS_VERSION must be 'latest', a major version, or in the form XX.YY.ZZ, received '${value}'`\n })\n )\n .transform((value) => (value !== '' ? value : undefined)),\n HIGHCHARTS_CDN_URL: z\n .string()\n .trim()\n .refine(\n (value) =>\n value.startsWith('https://') ||\n value.startsWith('http://') ||\n value === '',\n (value) => ({\n message: `Invalid value for HIGHCHARTS_CDN_URL. It should start with http:// or https://, received '${value}'`\n })\n )\n .transform((value) => (value !== '' ? value : undefined)),\n HIGHCHARTS_CORE_SCRIPTS: v.array(scriptsNames.core),\n HIGHCHARTS_MODULE_SCRIPTS: v.array(scriptsNames.modules),\n HIGHCHARTS_INDICATOR_SCRIPTS: v.array(scriptsNames.indicators),\n HIGHCHARTS_FORCE_FETCH: v.boolean(),\n HIGHCHARTS_CACHE_PATH: v.string(),\n HIGHCHARTS_ADMIN_TOKEN: v.string(),\n\n // export\n EXPORT_TYPE: v.enum(['jpeg', 'png', 'pdf', 'svg']),\n EXPORT_CONSTR: v.enum(['chart', 'stockChart', 'mapChart', 'ganttChart']),\n EXPORT_DEFAULT_HEIGHT: v.positiveNum(),\n EXPORT_DEFAULT_WIDTH: v.positiveNum(),\n EXPORT_DEFAULT_SCALE: v.positiveNum(),\n EXPORT_RASTERIZATION_TIMEOUT: v.nonNegativeNum(),\n\n // custom\n CUSTOM_LOGIC_ALLOW_CODE_EXECUTION: v.boolean(),\n CUSTOM_LOGIC_ALLOW_FILE_RESOURCES: v.boolean(),\n\n // server\n SERVER_ENABLE: v.boolean(),\n SERVER_HOST: v.string(),\n SERVER_PORT: v.positiveNum(),\n SERVER_MAX_UPLOAD_SIZE: v.positiveNum(),\n SERVER_BENCHMARKING: v.boolean(),\n\n // server proxy\n SERVER_PROXY_HOST: v.string(),\n SERVER_PROXY_PORT: v.positiveNum(),\n SERVER_PROXY_USERNAME: v.string(),\n SERVER_PROXY_PASSWORD: v.string(),\n SERVER_PROXY_TIMEOUT: v.nonNegativeNum(),\n\n // server rate limiting\n SERVER_RATE_LIMITING_ENABLE: v.boolean(),\n SERVER_RATE_LIMITING_MAX_REQUESTS: v.nonNegativeNum(),\n SERVER_RATE_LIMITING_WINDOW: v.nonNegativeNum(),\n SERVER_RATE_LIMITING_DELAY: v.nonNegativeNum(),\n SERVER_RATE_LIMITING_TRUST_PROXY: v.boolean(),\n SERVER_RATE_LIMITING_SKIP_KEY: v.string(),\n SERVER_RATE_LIMITING_SKIP_TOKEN: v.string(),\n\n // server ssl\n SERVER_SSL_ENABLE: v.boolean(),\n SERVER_SSL_FORCE: v.boolean(),\n SERVER_SSL_PORT: v.positiveNum(),\n SERVER_SSL_CERT_PATH: v.string(),\n\n // pool\n POOL_MIN_WORKERS: v.nonNegativeNum(),\n POOL_MAX_WORKERS: v.nonNegativeNum(),\n POOL_WORK_LIMIT: v.positiveNum(),\n POOL_ACQUIRE_TIMEOUT: v.nonNegativeNum(),\n POOL_CREATE_TIMEOUT: v.nonNegativeNum(),\n POOL_DESTROY_TIMEOUT: v.nonNegativeNum(),\n POOL_IDLE_TIMEOUT: v.nonNegativeNum(),\n POOL_CREATE_RETRY_INTERVAL: v.nonNegativeNum(),\n POOL_REAPER_INTERVAL: v.nonNegativeNum(),\n POOL_BENCHMARKING: v.boolean(),\n\n // logger\n LOGGING_LEVEL: z\n .string()\n .trim()\n .refine(\n (value) =>\n value === '' ||\n (!isNaN(parseFloat(value)) &&\n parseFloat(value) >= 0 &&\n parseFloat(value) <= 5),\n (value) => ({\n message: `Invalid value for LOGGING_LEVEL. We only accept values from 0 to 5 as logging levels, received '${value}'`\n })\n )\n .transform((value) => (value !== '' ? parseFloat(value) : undefined)),\n LOGGING_FILE: v.string(),\n LOGGING_DEST: v.string(),\n LOGGING_TO_CONSOLE: v.boolean(),\n LOGGING_TO_FILE: v.boolean(),\n\n // ui\n UI_ENABLE: v.boolean(),\n UI_ROUTE: v.string(),\n\n // other\n OTHER_NODE_ENV: v.enum(['development', 'production', 'test']),\n OTHER_LISTEN_TO_PROCESS_EXITS: v.boolean(),\n OTHER_NO_LOGO: v.boolean(),\n OTHER_HARD_RESET_PAGE: v.boolean(),\n OTHER_BROWSER_SHELL_MODE: v.boolean(),\n OTHER_ALLOW_XLINK: v.boolean(),\n\n // debugger\n DEBUG_ENABLE: v.boolean(),\n DEBUG_HEADLESS: v.boolean(),\n DEBUG_DEVTOOLS: v.boolean(),\n DEBUG_LISTEN_TO_CONSOLE: v.boolean(),\n DEBUG_DUMPIO: v.boolean(),\n DEBUG_SLOW_MO: v.nonNegativeNum(),\n DEBUG_DEBUGGING_PORT: v.positiveNum()\n});\n\nexport const envs = Config.partial().parse(process.env);\n","/*******************************************************************************\n\nHighcharts Export Server\n\nCopyright (c) 2016-2024, Highsoft\n\nLicenced under the MIT licence.\n\nAdditionally a valid Highcharts license is required for use.\n\nSee LICENSE file in root for details.\n\n*******************************************************************************/\n\nimport { appendFile, existsSync, mkdirSync } from 'fs';\n\n// The available colors\nconst colors = ['red', 'yellow', 'blue', 'gray', 'green'];\n\n// The default logging config\nlet logging = {\n // Flags for logging status\n toConsole: true,\n toFile: false,\n pathCreated: false,\n // Log levels\n levelsDesc: [\n {\n title: 'error',\n color: colors[0]\n },\n {\n title: 'warning',\n color: colors[1]\n },\n {\n title: 'notice',\n color: colors[2]\n },\n {\n title: 'verbose',\n color: colors[3]\n },\n {\n title: 'benchmark',\n color: colors[4]\n }\n ],\n // Log listeners\n listeners: []\n};\n\n/**\n * Logs the provided texts to a file, if file logging is enabled. It creates\n * the necessary directory structure if not already created and appends the\n * content, including an optional prefix, to the specified log file.\n *\n * @param {string[]} texts - An array of texts to be logged.\n * @param {string} prefix - An optional prefix to be added to each log entry.\n */\nconst logToFile = (texts, prefix) => {\n if (!logging.pathCreated) {\n // Create if does not exist\n !existsSync(logging.dest) && mkdirSync(logging.dest);\n\n // We now assume the path is available, e.g. it's the responsibility\n // of the user to create the path with the correct access rights.\n logging.pathCreated = true;\n }\n\n // Add the content to a file\n appendFile(\n `${logging.dest}${logging.file}`,\n [prefix].concat(texts).join(' ') + '\\n',\n (error) => {\n if (error) {\n console.log(`[logger] Unable to write to log file: ${error}`);\n logging.toFile = false;\n }\n }\n );\n};\n\n/**\n * Logs a message. Accepts a variable amount of arguments. Arguments after\n * `level` will be passed directly to console.log, and/or will be joined\n * and appended to the log file.\n *\n * @param {any} args - An array of arguments where the first is the log level\n * and the rest are strings to build a message with.\n */\nexport const log = (...args) => {\n const [newLevel, ...texts] = args;\n\n // Current logging options\n const { levelsDesc, level } = logging;\n\n // Check if log level is within a correct range or is a benchmark log\n if (\n newLevel !== 5 &&\n (newLevel === 0 || newLevel > level || level > levelsDesc.length)\n ) {\n return;\n }\n\n // Get rid of the GMT text information\n const newDate = new Date().toString().split('(')[0].trim();\n\n // Create a message's prefix\n const prefix = `${newDate} [${levelsDesc[newLevel - 1].title}] -`;\n\n // Call available log listeners\n logging.listeners.forEach((fn) => {\n fn(prefix, texts.join(' '));\n });\n\n // Log to console\n if (logging.toConsole) {\n console.log.apply(\n undefined,\n [prefix.toString()[logging.levelsDesc[newLevel - 1].color]].concat(texts)\n );\n }\n\n // Log to file\n if (logging.toFile) {\n logToFile(texts, prefix);\n }\n};\n\n/**\n * Logs an error message with its stack trace. Optionally, a custom message\n * can be provided.\n *\n * @param {number} level - The log level.\n * @param {Error} error - The error object.\n * @param {string} customMessage - An optional custom message to be logged along\n * with the error.\n */\nexport const logWithStack = (newLevel, error, customMessage) => {\n // Get the main message\n const mainMessage = customMessage || error.message;\n\n // Current logging options\n const { level, levelsDesc } = logging;\n\n // Check if log level is within a correct range\n if (newLevel === 0 || newLevel > level || level > levelsDesc.length) {\n return;\n }\n\n // Get rid of the GMT text information\n const newDate = new Date().toString().split('(')[0].trim();\n\n // Create a message's prefix\n const prefix = `${newDate} [${levelsDesc[newLevel - 1].title}] -`;\n\n // If the customMessage exists, we want to display the whole stack message\n const stackMessage =\n error.message !== error.stackMessage || error.stackMessage === undefined\n ? error.stack\n : error.stack.split('\\n').slice(1).join('\\n');\n\n // Combine custom message or error message with error stack message\n const texts = [mainMessage, '\\n', stackMessage];\n\n // Log to console\n if (logging.toConsole) {\n console.log.apply(\n undefined,\n [prefix.toString()[logging.levelsDesc[newLevel - 1].color]].concat([\n mainMessage[colors[newLevel - 1]],\n '\\n',\n stackMessage\n ])\n );\n }\n\n // Call available log listeners\n logging.listeners.forEach((fn) => {\n fn(prefix, texts.join(' '));\n });\n\n // Log to file\n if (logging.toFile) {\n logToFile(texts, prefix);\n }\n};\n\n/**\n * Sets the log level to the specified value. Log levels are (0 = no logging,\n * 1 = error, 2 = warning, 3 = notice, 4 = verbose or 5 = benchmark)\n *\n * @param {number} newLevel - The new log level to be set.\n */\nexport const setLogLevel = (newLevel) => {\n if (newLevel >= 0 && newLevel <= logging.levelsDesc.length) {\n logging.level = newLevel;\n }\n};\n\n/**\n * Enables file logging with the specified destination and log file.\n *\n * @param {string} logDest - The destination path for log files.\n * @param {string} logFile - The log file name.\n */\nexport const enableFileLogging = (logDest, logFile) => {\n // Update logging options\n logging = {\n ...logging,\n dest: logDest || logging.dest,\n file: logFile || logging.file,\n toFile: true\n };\n\n if (logging.dest.length === 0) {\n return log(1, '[logger] File logging initialization: no path supplied.');\n }\n\n if (!logging.dest.endsWith('/')) {\n logging.dest += '/';\n }\n};\n\n/**\n * Initializes logging with the specified logging configuration.\n *\n * @param {Object} loggingOptions - The logging configuration object.\n */\nexport const initLogging = (loggingOptions) => {\n // Set all the logging options on our logging module object\n for (const [key, value] of Object.entries(loggingOptions)) {\n logging[key] = value;\n }\n\n // Set the log level\n setLogLevel(loggingOptions && parseInt(loggingOptions.level));\n\n // Set the log file path and name\n if (loggingOptions && loggingOptions.dest && loggingOptions.toFile) {\n enableFileLogging(\n loggingOptions.dest,\n loggingOptions.file || 'highcharts-export-server.log'\n );\n }\n};\n\n/**\n * Adds a listener function to the logging system.\n *\n * @param {function} fn - The listener function to be added.\n */\nexport const listen = (fn) => {\n logging.listeners.push(fn);\n};\n\nexport default {\n log,\n logWithStack,\n setLogLevel,\n enableFileLogging,\n initLogging,\n listen\n};\n","/*******************************************************************************\n\nHighcharts Export Server\n\nCopyright (c) 2016-2024, Highsoft\n\nLicenced under the MIT licence.\n\nAdditionally a valid Highcharts license is required for use.\n\nSee LICENSE file in root for details.\n\n*******************************************************************************/\n\nimport { readFileSync } from 'fs';\nimport { join } from 'path';\nimport { fileURLToPath } from 'url';\n\nimport { defaultConfig } from '../lib/schemas/config.js';\nimport { log, logWithStack } from './logger.js';\n\nconst MAX_BACKOFF_ATTEMPTS = 6;\n\nexport const __dirname = fileURLToPath(new URL('../.', import.meta.url));\n\n/**\n * Clears and standardizes text by replacing multiple consecutive whitespace\n * characters with a single space and trimming any leading or trailing\n * whitespace.\n *\n * @param {string} text - The input text to be cleared.\n * @param {RegExp} [rule=/\\s\\s+/g] - The regular expression rule to match\n * multiple consecutive whitespace characters.\n * @param {string} [replacer=' '] - The string used to replace multiple\n * consecutive whitespace characters.\n *\n * @returns {string} - The cleared and standardized text.\n */\nexport const clearText = (text, rule = /\\s\\s+/g, replacer = ' ') =>\n text.replaceAll(rule, replacer).trim();\n\n/**\n * Implements an exponential backoff strategy for retrying a function until\n * a certain number of attempts are reached.\n *\n * @param {Function} fn - The function to be retried.\n * @param {number} [attempt=0] - The current attempt number.\n * @param {...any} args - Arguments to be passed to the function.\n *\n * @returns {Promise} - A promise that resolves to the result of the function\n * if successful.\n *\n * @throws {Error} - Throws an error if the maximum number of attempts\n * is reached.\n */\nexport const expBackoff = async (fn, attempt = 0, ...args) => {\n try {\n // Try to call the function\n return await fn(...args);\n } catch (error) {\n // Calculate delay in ms\n const delayInMs = 2 ** attempt * 1000;\n\n // If the attempt exceeds the maximum attempts of reapeat, throw an error\n if (++attempt >= MAX_BACKOFF_ATTEMPTS) {\n throw error;\n }\n\n // Wait given amount of time\n await new Promise((response) => setTimeout(response, delayInMs));\n log(\n 3,\n `[pool] Waited ${delayInMs}ms until next call for the resource id: ${args[0]}.`\n );\n\n // Try again\n return expBackoff(fn, attempt, ...args);\n }\n};\n\n/**\n * Fixes the export type based on MIME types and file extensions.\n *\n * @param {string} type - The original export type.\n * @param {string} outfile - The file path or name.\n *\n * @returns {string} - The corrected export type.\n */\nexport const fixType = (type, outfile) => {\n // MIME types\n const mimeTypes = {\n 'image/png': 'png',\n 'image/jpeg': 'jpeg',\n 'application/pdf': 'pdf',\n 'image/svg+xml': 'svg'\n };\n\n // Formats\n const formats = ['png', 'jpeg', 'pdf', 'svg'];\n\n // Check if type and outfile's extensions are the same\n if (outfile) {\n const outType = outfile.split('.').pop();\n\n if (outType === 'jpg') {\n type = 'jpeg';\n } else if (formats.includes(outType) && type !== outType) {\n type = outType;\n }\n }\n\n // Return a correct type\n return mimeTypes[type] || formats.find((t) => t === type) || 'png';\n};\n\n/**\n * Handles and validates resources for export.\n *\n * @param {Object|string} resources - The resources to be handled. Can be either\n * a JSON object, stringified JSON or a path to a JSON file.\n * @param {boolean} allowFileResources - Whether to allow loading resources from\n * files.\n *\n * @returns {Object|undefined} - The handled resources or undefined if no valid\n * resources are found.\n */\nexport const handleResources = (resources = false, allowFileResources) => {\n const allowedProps = ['js', 'css', 'files'];\n\n let handledResources = resources;\n let correctResources = false;\n\n // Try to load resources from a file\n if (allowFileResources && resources.endsWith('.json')) {\n try {\n handledResources = isCorrectJSON(readFileSync(resources, 'utf8'));\n } catch (error) {\n return logWithStack(2, error, `[cli] No resources found.`);\n }\n } else {\n // Try to get JSON\n handledResources = isCorrectJSON(resources);\n\n // Get rid of the files section\n if (handledResources && !allowFileResources) {\n delete handledResources.files;\n }\n }\n\n // Filter from unnecessary properties\n for (const propName in handledResources) {\n if (!allowedProps.includes(propName)) {\n delete handledResources[propName];\n } else if (!correctResources) {\n correctResources = true;\n }\n }\n\n // Check if at least one of allowed properties is present\n if (!correctResources) {\n return log(3, `[cli] No resources found.`);\n }\n\n // Handle files section\n if (handledResources.files) {\n handledResources.files = handledResources.files.map((item) => item.trim());\n if (!handledResources.files || handledResources.files.length <= 0) {\n delete handledResources.files;\n }\n }\n\n // Return resources\n return handledResources;\n};\n\n/**\n * Validates and parses JSON data. Checks if provided data is or can\n * be a correct JSON. If a primitive is provided, it is stringified and returned.\n *\n * @param {Object|string} data - The JSON data to be validated and parsed.\n * @param {boolean} toString - Whether to return a stringified representation\n * of the parsed JSON.\n *\n * @returns {Object|string|boolean} - The parsed JSON object, stringified JSON,\n * or false if validation fails.\n */\nexport function isCorrectJSON(data, toString) {\n try {\n // Get the string representation if not already before parsing\n const parsedData = JSON.parse(\n typeof data !== 'string' ? JSON.stringify(data) : data\n );\n\n // Return a stringified representation of a JSON if required\n if (typeof parsedData !== 'string' && toString) {\n return JSON.stringify(parsedData);\n }\n\n // Return a JSON\n return parsedData;\n } catch {\n return false;\n }\n}\n\n/**\n * Checks if the given item is an object.\n *\n * @param {any} item - The item to be checked.\n *\n * @returns {boolean} - True if the item is an object, false otherwise.\n */\nexport const isObject = (item) =>\n typeof item === 'object' && !Array.isArray(item) && item !== null;\n\n/**\n * Checks if the given object is empty.\n *\n * @param {Object} item - The object to be checked.\n *\n * @returns {boolean} - True if the object is empty, false otherwise.\n */\nexport const isObjectEmpty = (item) =>\n typeof item === 'object' &&\n !Array.isArray(item) &&\n item !== null &&\n Object.keys(item).length === 0;\n\n/**\n * Checks if a private IP range URL is found in the given string.\n *\n * @param {string} item - The string to be checked for a private IP range URL.\n *\n * @returns {boolean} - True if a private IP range URL is found, false\n * otherwise.\n */\nexport const isPrivateRangeUrlFound = (item) => {\n const regexPatterns = [\n /xlink:href=\"(?:http:\\/\\/|https:\\/\\/)?localhost\\b/,\n /xlink:href=\"(?:http:\\/\\/|https:\\/\\/)?10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b/,\n /xlink:href=\"(?:http:\\/\\/|https:\\/\\/)?127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b/,\n /xlink:href=\"(?:http:\\/\\/|https:\\/\\/)?172\\.(1[6-9]|2[0-9]|3[0-1])\\.\\d{1,3}\\.\\d{1,3}\\b/,\n /xlink:href=\"(?:http:\\/\\/|https:\\/\\/)?192\\.168\\.\\d{1,3}\\.\\d{1,3}\\b/\n ];\n\n return regexPatterns.some((pattern) => pattern.test(item));\n};\n\n/**\n * Creates a deep copy of the given object or array.\n *\n * @param {Object|Array} obj - The object or array to be deeply copied.\n *\n * @returns {Object|Array} - The deep copy of the provided object or array.\n */\nexport const deepCopy = (obj) => {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n\n const copy = Array.isArray(obj) ? [] : {};\n\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n copy[key] = deepCopy(obj[key]);\n }\n }\n\n return copy;\n};\n\n/**\n * Converts the provided options object to a JSON-formatted string with the\n * option to preserve functions.\n *\n * @param {Object} options - The options object to be converted to a string.\n * @param {boolean} allowFunctions - If set to true, functions are preserved\n * in the output.\n *\n * @returns {string} - The JSON-formatted string representing the options.\n */\nexport const optionsStringify = (options, allowFunctions) => {\n const replacerCallback = (name, value) => {\n if (typeof value === 'string') {\n value = value.trim();\n\n // If allowFunctions is set to true, preserve functions\n if (\n (value.startsWith('function(') || value.startsWith('function (')) &&\n value.endsWith('}')\n ) {\n value = allowFunctions\n ? `EXP_FUN${(value + '').replaceAll(/\\n|\\t|\\r/g, ' ')}EXP_FUN`\n : undefined;\n }\n }\n\n return typeof value === 'function'\n ? `EXP_FUN${(value + '').replaceAll(/\\n|\\t|\\r/g, ' ')}EXP_FUN`\n : value;\n };\n\n // Stringify options and if required, replace special functions marks\n return JSON.stringify(options, replacerCallback).replaceAll(\n /\"EXP_FUN|EXP_FUN\"/g,\n ''\n );\n};\n\n/**\n * Prints the Highcharts Export Server logo and version information.\n *\n * @param {boolean} noLogo - If true, only prints version information without\n * the logo.\n */\nexport const printLogo = (noLogo) => {\n // Get package version either from env or from package.json\n const packageVersion = JSON.parse(\n readFileSync(join(__dirname, 'package.json'))\n ).version;\n\n // Print text only\n if (noLogo) {\n console.log(`Starting Highcharts Export Server v${packageVersion}...`);\n return;\n }\n\n // Print the logo\n console.log(\n readFileSync(__dirname + '/msg/startup.msg').toString().bold.yellow,\n `v${packageVersion}\\n`.bold\n );\n};\n\n/**\n * Prints the usage information for CLI arguments. If required, it can list\n * properties recursively\n */\nexport function printUsage() {\n const pad = 48;\n const readme = 'https://github.com/highcharts/node-export-server#readme';\n\n // Display readme information\n console.log(\n '\\nUsage of CLI arguments:'.bold,\n '\\n------',\n `\\nFor more detailed information, visit the readme at: ${readme.bold.yellow}.`\n );\n\n const cycleCategories = (options) => {\n for (const [name, option] of Object.entries(options)) {\n // If category has more levels, go further\n if (!Object.prototype.hasOwnProperty.call(option, 'value')) {\n cycleCategories(option);\n } else {\n let descName = ` --${option.cliName || name} ${\n ('<' + option.type + '>').green\n } `;\n if (descName.length < pad) {\n for (let i = descName.length; i < pad; i++) {\n descName += '.';\n }\n }\n\n // Display correctly aligned messages\n console.log(\n descName,\n option.description,\n `[Default: ${option.value.toString().bold}]`.blue\n );\n }\n }\n };\n\n // Cycle through options of each categories and display the usage info\n Object.keys(defaultConfig).forEach((category) => {\n // Only puppeteer and highcharts categories cannot be configured through CLI\n if (!['puppeteer', 'highcharts'].includes(category)) {\n console.log(`\\n${category.toUpperCase()}`.red);\n cycleCategories(defaultConfig[category]);\n }\n });\n console.log('\\n');\n}\n\n/**\n * Rounds a number to the specified precision.\n *\n * @param {number} value - The number to be rounded.\n * @param {number} precision - The number of decimal places to round to.\n *\n * @returns {number} - The rounded number.\n */\nexport const roundNumber = (value, precision = 1) => {\n const multiplier = Math.pow(10, precision || 0);\n return Math.round(+value * multiplier) / multiplier;\n};\n\n/**\n * Converts a value to a boolean.\n *\n * @param {any} item - The value to be converted to a boolean.\n *\n * @returns {boolean} - The boolean representation of the input value.\n */\nexport const toBoolean = (item) =>\n ['false', 'undefined', 'null', 'NaN', '0', ''].includes(item)\n ? false\n : !!item;\n\n/**\n * Wraps custom code to execute it safely.\n *\n * @param {string} customCode - The custom code to be wrapped.\n * @param {boolean} allowFileResources - Flag to allow loading code from a file.\n *\n * @returns {string|boolean} - The wrapped custom code or false if wrapping\n * fails.\n */\nexport const wrapAround = (customCode, allowFileResources) => {\n if (customCode && typeof customCode === 'string') {\n customCode = customCode.trim();\n\n if (customCode.endsWith('.js')) {\n return allowFileResources\n ? wrapAround(readFileSync(customCode, 'utf8'))\n : false;\n } else if (\n customCode.startsWith('function()') ||\n customCode.startsWith('function ()') ||\n customCode.startsWith('()=>') ||\n customCode.startsWith('() =>')\n ) {\n return `(${customCode})()`;\n }\n return customCode.replace(/;$/, '');\n }\n};\n\n/**\n * Utility to measure elapsed time using the Node.js process.hrtime() method.\n *\n * @returns {function(): number} - A function to calculate the elapsed time\n * in milliseconds.\n */\nexport const measureTime = () => {\n const start = process.hrtime.bigint();\n return () => Number(process.hrtime.bigint() - start) / 1000000;\n};\n\nexport default {\n __dirname,\n clearText,\n expBackoff,\n fixType,\n handleResources,\n isCorrectJSON,\n isObject,\n isObjectEmpty,\n isPrivateRangeUrlFound,\n optionsStringify,\n printLogo,\n printUsage,\n roundNumber,\n toBoolean,\n wrapAround,\n measureTime\n};\n","/*******************************************************************************\n\nHighcharts Export Server\n\nCopyright (c) 2016-2024, Highsoft\n\nLicenced under the MIT licence.\n\nAdditionally a valid Highcharts license is required for use.\n\nSee LICENSE file in root for details.\n\n*******************************************************************************/\n\nimport { existsSync, readFileSync, promises as fsPromises } from 'fs';\n\nimport prompts from 'prompts';\n\nimport {\n absoluteProps,\n defaultConfig,\n nestedArgs,\n promptsConfig\n} from './schemas/config.js';\nimport { envs } from './envs.js';\nimport { log, logWithStack } from './logger.js';\nimport { deepCopy, isObject, printUsage, toBoolean } from './utils.js';\n\nlet generalOptions = {};\n\n/**\n * Retrieves and returns the general options for the export process.\n *\n * @returns {Object} The general options object.\n */\nexport const getOptions = () => generalOptions;\n\n/**\n * Initializes and sets the general options for the server instace, keeping\n * the principle of the options load priority. It accepts optional userOptions\n * and args from the CLI.\n *\n * @param {Object} userOptions - User-provided options for customization.\n * @param {Array} args - Command-line arguments for additional configuration\n * (CLI usage).\n *\n * @returns {Object} The updated general options object.\n */\nexport const setOptions = (userOptions, args) => {\n // Only for the CLI usage\n if (args?.length) {\n // Get the additional options from the custom JSON file\n generalOptions = loadConfigFile(args);\n }\n\n // Update the default config with a correct option values\n updateDefaultConfig(defaultConfig, generalOptions);\n\n // Set values for server's options and returns them\n generalOptions = initOptions(defaultConfig);\n\n // Apply user options if there are any\n if (userOptions) {\n // Merge user options\n generalOptions = mergeConfigOptions(\n generalOptions,\n userOptions,\n absoluteProps\n );\n }\n\n // Only for the CLI usage\n if (args?.length) {\n // Pair provided arguments\n generalOptions = pairArgumentValue(generalOptions, args, defaultConfig);\n }\n\n // Return final general options\n return generalOptions;\n};\n\n/**\n * Allows manual configuration based on specified prompts and saves\n * the configuration to a file.\n *\n * @param {string} configFileName - The name of the configuration file.\n *\n * @returns {Promise} A Promise that resolves to true once the manual\n * configuration is completed and saved.\n */\nexport const manualConfig = async (configFileName) => {\n // Prepare a config object\n let configFile = {};\n\n // Check if provided config file exists\n if (existsSync(configFileName)) {\n configFile = JSON.parse(readFileSync(configFileName, 'utf8'));\n }\n\n // Question about a configuration category\n const onSubmit = async (p, categories) => {\n let questionsCounter = 0;\n let allQuestions = [];\n\n // Create a corresponding property in the manualConfig object\n for (const section of categories) {\n // Mark each option with a section\n promptsConfig[section] = promptsConfig[section].map((option) => ({\n ...option,\n section\n }));\n\n // Collect the questions\n allQuestions = [...allQuestions, ...promptsConfig[section]];\n }\n\n await prompts(allQuestions, {\n onSubmit: async (prompt, answer) => {\n // Get the default module scripts\n if (prompt.name === 'moduleScripts') {\n answer = answer.length\n ? answer.map((module) => prompt.choices[module])\n : prompt.choices;\n\n configFile[prompt.section][prompt.name] = answer;\n } else {\n configFile[prompt.section] = recursiveProps(\n Object.assign({}, configFile[prompt.section] || {}),\n prompt.name.split('.'),\n prompt.choices ? prompt.choices[answer] : answer\n );\n }\n\n if (++questionsCounter === allQuestions.length) {\n try {\n await fsPromises.writeFile(\n configFileName,\n JSON.stringify(configFile, null, 2),\n 'utf8'\n );\n } catch (error) {\n logWithStack(\n 1,\n error,\n `[config] An error occurred while creating the ${configFileName} file.`\n );\n }\n return true;\n }\n }\n });\n\n return true;\n };\n\n // Find the categories\n const choices = Object.keys(promptsConfig).map((choice) => ({\n title: `${choice} options`,\n value: choice\n }));\n\n // Category prompt\n return prompts(\n {\n type: 'multiselect',\n name: 'category',\n message: 'Which category do you want to configure?',\n hint: 'Space: Select specific, A: Select all, Enter: Confirm.',\n instructions: '',\n choices\n },\n { onSubmit }\n );\n};\n\n/**\n * Maps old-structured (PhantomJS) options to a new configuration format\n * (Puppeteer).\n *\n * @param {Object} oldOptions - Old-structured options to be mapped.\n *\n * @returns {Object} New options structured based on the defined nestedArgs\n * mapping.\n */\nexport const mapToNewConfig = (oldOptions) => {\n const newOptions = {};\n // Cycle through old-structured options\n for (const [key, value] of Object.entries(oldOptions)) {\n const propertiesChain = nestedArgs[key] ? nestedArgs[key].split('.') : [];\n\n // Populate object in correct properties levels\n propertiesChain.reduce(\n (obj, prop, index) =>\n (obj[prop] =\n propertiesChain.length - 1 === index ? value : obj[prop] || {}),\n newOptions\n );\n }\n return newOptions;\n};\n\n/**\n * Merges two sets of configuration options, considering absolute properties.\n *\n * @param {Object} options - Original configuration options.\n * @param {Object} newOptions - New configuration options to be merged.\n * @param {Array} absoluteProps - List of properties that should\n * not be recursively merged.\n *\n * @returns {Object} Merged configuration options.\n */\nexport const mergeConfigOptions = (options, newOptions, absoluteProps = []) => {\n const mergedOptions = deepCopy(options);\n\n for (const [key, value] of Object.entries(newOptions)) {\n mergedOptions[key] =\n isObject(value) &&\n !absoluteProps.includes(key) &&\n mergedOptions[key] !== undefined\n ? mergeConfigOptions(mergedOptions[key], value, absoluteProps)\n : value !== undefined\n ? value\n : mergedOptions[key];\n }\n\n return mergedOptions;\n};\n\n/**\n * Initializes export settings based on provided exportOptions\n * and generalOptions.\n *\n * @param {Object} exportOptions - Options specific to the export process.\n * @param {Object} generalOptions - General configuration options.\n *\n * @returns {Object} Initialized export settings.\n */\nexport const initExportSettings = (exportOptions, generalOptions = {}) => {\n let options = {};\n\n if (exportOptions.svg) {\n options = deepCopy(generalOptions);\n options.export.type = exportOptions.type || exportOptions.export.type;\n options.export.scale = exportOptions.scale || exportOptions.export.scale;\n options.export.outfile =\n exportOptions.outfile || exportOptions.export.outfile;\n options.payload = {\n svg: exportOptions.svg\n };\n } else {\n options = mergeConfigOptions(\n generalOptions,\n exportOptions,\n // Omit going down recursively with the belows\n absoluteProps\n );\n }\n\n options.export.outfile =\n options.export?.outfile || `chart.${options.export?.type || 'png'}`;\n return options;\n};\n\n/**\n * Loads additional configuration from a specified file using\n * the --loadConfig option.\n *\n * @param {Array} args - Command-line arguments to check for\n * the --loadConfig option.\n *\n * @returns {Object} Additional configuration loaded from the specified file,\n * or an empty object if not found or invalid.\n */\nfunction loadConfigFile(args) {\n // Check if the --loadConfig option was used\n const configIndex = args.findIndex(\n (arg) => arg.replace(/-/g, '') === 'loadConfig'\n );\n\n // Check if the --loadConfig has a value\n if (configIndex > -1 && args[configIndex + 1]) {\n const fileName = args[configIndex + 1];\n try {\n // Check if an additional config file is a correct JSON file\n if (fileName && fileName.endsWith('.json')) {\n // Load an optional custom JSON config file\n return JSON.parse(readFileSync(fileName));\n }\n } catch (error) {\n logWithStack(\n 2,\n error,\n `[config] Unable to load the configuration from the ${fileName} file.`\n );\n }\n }\n\n // No additional options to return\n return {};\n}\n\n/**\n * Updates the default configuration object with values from a custom object\n * and environment variables.\n *\n * @param {Object} configObj - The default configuration object.\n * @param {Object} customObj - Custom configuration object to override defaults.\n * @param {string} propChain - Property chain for tracking nested properties\n * during recursion.\n */\nfunction updateDefaultConfig(configObj, customObj = {}, propChain = '') {\n Object.keys(configObj).forEach((key) => {\n const entry = configObj[key];\n const customValue = customObj && customObj[key];\n\n if (typeof entry.value === 'undefined') {\n updateDefaultConfig(entry, customValue, `${propChain}.${key}`);\n } else {\n // If a value from a custom JSON exists, it take precedence\n if (customValue !== undefined) {\n entry.value = customValue;\n }\n\n // If a value from an env variable exists, it take precedence\n if (entry.envLink in envs && envs[entry.envLink] !== undefined) {\n entry.value = envs[entry.envLink];\n }\n }\n });\n}\n\n/**\n * Initializes options object based on provided items, setting values from\n * nested properties recursively.\n *\n * @param {Object} items - Configuration items to be used for initializing\n * options.\n *\n * @returns {Object} Initialized options object.\n */\nfunction initOptions(items) {\n let options = {};\n for (const [name, item] of Object.entries(items)) {\n options[name] = Object.prototype.hasOwnProperty.call(item, 'value')\n ? item.value\n : initOptions(item);\n }\n return options;\n}\n\n/**\n * Pairs argument values with corresponding options in the configuration,\n * updating the options object.\n *\n * @param {Object} options - Configuration options object to be updated.\n * @param {Array} args - Command-line arguments containing values for specific\n * options.\n * @param {Object} defaultConfig - Default configuration object for reference.\n *\n * @returns {Object} Updated options object.\n */\nfunction pairArgumentValue(options, args, defaultConfig) {\n let showUsage = false;\n for (let i = 0; i < args.length; i++) {\n const option = args[i].replace(/-/g, '');\n\n // Find the right place for property's value\n const propertiesChain = nestedArgs[option]\n ? nestedArgs[option].split('.')\n : [];\n\n // Get the correct type for CLI args which are passed as strings\n let argumentType;\n propertiesChain.reduce((obj, prop, index) => {\n if (propertiesChain.length - 1 === index) {\n argumentType = obj[prop].type;\n }\n return obj[prop];\n }, defaultConfig);\n\n propertiesChain.reduce((obj, prop, index) => {\n if (propertiesChain.length - 1 === index) {\n // Finds an option and set a corresponding value\n if (typeof obj[prop] !== 'undefined') {\n if (args[++i]) {\n if (argumentType === 'boolean') {\n obj[prop] = toBoolean(args[i]);\n } else if (argumentType === 'number') {\n obj[prop] = +args[i];\n } else if (argumentType.indexOf(']') >= 0) {\n obj[prop] = args[i].split(',');\n } else {\n obj[prop] = args[i];\n }\n } else {\n log(\n 2,\n `[config] Missing value for the '${option}' argument. Using the default value.`\n );\n showUsage = true;\n }\n }\n }\n return obj[prop];\n }, options);\n }\n\n // Display the usage for the reference if needed\n if (showUsage) {\n printUsage(defaultConfig);\n }\n\n return options;\n}\n\n/**\n * Recursively updates properties in an object based on nested names and assigns\n * the final value.\n *\n * @param {Object} objectToUpdate - The object to be updated.\n * @param {Array} nestedNames - Array of nested property names.\n * @param {any} value - The final value to be assigned.\n *\n * @returns {Object} Updated object with assigned values.\n */\nfunction recursiveProps(objectToUpdate, nestedNames, value) {\n while (nestedNames.length > 1) {\n const propName = nestedNames.shift();\n\n // Create a property in object if it doesn't exist\n if (!Object.prototype.hasOwnProperty.call(objectToUpdate, propName)) {\n objectToUpdate[propName] = {};\n }\n\n // Call function again if there still names to go\n objectToUpdate[propName] = recursiveProps(\n Object.assign({}, objectToUpdate[propName]),\n nestedNames,\n value\n );\n\n return objectToUpdate;\n }\n\n // Assign the final value\n objectToUpdate[nestedNames[0]] = value;\n return objectToUpdate;\n}\n\nexport default {\n getOptions,\n setOptions,\n manualConfig,\n mapToNewConfig,\n mergeConfigOptions,\n initExportSettings\n};\n","/**\n * This module exports two functions: fetch (for GET requests) and post (for POST requests).\n */\n\nimport http from 'http';\nimport https from 'https';\n\n/**\n * Returns the HTTP or HTTPS protocol module based on the provided URL.\n *\n * @param {string} url - The URL to determine the protocol.\n *\n * @returns {Object} The HTTP or HTTPS protocol module (http or https).\n */\nconst getProtocol = (url) => (url.startsWith('https') ? https : http);\n\n/**\n * Fetches data from the specified URL using either HTTP or HTTPS protocol.\n *\n * @param {string} url - The URL to fetch data from.\n * @param {Object} requestOptions - Options for the HTTP request (optional).\n *\n * @returns {Promise} Promise resolving to the HTTP response object\n * with added 'text' property or rejecting with an error.\n */\nasync function fetch(url, requestOptions = {}) {\n return new Promise((resolve, reject) => {\n const protocol = getProtocol(url);\n\n protocol\n .get(\n url,\n Object.assign(\n {\n headers: {\n 'User-Agent': 'highcharts/export',\n Referer: 'highcharts.export'\n }\n },\n requestOptions || {}\n ),\n (res) => {\n let data = '';\n\n // A chunk of data has been received.\n res.on('data', (chunk) => {\n data += chunk;\n });\n\n // The whole response has been received.\n res.on('end', () => {\n if (!data) {\n reject('Nothing was fetched from the URL.');\n }\n\n res.text = data;\n resolve(res);\n });\n }\n )\n .on('error', (error) => {\n reject(error);\n });\n });\n}\n\n/**\n * Sends a POST request to the specified URL with the provided JSON body using\n * either HTTP or HTTPS protocol.\n *\n * @param {string} url - The URL to send the POST request to.\n * @param {Object} body - The JSON body to include in the POST request\n * (optional, default is an empty object).\n * @param {Object} requestOptions - Options for the HTTP request (optional).\n *\n * @returns {Promise} Promise resolving to the HTTP response object with\n * added 'text' property or rejecting with an error.\n */\nasync function post(url, body = {}, requestOptions = {}) {\n return new Promise((resolve, reject) => {\n const protocol = getProtocol(url);\n const data = JSON.stringify(body);\n\n // Set default headers and merge with requestOptions\n const options = Object.assign(\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Content-Length': data.length\n }\n },\n requestOptions\n );\n\n const req = protocol\n .request(url, options, (res) => {\n let responseData = '';\n\n // A chunk of data has been received.\n res.on('data', (chunk) => {\n responseData += chunk;\n });\n\n // The whole response has been received.\n res.on('end', () => {\n try {\n res.text = responseData;\n resolve(res);\n } catch (error) {\n reject(error);\n }\n });\n })\n .on('error', (error) => {\n reject(error);\n });\n\n // Write the request body and end the request.\n req.write(data);\n req.end();\n });\n}\n\nexport default fetch;\nexport { fetch, post };\n","class ExportError extends Error {\n constructor(message) {\n super();\n this.message = message;\n this.stackMessage = message;\n }\n\n setError(error) {\n this.error = error;\n if (error.name) {\n this.name = error.name;\n }\n if (error.statusCode) {\n this.statusCode = error.statusCode;\n }\n if (error.stack) {\n this.stackMessage = error.message;\n this.stack = error.stack;\n }\n return this;\n }\n}\n\nexport default ExportError;\n","/*******************************************************************************\n\nHighcharts Export Server\n\nCopyright (c) 2016-2024, Highsoft\n\nLicenced under the MIT licence.\n\nAdditionally a valid Highcharts license is required for use.\n\nSee LICENSE file in root for details.\n\n*******************************************************************************/\n\n// The cache manager manages the Highcharts library and its dependencies.\n// The cache itself is stored in .cache, and is checked by the config system\n// before starting the service\n\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';\nimport { join } from 'path';\n\nimport { HttpsProxyAgent } from 'https-proxy-agent';\n\nimport { getOptions } from './config.js';\nimport { envs } from './envs.js';\nimport { fetch } from './fetch.js';\nimport { log } from './logger.js';\nimport { __dirname } from './utils.js';\n\nimport ExportError from './errors/ExportError.js';\n\nconst cache = {\n cdnURL: 'https://code.highcharts.com/',\n activeManifest: {},\n sources: '',\n hcVersion: ''\n};\n\n/**\n * Extracts and caches the Highcharts version from the sources string.\n *\n * @returns {string} The extracted Highcharts version.\n */\nexport const extractVersion = (cache) => {\n return cache.sources\n .substring(0, cache.sources.indexOf('*/'))\n .replace('/*', '')\n .replace('*/', '')\n .replace(/\\n/g, '')\n .trim();\n};\n\n/**\n * Extracts the Highcharts module name based on the scriptPath.\n */\nexport const extractModuleName = (scriptPath) => {\n return scriptPath.replace(\n /(.*)\\/|(.*)modules\\/|stock\\/(.*)indicators\\/|maps\\/(.*)modules\\//gi,\n ''\n );\n};\n\n/**\n * Saves the provided configuration and fetched modules to the cache manifest\n * file.\n *\n * @param {object} config - Highcharts-related configuration object.\n * @param {object} fetchedModules - An object that contains mapped names of\n * fetched Highcharts modules to use.\n *\n * @throws {ExportError} Throws an ExportError if an error occurs while writing\n * the cache manifest.\n */\nexport const saveConfigToManifest = async (config, fetchedModules) => {\n const newManifest = {\n version: config.version,\n modules: fetchedModules || {}\n };\n\n // Update cache object with the current modules\n cache.activeManifest = newManifest;\n\n log(3, '[cache] Writing a new manifest.');\n try {\n writeFileSync(\n join(__dirname, config.cachePath, 'manifest.json'),\n JSON.stringify(newManifest),\n 'utf8'\n );\n } catch (error) {\n throw new ExportError('[cache] Error writing the cache manifest.').setError(\n error\n );\n }\n};\n\n/**\n * Fetches a single script and updates the fetchedModules accordingly.\n *\n * @param {string} script - A path to script to get.\n * @param {Object} requestOptions - Additional options for the proxy agent\n * to use for a request.\n * @param {Object} fetchedModules - An object which tracks which Highcharts\n * modules have been fetched.\n * @param {boolean} shouldThrowError - A flag to indicate if the error should be\n * thrown. This should be used only for the core scripts.\n *\n * @returns {Promise} A Promise resolving to the text representation\n * of the fetched script.\n *\n * @throws {ExportError} Throws an ExportError if there is a problem with\n * fetching the script.\n */\nexport const fetchAndProcessScript = async (\n script,\n requestOptions,\n fetchedModules,\n shouldThrowError = false\n) => {\n // Get rid of the .js from the custom strings\n if (script.endsWith('.js')) {\n script = script.substring(0, script.length - 3);\n }\n\n log(4, `[cache] Fetching script - ${script}.js`);\n\n // Fetch the script\n const response = await fetch(`${script}.js`, requestOptions);\n\n // If OK, return its text representation\n if (response.statusCode === 200 && typeof response.text == 'string') {\n if (fetchedModules) {\n const moduleName = extractModuleName(script);\n fetchedModules[moduleName] = 1;\n }\n\n return response.text;\n }\n\n if (shouldThrowError) {\n throw new ExportError(\n `Could not fetch the ${script}.js. The script might not exist in the requested version (status code: ${response.statusCode}).`\n ).setError(response);\n } else {\n log(\n 2,\n `[cache] Could not fetch the ${script}.js. The script might not exist in the requested version.`\n );\n }\n\n return '';\n};\n\n/**\n * Fetches Highcharts scripts and customScripts from the given CDNs.\n *\n * @param {string} coreScripts - Array of Highcharts core scripts to fetch.\n * @param {string} moduleScripts - Array of Highcharts modules to fetch.\n * @param {string} customScripts - Array of custom script paths to fetch\n * (full URLs).\n * @param {object} proxyOptions - Options for the proxy agent to use for\n * a request.\n * @param {object} fetchedModules - An object which tracks which Highcharts\n * modules have been fetched.\n *\n * @returns {Promise} The fetched scripts content joined.\n */\nexport const fetchScripts = async (\n coreScripts,\n moduleScripts,\n customScripts,\n proxyOptions,\n fetchedModules\n) => {\n // Configure proxy if exists\n let proxyAgent;\n const { host, port, username, password } = proxyOptions;\n\n // Try to create a Proxy Agent\n if (host && port) {\n try {\n proxyAgent = new HttpsProxyAgent({\n host,\n port,\n ...(username && password ? { username, password } : {})\n });\n } catch (error) {\n throw new ExportError('[cache] Could not create a Proxy Agent.').setError(\n error\n );\n }\n }\n\n // If exists, add proxy agent to request options\n const requestOptions = proxyAgent\n ? {\n agent: proxyAgent,\n timeout: envs.SERVER_PROXY_TIMEOUT\n }\n : {};\n\n const allFetchPromises = [\n ...coreScripts.map((script) =>\n fetchAndProcessScript(`${script}`, requestOptions, fetchedModules, true)\n ),\n ...moduleScripts.map((script) =>\n fetchAndProcessScript(`${script}`, requestOptions, fetchedModules)\n ),\n ...customScripts.map((script) =>\n fetchAndProcessScript(`${script}`, requestOptions)\n )\n ];\n\n const fetchedScripts = await Promise.all(allFetchPromises);\n return fetchedScripts.join(';\\n');\n};\n\n/**\n * Updates the local cache with Highcharts scripts and their versions.\n *\n * @param {Object} options - Object containing all options.\n * @param {string} sourcePath - The path to the source file in the cache.\n *\n * @returns {Promise} A Promise resolving to an object representing\n * the fetched modules.\n *\n * @throws {ExportError} Throws an ExportError if there is an issue updating\n * the local Highcharts cache.\n */\nexport const updateCache = async (\n highchartsOptions,\n proxyOptions,\n sourcePath\n) => {\n const version = highchartsOptions.version;\n const hcVersion = version === 'latest' || !version ? '' : `${version}/`;\n const cdnURL = highchartsOptions.cdnURL || cache.cdnURL;\n\n log(\n 3,\n `[cache] Updating cache version to Highcharts: ${hcVersion || 'latest'}.`\n );\n\n const fetchedModules = {};\n try {\n cache.sources = await fetchScripts(\n [\n ...highchartsOptions.coreScripts.map((c) => `${cdnURL}${hcVersion}${c}`)\n ],\n [\n ...highchartsOptions.moduleScripts.map((m) =>\n m === 'map'\n ? `${cdnURL}maps/${hcVersion}modules/${m}`\n : `${cdnURL}${hcVersion}modules/${m}`\n ),\n ...highchartsOptions.indicatorScripts.map(\n (i) => `${cdnURL}stock/${hcVersion}indicators/${i}`\n )\n ],\n highchartsOptions.customScripts,\n proxyOptions,\n fetchedModules\n );\n\n cache.hcVersion = extractVersion(cache);\n\n // Save the fetched modules into caches' source JSON\n writeFileSync(sourcePath, cache.sources);\n return fetchedModules;\n } catch (error) {\n throw new ExportError(\n '[cache] Unable to update the local Highcharts cache.'\n ).setError(error);\n }\n};\n\n/**\n * Updates the Highcharts version in the applied configuration and checks\n * the cache for the new version.\n *\n * @param {string} newVersion - The new Highcharts version to be applied.\n *\n * @returns {Promise<(object|boolean)>} A Promise resolving to the updated\n * configuration with the new version, or false if no applied configuration\n * exists.\n */\nexport const updateVersion = async (newVersion) => {\n const options = getOptions();\n if (options?.highcharts) {\n options.highcharts.version = newVersion;\n }\n await checkAndUpdateCache(options);\n};\n\n/**\n * Checks the cache for Highcharts dependencies, updates the cache if needed,\n * and loads the sources.\n *\n * @param {Object} options - Object containing all options.\n *\n * @returns {Promise} A Promise that resolves once the cache is checked\n * and updated.\n *\n * @throws {ExportError} Throws an ExportError if there is an issue updating\n * or reading the cache.\n */\nexport const checkAndUpdateCache = async (options) => {\n const { highcharts, server } = options;\n const cachePath = join(__dirname, highcharts.cachePath);\n\n let fetchedModules;\n // Prepare paths to manifest and sources from the .cache folder\n const manifestPath = join(cachePath, 'manifest.json');\n const sourcePath = join(cachePath, 'sources.js');\n\n // Create the cache destination if it doesn't exist already\n !existsSync(cachePath) && mkdirSync(cachePath);\n\n // Fetch all the scripts either if manifest.json does not exist\n // or if the forceFetch option is enabled\n if (!existsSync(manifestPath) || highcharts.forceFetch) {\n log(3, '[cache] Fetching and caching Highcharts dependencies.');\n fetchedModules = await updateCache(highcharts, server.proxy, sourcePath);\n } else {\n let requestUpdate = false;\n\n // Read the manifest JSON\n const manifest = JSON.parse(readFileSync(manifestPath));\n\n // Check if the modules is an array, if so, we rewrite it to a map to make\n // it easier to resolve modules.\n if (manifest.modules && Array.isArray(manifest.modules)) {\n const moduleMap = {};\n manifest.modules.forEach((m) => (moduleMap[m] = 1));\n manifest.modules = moduleMap;\n }\n\n const { coreScripts, moduleScripts, indicatorScripts } = highcharts;\n const numberOfModules =\n coreScripts.length + moduleScripts.length + indicatorScripts.length;\n\n // Compare the loaded highcharts config with the contents in cache.\n // If there are changes, fetch requested modules and products,\n // and bake them into a giant blob. Save the blob.\n if (manifest.version !== highcharts.version) {\n log(\n 2,\n '[cache] A Highcharts version mismatch in the cache, need to re-fetch.'\n );\n requestUpdate = true;\n } else if (Object.keys(manifest.modules || {}).length !== numberOfModules) {\n log(\n 2,\n '[cache] The cache and the requested modules do not match, need to re-fetch.'\n );\n requestUpdate = true;\n } else {\n // Check each module, if anything is missing refetch everything\n requestUpdate = (moduleScripts || []).some((moduleName) => {\n if (!manifest.modules[moduleName]) {\n log(\n 2,\n `[cache] The ${moduleName} is missing in the cache, need to re-fetch.`\n );\n return true;\n }\n });\n }\n\n if (requestUpdate) {\n fetchedModules = await updateCache(highcharts, server.proxy, sourcePath);\n } else {\n log(3, '[cache] Dependency cache is up to date, proceeding.');\n\n // Load the sources\n cache.sources = readFileSync(sourcePath, 'utf8');\n\n // Get current modules map\n fetchedModules = manifest.modules;\n\n cache.hcVersion = extractVersion(cache);\n }\n }\n\n // Finally, save the new manifest, which is basically our current config\n // in a slightly different format\n await saveConfigToManifest(highcharts, fetchedModules);\n};\n\nexport const getCachePath = () =>\n join(__dirname, getOptions().highcharts.cachePath);\n\nexport const getCache = () => cache;\n\nexport const highcharts = () => cache.sources;\n\nexport const version = () => cache.hcVersion;\n\nexport default {\n checkAndUpdateCache,\n getCachePath,\n updateVersion,\n getCache,\n highcharts,\n version\n};\n","/*******************************************************************************\n\nHighcharts Export Server\n\nCopyright (c) 2016-2024, Highsoft\n\nLicenced under the MIT licence.\n\nAdditionally a valid Highcharts license is required for use.\n\nSee LICENSE file in root for details.\n\n*******************************************************************************/\n\n/* eslint-disable no-undef */\n\n/**\n * Setting the animObject. Called when initing the page.\n */\nexport function setupHighcharts() {\n Highcharts.animObject = function () {\n return { duration: 0 };\n };\n}\n\n/**\n * Creates the actual chart.\n *\n * @param {object} chartOptions - The options for the Highcharts chart.\n * @param {object} options - The export options.\n * @param {boolean} displayErrors - A flag indicating whether to display errors.\n */\nexport async function triggerExport(chartOptions, options, displayErrors) {\n // Display errors flag taken from chart options nad debugger module\n window._displayErrors = displayErrors;\n\n // Get required functions\n const { getOptions, merge, setOptions, wrap } = Highcharts;\n\n // Create a separate object for a potential setOptions usages in order to\n // prevent from polluting other exports that can happen on the same page\n Highcharts.setOptionsObj = merge(false, {}, getOptions());\n\n // By default animation is disabled\n const chart = {\n animation: false\n };\n\n // When straight inject, the size is set through CSS only\n if (options.export.strInj) {\n chart.height = chartOptions.chart.height;\n chart.width = chartOptions.chart.width;\n }\n\n // NOTE: Is this used for anything useful?\n window.isRenderComplete = false;\n wrap(Highcharts.Chart.prototype, 'init', function (proceed, userOptions, cb) {\n // Override userOptions with image friendly options\n userOptions = merge(userOptions, {\n exporting: {\n enabled: false\n },\n plotOptions: {\n series: {\n label: {\n enabled: false\n }\n }\n },\n /* Expects tooltip in userOptions when forExport is true.\n https://github.com/highcharts/highcharts/blob/3ad430a353b8056b9e764aa4e5cd6828aa479db2/js/parts/Chart.js#L241\n */\n tooltip: {}\n });\n\n (userOptions.series || []).forEach(function (series) {\n series.animation = false;\n });\n\n // Add flag to know if chart render has been called.\n if (!window.onHighchartsRender) {\n window.onHighchartsRender = Highcharts.addEvent(this, 'render', () => {\n window.isRenderComplete = true;\n });\n }\n\n proceed.apply(this, [userOptions, cb]);\n });\n\n wrap(Highcharts.Series.prototype, 'init', function (proceed, chart, options) {\n proceed.apply(this, [chart, options]);\n });\n\n // Get the user options\n const userOptions = options.export.strInj\n ? new Function(`return ${options.export.strInj}`)()\n : chartOptions;\n\n // Trigger custom code\n if (options.customLogic.customCode) {\n new Function('options', options.customLogic.customCode)(userOptions);\n }\n\n // Merge the globalOptions, themeOptions, options from the wrapped\n // setOptions function and user options to create the final options object\n const finalOptions = merge(\n false,\n JSON.parse(options.export.themeOptions),\n userOptions,\n // Placed it here instead in the init because of the size issues\n { chart }\n );\n\n const finalCallback = options.customLogic.callback\n ? new Function(`return ${options.customLogic.callback}`)()\n : undefined;\n\n // Set the global options if exist\n const globalOptions = JSON.parse(options.export.globalOptions);\n if (globalOptions) {\n setOptions(globalOptions);\n }\n\n let constr = options.export.constr || 'chart';\n constr = typeof Highcharts[constr] !== 'undefined' ? constr : 'chart';\n\n Highcharts[constr]('container', finalOptions, finalCallback);\n\n // Get the current global options\n const defaultOptions = getOptions();\n\n // Clear it just in case (e.g. the setOptions was used in the customCode)\n for (const prop in defaultOptions) {\n if (typeof defaultOptions[prop] !== 'function') {\n delete defaultOptions[prop];\n }\n }\n\n // Set the default options back\n setOptions(Highcharts.setOptionsObj);\n\n // Empty the custom global options object\n Highcharts.setOptionsObj = {};\n}\n","/*******************************************************************************\n\nHighcharts Export Server\n\nCopyright (c) 2016-2024, Highsoft\n\nLicenced under the MIT licence.\n\nAdditionally a valid Highcharts license is required for use.\n\nSee LICENSE file in root for details.\n\n*******************************************************************************/\n\nimport { readFileSync } from 'fs';\nimport path from 'path';\n\nimport puppeteer from 'puppeteer';\n\nimport { getCachePath } from './cache.js';\nimport { getOptions } from './config.js';\nimport { setupHighcharts } from './highcharts.js';\nimport { log, logWithStack } from './logger.js';\nimport { __dirname } from './utils.js';\n\nimport ExportError from './errors/ExportError.js';\n\n// Get the template for the page\nconst template = readFileSync(__dirname + '/templates/template.html', 'utf8');\n\nlet browser;\n\n/**\n * Retrieves the existing Puppeteer browser instance.\n *\n * @returns {Promise} A Promise resolving to the Puppeteer browser\n * instance.\n *\n * @throws {ExportError} Throws an ExportError if no valid browser has been\n * created.\n */\nexport function get() {\n if (!browser) {\n throw new ExportError('[browser] No valid browser has been created.');\n }\n return browser;\n}\n\n/**\n * Creates a Puppeteer browser instance with the specified arguments.\n *\n * @param {Array} puppeteerArgs - Additional arguments for Puppeteer launch.\n *\n * @returns {Promise} A Promise resolving to the Puppeteer browser\n * instance.\n *\n * @throws {ExportError} Throws an ExportError if max retries to open a browser\n * instance are reached, or if no browser instance is found after retries.\n */\nexport async function create(puppeteerArgs) {\n // Get debug and other options\n const { puppeteer: puppeteerOptions, debug, other } = getOptions();\n\n // Get the debug options\n const { enable: enabledDebug, ...debugOptions } = debug;\n\n const launchOptions = {\n headless: other.browserShellMode ? 'shell' : true,\n userDataDir: puppeteerOptions.tempDir || './tmp/',\n args: puppeteerArgs,\n handleSIGINT: false,\n handleSIGTERM: false,\n handleSIGHUP: false,\n waitForInitialPage: false,\n defaultViewport: null,\n ...(enabledDebug && debugOptions)\n };\n\n // Create a browser\n if (!browser) {\n const maxTries = 25;\n let tryCount = 0;\n\n const open = async () => {\n try {\n log(\n 3,\n `[browser] Attempting to get a browser instance (try ${++tryCount}).`\n );\n browser = await puppeteer.launch(launchOptions);\n } catch (error) {\n // This isn't a full error yet as puppeteer sometimes takes time to\n // initialize properly.\n logWithStack(\n 2,\n error,\n `[browser] Failed to launch a browser instance - retrying (attempt ${tryCount}/${maxTries}).`\n );\n\n // Retry to launch browser until reaching max attempts\n if (tryCount < 25) {\n log(\n 3,\n `[browser] Retry to open a browser (attempt ${tryCount}/${maxTries}).`\n );\n await new Promise((response) => setTimeout(response, 4000));\n await open();\n } else {\n //... now it's an error, which is caught by the caller\n throw error;\n }\n }\n };\n\n try {\n await open();\n\n // Shell mode inform\n if (launchOptions.headless === 'shell') {\n log(3, `[browser] Launched browser in shell mode.`);\n }\n\n // Debug mode inform\n if (enabledDebug) {\n log(3, `[browser] Launched browser in debug mode.`);\n }\n } catch (error) {\n throw new ExportError(\n '[browser] Maximum retries to open a browser instance reached.'\n ).setError(error);\n }\n\n if (!browser) {\n throw new ExportError('[browser] Cannot find a browser to open.');\n }\n }\n\n // Return a browser promise\n return browser;\n}\n\n/**\n * Closes the Puppeteer browser instance if it is connected.\n *\n * @returns {Promise} A Promise resolving to true after the browser\n * is closed.\n */\nexport async function close() {\n // Close the browser when connnected\n if (browser?.connected) {\n await browser.close();\n }\n log(4, '[browser] Closed the browser.');\n}\n\n/**\n * Creates a new Puppeteer Page within an existing browser instance.\n *\n * If the browser instance is not available, returns false.\n *\n * The function creates a new page, disables caching, sets content using\n * setPageContent(), and returns the created Puppeteer Page.\n *\n * @returns {(boolean|object)} Returns false if the browser instance is not\n * available, or a Puppeteer Page object representing the newly created page.\n */\nexport async function newPage() {\n if (!browser) {\n return false;\n }\n\n // Create a page\n const page = await browser.newPage();\n\n // Disable cache\n await page.setCacheEnabled(false);\n\n // Set the content\n await setPageContent(page);\n\n // Set page events\n setPageEvents(page);\n\n return page;\n}\n\n/**\n * Clears the content of a Puppeteer Page based on the specified mode.\n *\n * @param {Object} page - The Puppeteer Page object to be cleared.\n * @param {boolean} hardReset - A flag indicating the type of clearing\n * to be performed. If true, navigates to 'about:blank' and resets content\n * and scripts. If false, clears the body content by setting a predefined HTML\n * structure.\n *\n * @throws {Error} Logs thrown error if clearing the page content fails.\n */\nexport async function clearPage(page, hardReset = false) {\n try {\n if (page && !page.isClosed()) {\n if (hardReset) {\n // Navigate to about:blank\n await page.goto('about:blank', { waitUntil: 'domcontentloaded' });\n\n // Set the content and and scripts again\n await setPageContent(page);\n } else {\n // Clear body content\n await page.evaluate(() => {\n document.body.innerHTML =\n '
';\n });\n }\n return true;\n }\n } catch (error) {\n logWithStack(\n 2,\n error,\n '[browser] Could not clear the content of the page.'\n );\n }\n\n return false;\n}\n\n/**\n * Adds custom JS and CSS resources to a Puppeteer Page based on the specified\n * options.\n *\n * @param {Object} page - The Puppeteer Page object to which resources will be\n * added.\n * @param {Object} options - All options and configuration.\n *\n * @returns {Promise>} - Promise resolving to an array of injected\n * resources.\n */\nexport async function addPageResources(page, options) {\n // Injected resources array\n const injectedResources = [];\n\n // Use resources\n const resources = options.customLogic.resources;\n if (resources) {\n const injectedJs = [];\n\n // Load custom JS code\n if (resources.js) {\n injectedJs.push({\n content: resources.js\n });\n }\n\n // Load scripts from all custom files\n if (resources.files) {\n for (const file of resources.files) {\n const isLocal = !file.startsWith('http') ? true : false;\n\n // Add each custom script from resources' files\n injectedJs.push(\n isLocal\n ? {\n content: readFileSync(file, 'utf8')\n }\n : {\n url: file\n }\n );\n }\n }\n\n for (const jsResource of injectedJs) {\n try {\n injectedResources.push(await page.addScriptTag(jsResource));\n } catch (error) {\n logWithStack(2, error, `[export] The JS resource cannot be loaded.`);\n }\n }\n injectedJs.length = 0;\n\n // Load CSS\n const injectedCss = [];\n if (resources.css) {\n let cssImports = resources.css.match(/@import\\s*([^;]*);/g);\n if (cssImports) {\n // Handle css section\n for (let cssImportPath of cssImports) {\n if (cssImportPath) {\n cssImportPath = cssImportPath\n .replace('url(', '')\n .replace('@import', '')\n .replace(/\"/g, '')\n .replace(/'/g, '')\n .replace(/;/, '')\n .replace(/\\)/g, '')\n .trim();\n\n // Add each custom css from resources\n if (cssImportPath.startsWith('http')) {\n injectedCss.push({\n url: cssImportPath\n });\n } else if (options.customLogic.allowFileResources) {\n injectedCss.push({\n path: path.join(__dirname, cssImportPath)\n });\n }\n }\n }\n }\n\n // The rest of the CSS section will be content by now\n injectedCss.push({\n content: resources.css.replace(/@import\\s*([^;]*);/g, '') || ' '\n });\n\n for (const cssResource of injectedCss) {\n try {\n injectedResources.push(await page.addStyleTag(cssResource));\n } catch (error) {\n logWithStack(2, error, `[export] The CSS resource cannot be loaded.`);\n }\n }\n injectedCss.length = 0;\n }\n }\n return injectedResources;\n}\n\n/**\n * Clears out all state set on the page with addScriptTag/addStyleTag. Removes\n * injected resources and resets CSS and script tags on the page. Additionally,\n * it destroys previously existing charts.\n *\n * @param {Object} page - The Puppeteer Page object from which resources will\n * be cleared.\n * @param {Array} injectedResources - Array of injected resources\n * to be cleared.\n */\nexport async function clearPageResources(page, injectedResources) {\n try {\n for (const resource of injectedResources) {\n await resource.dispose();\n }\n\n // Destroy old charts after export is done and reset all CSS and script tags\n await page.evaluate(() => {\n // We are not guaranteed that Highcharts is loaded, e,g, when doing SVG\n // exports\n if (typeof Highcharts !== 'undefined') {\n // eslint-disable-next-line no-undef\n const oldCharts = Highcharts.charts;\n\n // Check in any already existing charts\n if (Array.isArray(oldCharts) && oldCharts.length) {\n // Destroy old charts\n for (const oldChart of oldCharts) {\n oldChart && oldChart.destroy();\n // eslint-disable-next-line no-undef\n Highcharts.charts.shift();\n }\n }\n }\n\n // eslint-disable-next-line no-undef\n const [...scriptsToRemove] = document.getElementsByTagName('script');\n // eslint-disable-next-line no-undef\n const [, ...stylesToRemove] = document.getElementsByTagName('style');\n // eslint-disable-next-line no-undef\n const [...linksToRemove] = document.getElementsByTagName('link');\n\n // Remove tags\n for (const element of [\n ...scriptsToRemove,\n ...stylesToRemove,\n ...linksToRemove\n ]) {\n element.remove();\n }\n });\n } catch (error) {\n logWithStack(2, error, `[browser] Could not clear page's resources.`);\n }\n}\n\n/**\n * Sets the content for a Puppeteer Page using a predefined template\n * and additional scripts. Also, sets the pageerror in order to catch\n * and display errors from the window context.\n *\n * @param {Object} page - The Puppeteer Page object for which the content\n * is being set.\n */\nasync function setPageContent(page) {\n await page.setContent(template, { waitUntil: 'domcontentloaded' });\n\n // Add all registered Higcharts scripts, quite demanding\n await page.addScriptTag({ path: `${getCachePath()}/sources.js` });\n\n // Set the initial animObject\n await page.evaluate(setupHighcharts);\n}\n\n/**\n * Set events for a Puppeteer Page.\n *\n * @param {Object} page - The Puppeteer Page object to set events to.\n */\nfunction setPageEvents(page) {\n // Get debug options\n const { debug } = getOptions();\n\n // Set the console listener, if needed\n if (debug.enable && debug.listenToConsole) {\n page.on('console', (message) => {\n console.log(`[debug] ${message.text()}`);\n });\n }\n\n // Set the pageerror listener\n page.on('pageerror', async (error) => {\n // It would seem like this may fire at the same time or shortly before\n // a page is closed.\n if (page.isClosed()) {\n return;\n }\n\n // TODO: Consider adding a switch here that turns on log(0) logging\n // on page errors.\n await page.$eval(\n '#container',\n (element, errorMessage) => {\n // eslint-disable-next-line no-undef\n if (window._displayErrors) {\n element.innerHTML = errorMessage;\n }\n },\n `

Chart input data error:

${error.toString()}`\n );\n });\n}\n\nexport default {\n get,\n create,\n close,\n newPage,\n clearPage,\n addPageResources,\n clearPageResources\n};\n","/*******************************************************************************\n\nHighcharts Export Server\n\nCopyright (c) 2016-2024, Highsoft\n\nLicenced under the MIT licence.\n\nAdditionally a valid Highcharts license is required for use.\n\nSee LICENSE file in root for details.\n\n*******************************************************************************/\n\nimport { addPageResources, clearPageResources } from './browser.js';\nimport { getCache } from './cache.js';\nimport { triggerExport } from './highcharts.js';\nimport { log } from './logger.js';\n\nimport svgTemplate from './../templates/svg_export/svg_export.js';\n\nimport ExportError from './errors/ExportError.js';\n\n/**\n * Retrieves the clipping region coordinates of the specified page element with\n * the id 'chart-container'.\n *\n * @param {Object} page - Puppeteer page object.\n *\n * @returns {Promise} Promise resolving to an object containing\n * x, y, width, and height properties.\n */\nconst getClipRegion = (page) =>\n page.$eval('#chart-container', (element) => {\n const { x, y, width, height } = element.getBoundingClientRect();\n return {\n x,\n y,\n width,\n height: Math.trunc(height > 1 ? height : 500)\n };\n });\n\n/**\n * Creates an image using Puppeteer's page screenshot functionality with\n * specified options.\n *\n * @param {Object} page - Puppeteer page object.\n * @param {string} type - Image type.\n * @param {string} encoding - Image encoding.\n * @param {Object} clip - Clipping region coordinates.\n * @param {number} rasterizationTimeout - Timeout for rasterization\n * in milliseconds.\n *\n * @returns {Promise} Promise resolving to the image buffer or rejecting\n * with an ExportError for timeout.\n */\nconst createImage = (page, type, encoding, clip, rasterizationTimeout) =>\n Promise.race([\n page.screenshot({\n type,\n encoding,\n clip,\n captureBeyondViewport: true,\n fullPage: false,\n optimizeForSpeed: true,\n ...(type !== 'png' ? { quality: 80 } : {}),\n\n // #447, #463 - always render on a transparent page if the expected type\n // format is PNG\n omitBackground: type == 'png'\n }),\n new Promise((_resolve, reject) =>\n setTimeout(\n () => reject(new ExportError('Rasterization timeout')),\n rasterizationTimeout || 1500\n )\n )\n ]);\n\n/**\n * Creates a PDF using Puppeteer's page pdf functionality with specified\n * options.\n *\n * @param {Object} page - Puppeteer page object.\n * @param {number} height - PDF height.\n * @param {number} width - PDF width.\n * @param {string} encoding - PDF encoding.\n *\n * @returns {Promise} Promise resolving to the PDF buffer.\n */\nconst createPDF = async (\n page,\n height,\n width,\n encoding,\n rasterizationTimeout\n) => {\n await page.emulateMediaType('screen');\n\n return page.pdf({\n // This will remove an extra empty page in PDF exports\n height: height + 1,\n width,\n encoding,\n timeout: rasterizationTimeout || 1500\n });\n};\n\n/**\n * Creates an SVG string by evaluating the outerHTML of the first 'svg' element\n * inside an element with the id 'container'.\n *\n * @param {Object} page - Puppeteer page object.\n *\n * @returns {Promise} Promise resolving to the SVG string.\n */\nconst createSVG = (page) =>\n page.$eval('#container svg:first-of-type', (element) => element.outerHTML);\n\n/**\n * Sets the specified chart and options as configuration into the triggerExport\n * function within the window context using page.evaluate.\n *\n * @param {Object} page - Puppeteer page object.\n * @param {any} chart - The chart object to be configured.\n * @param {Object} options - Configuration options for the chart.\n *\n * @returns {Promise} Promise resolving after the configuration is set.\n */\nconst setAsConfig = async (page, chart, options, displayErrors) => {\n // Get rid of the redunant string data\n options.export.instr = null;\n options.export.infile = null;\n\n // Get the size of the export input\n const totalSize = Buffer.byteLength(\n options.export?.strInj ? options.export?.strInj : JSON.stringify(chart),\n 'utf-8'\n );\n\n // Log the size in MB\n log(\n 4,\n `[export] The current total size of data passed to a page is around ${(\n totalSize /\n (1024 * 1024)\n ).toFixed(2)} MB`\n );\n\n // Check the size of data passed to the page\n if (totalSize >= 100 * 1024 * 1024) {\n throw new ExportError(`[export] The data passed to a page exceeded 100MB.`);\n }\n\n // Trigger the Highcharts chart creation\n return page.evaluate(triggerExport, chart, options, displayErrors);\n};\n\n/**\n * Exports to a chart from a page using Puppeteer.\n *\n * @param {Object} page - Puppeteer page object.\n * @param {any} chart - The chart object or SVG configuration to be exported.\n * @param {Object} options - Export options and configuration.\n *\n * @returns {Promise} Promise resolving to\n * the exported data or rejecting with an ExportError.\n */\nexport default async (page, chart, options) => {\n // Injected resources array (additional JS and CSS)\n let injectedResources = [];\n\n try {\n log(4, '[export] Determining export path.');\n\n const exportOptions = options.export;\n\n // Decide whether display error or debbuger wrapper around it\n const displayErrors =\n exportOptions?.options?.chart?.displayErrors &&\n getCache().activeManifest.modules.debugger;\n\n let isSVG;\n if (\n chart.indexOf &&\n (chart.indexOf('= 0 || chart.indexOf('= 0)\n ) {\n // SVG input handling\n log(4, '[export] Treating as SVG.');\n\n // If input is also SVG, just return it\n if (exportOptions.type === 'svg') {\n return chart;\n }\n\n isSVG = true;\n await page.setContent(svgTemplate(chart), {\n waitUntil: 'domcontentloaded'\n });\n } else {\n // JSON config handling\n log(4, '[export] Treating as config.');\n\n // Need to perform straight inject\n if (exportOptions.strInj) {\n // Injection based configuration export\n await setAsConfig(\n page,\n {\n chart: {\n height: exportOptions.height,\n width: exportOptions.width\n }\n },\n options,\n displayErrors\n );\n } else {\n // Basic configuration export\n chart.chart.height = exportOptions.height;\n chart.chart.width = exportOptions.width;\n\n await setAsConfig(page, chart, options, displayErrors);\n }\n }\n\n // Keeps track of all resources added on the page with addXXXTag. etc\n // It's VITAL that all added resources ends up here so we can clear things\n // out when doing a new export in the same page!\n injectedResources = await addPageResources(page, options);\n\n // Get the real chart size and set the zoom accordingly\n const size = isSVG\n ? await page.evaluate((scale) => {\n const svgElement = document.querySelector(\n '#chart-container svg:first-of-type'\n );\n\n // Get the values correctly scaled\n const chartHeight = svgElement.height.baseVal.value * scale;\n const chartWidth = svgElement.width.baseVal.value * scale;\n\n // In case of SVG the zoom must be set directly for body\n // Set the zoom as scale\n // eslint-disable-next-line no-undef\n document.body.style.zoom = scale;\n\n // Set the margin to 0px\n // eslint-disable-next-line no-undef\n document.body.style.margin = '0px';\n\n return {\n chartHeight,\n chartWidth\n };\n }, parseFloat(exportOptions.scale))\n : await page.evaluate(() => {\n // eslint-disable-next-line no-undef\n const { chartHeight, chartWidth } = window.Highcharts.charts[0];\n\n // No need for such scale manipulation in case of other types of exports\n // Reset the zoom for other exports than to SVGs\n // eslint-disable-next-line no-undef\n document.body.style.zoom = 1;\n\n return {\n chartHeight,\n chartWidth\n };\n });\n\n // Set final height and width for viewport\n const viewportHeight = Math.abs(\n Math.ceil(size.chartHeight || exportOptions.height)\n );\n const viewportWidth = Math.abs(\n Math.ceil(size.chartWidth || exportOptions.width)\n );\n\n // Get the clip region for the page\n const { x, y } = await getClipRegion(page);\n\n // Set the final viewport now that we have the real height\n await page.setViewport({\n height: viewportHeight,\n width: viewportWidth,\n deviceScaleFactor: isSVG ? 1 : parseFloat(exportOptions.scale)\n });\n\n let data;\n // Rasterization process\n if (exportOptions.type === 'svg') {\n // SVG\n data = await createSVG(page);\n } else if (['png', 'jpeg'].includes(exportOptions.type)) {\n // PNG or JPEG\n data = await createImage(\n page,\n exportOptions.type,\n 'base64',\n {\n width: viewportWidth,\n height: viewportHeight,\n x,\n y\n },\n exportOptions.rasterizationTimeout\n );\n } else if (exportOptions.type === 'pdf') {\n // PDF\n data = await createPDF(\n page,\n viewportHeight,\n viewportWidth,\n 'base64',\n exportOptions.rasterizationTimeout\n );\n } else {\n throw new ExportError(\n `[export] Unsupported output format ${exportOptions.type}.`\n );\n }\n\n // Clear previously injected JS and CSS resources\n await clearPageResources(page, injectedResources);\n return data;\n } catch (error) {\n await clearPageResources(page, injectedResources);\n return error;\n }\n};\n","/*******************************************************************************\n\nHighcharts Export Server\n\nCopyright (c) 2016-2024, Highsoft\n\nLicenced under the MIT licence.\n\nAdditionally a valid Highcharts license is required for use.\n\nSee LICENSE file in root for details.\n\n*******************************************************************************/\n\nimport cssTemplate from './css.js';\n\nexport default (chart) => `\n\n\n \n \n Highcharts Export\n \n \n \n
\n ${chart}\n
\n \n\n\n`;\n","/*******************************************************************************\n\nHighcharts Export Server\n\nCopyright (c) 2016-2024, Highsoft\n\nLicenced under the MIT licence.\n\nAdditionally a valid Highcharts license is required for use.\n\nSee LICENSE file in root for details.\n\n*******************************************************************************/\n\nimport { Pool } from 'tarn';\nimport { v4 as uuid } from 'uuid';\n\nimport {\n create as createBrowser,\n close as closeBrowser,\n newPage,\n clearPage\n} from './browser.js';\nimport puppeteerExport from './export.js';\nimport { log, logWithStack } from './logger.js';\nimport { measureTime } from './utils.js';\n\nimport ExportError from './errors/ExportError.js';\n\n// The pool instance\nlet pool = false;\n\n// Pool statistics\nexport const stats = {\n performedExports: 0,\n exportAttempts: 0,\n exportFromSvgAttempts: 0,\n timeSpent: 0,\n droppedExports: 0,\n spentAverage: 0\n};\n\nlet poolConfig = {};\n\nconst factory = {\n /**\n * Creates a new worker page for the export pool.\n *\n * @returns {Object} - An object containing the worker ID, a reference to the\n * browser page, and initial work count.\n *\n * @throws {ExportError} - If there's an error during the creation of the new\n * page.\n */\n create: async () => {\n let page = false;\n\n const id = uuid();\n const startDate = new Date().getTime();\n\n try {\n page = await newPage();\n\n if (!page || page.isClosed()) {\n throw new ExportError('The page is invalid or closed.');\n }\n\n log(\n 3,\n `[pool] Successfully created a worker ${id} - took ${\n new Date().getTime() - startDate\n } ms.`\n );\n } catch (error) {\n throw new ExportError(\n 'Error encountered when creating a new page.'\n ).setError(error);\n }\n\n return {\n id,\n page,\n // Try to distribute the initial work count\n workCount: Math.round(Math.random() * (poolConfig.workLimit / 2))\n };\n },\n\n /**\n * Validates a worker page in the export pool, checking if it has exceeded\n * the work limit.\n *\n * @param {Object} workerHandle - The handle to the worker, containing the\n * worker's ID, a reference to the browser page, and work count.\n *\n * @returns {boolean} - Returns true if the worker is valid and within\n * the work limit; otherwise, returns false.\n */\n validate: async (workerHandle) => {\n // NOTE: In certain cases acquiring throws a TargetCloseError, which may\n // be caused by two things:\n // - The page is closed and attempted to be reused.\n // - Lost contact with the browser\n // What we're seeing in logs is that successive exports typically\n // succeeds, and the server recovers, indicating that it's likely\n // the first case. This is an attempt at allievating the issue by\n // simply not validating the worker if the page is null or closed.\n //\n // The actual result from when this happened, was that a worker would\n // be completely locked, stopping it from being acquired until\n // its work count reached the limit.\n if (!workerHandle.page || workerHandle.page?.isClosed()) {\n return false;\n }\n\n if (\n poolConfig.workLimit &&\n ++workerHandle.workCount > poolConfig.workLimit\n ) {\n log(\n 3,\n `[pool] Worker failed validation: exceeded work limit (limit is ${poolConfig.workLimit}).`\n );\n return false;\n }\n return true;\n },\n\n /**\n * Destroys a worker entry in the export pool, closing its associated page.\n *\n * @param {Object} workerHandle - The handle to the worker, containing\n * the worker's ID and a reference to the browser page.\n */\n destroy: async (workerHandle) => {\n log(3, `[pool] Destroying pool entry ${workerHandle.id}.`);\n\n if (workerHandle.page && !workerHandle.page.isClosed()) {\n await workerHandle.page.close();\n }\n }\n\n // log: (message, level) => log(1, '[tarn] ' + message)\n};\n\n/**\n * Initializes the export pool with the provided configuration, creating\n * a browser instance and setting up worker resources.\n *\n * @param {Object} config - Configuration options for the export pool along\n * with custom puppeteer arguments for the puppeteer.launch function.\n */\nexport const initPool = async (config) => {\n // For the module scope usage\n poolConfig = config && config.pool ? { ...config.pool } : {};\n\n // Create a browser instance with the puppeteer arguments\n await createBrowser(config.puppeteerArgs);\n\n log(\n 3,\n `[pool] Initializing pool with workers: min ${poolConfig.minWorkers}, max ${poolConfig.maxWorkers}.`\n );\n\n if (pool) {\n return log(\n 4,\n '[pool] Already initialized, please kill it before creating a new one.'\n );\n }\n\n if (parseInt(poolConfig.minWorkers) > parseInt(poolConfig.maxWorkers)) {\n poolConfig.minWorkers = poolConfig.maxWorkers;\n }\n\n try {\n // Create a pool along with a minimal number of resources\n pool = new Pool({\n // Get the create/validate/destroy/log functions\n ...factory,\n min: parseInt(poolConfig.minWorkers),\n max: parseInt(poolConfig.maxWorkers),\n acquireTimeoutMillis: poolConfig.acquireTimeout,\n createTimeoutMillis: poolConfig.createTimeout,\n destroyTimeoutMillis: poolConfig.destroyTimeout,\n idleTimeoutMillis: poolConfig.idleTimeout,\n createRetryIntervalMillis: poolConfig.createRetryInterval,\n reapIntervalMillis: poolConfig.reaperInterval,\n propagateCreateError: false\n });\n\n // Set events\n pool.on('release', async (resource) => {\n // Clear page\n const r = await clearPage(resource.page, false);\n log(\n 4,\n `[pool] Releasing a worker with ID ${resource.id}. Clear page status: ${r}.`\n );\n });\n\n pool.on('destroySuccess', (eventId, resource) => {\n log(4, `[pool] Destroyed a worker with ID ${resource.id}.`);\n resource.page = null;\n });\n\n const initialResources = [];\n // Create an initial number of resources\n for (let i = 0; i < poolConfig.minWorkers; i++) {\n try {\n const resource = await pool.acquire().promise;\n initialResources.push(resource);\n } catch (error) {\n logWithStack(2, error, '[pool] Could not create an initial resource.');\n }\n }\n\n // Release the initial number of resources back to the pool\n initialResources.forEach((resource) => {\n pool.release(resource);\n });\n\n log(\n 3,\n `[pool] The pool is ready${initialResources.length ? ` with ${initialResources.length} initial resources waiting.` : '.'}`\n );\n } catch (error) {\n throw new ExportError(\n '[pool] Could not create the pool of workers.'\n ).setError(error);\n }\n};\n\n/**\n * Kills all workers in the pool, destroys the pool, and closes the browser\n * instance.\n *\n * @returns {Promise} A promise that resolves after the workers are\n * killed, the pool is destroyed, and the browser is closed.\n */\nexport async function killPool() {\n log(3, '[pool] Killing pool with all workers and closing browser.');\n\n // If still alive, destroy the pool of pages before closing a browser\n if (pool) {\n // Free up not released workers\n for (const worker of pool.used) {\n pool.release(worker.resource);\n }\n\n // Destroy the pool if it is still available\n if (!pool.destroyed) {\n await pool.destroy();\n log(4, '[browser] Destroyed the pool of resources.');\n }\n }\n\n // Close the browser instance\n await closeBrowser();\n}\n\n/**\n * Processes the export work using a worker from the pool. Acquires a worker\n * handle from the pool, performs the export using puppeteer, and releases\n * the worker handle back to the pool.\n *\n * @param {string} chart - The chart data or configuration to be exported.\n * @param {Object} options - Export options and configuration.\n *\n * @returns {Promise} A promise that resolves with the export resultand\n * options.\n *\n * @throws {ExportError} If an error occurs during the export process.\n */\nexport const postWork = async (chart, options) => {\n let workerHandle;\n\n try {\n log(4, '[pool] Work received, starting to process.');\n\n ++stats.exportAttempts;\n if (poolConfig.benchmarking) {\n getPoolInfo();\n }\n\n if (!pool) {\n throw new ExportError('Work received, but pool has not been started.');\n }\n\n // Acquire the worker along with the id of resource and work count\n const acquireCounter = measureTime();\n try {\n log(4, '[pool] Acquiring a worker handle.');\n workerHandle = await pool.acquire().promise;\n\n // Check the page acquire time\n if (options.server.benchmarking) {\n log(\n 5,\n options.payload?.requestId\n ? `[benchmark] Request with ID ${options.payload?.requestId} -`\n : '[benchmark]',\n `Acquired a worker handle: ${acquireCounter()}ms.`\n );\n }\n } catch (error) {\n throw new ExportError(\n (options.payload?.requestId\n ? `For request with ID ${options.payload?.requestId} - `\n : '') +\n `Error encountered when acquiring an available entry: ${acquireCounter()}ms.`\n ).setError(error);\n }\n log(4, '[pool] Acquired a worker handle.');\n\n if (!workerHandle.page) {\n throw new ExportError(\n 'Resolved worker page is invalid: the pool setup is wonky.'\n );\n }\n\n // Save the start time\n let workStart = new Date().getTime();\n\n log(4, `[pool] Starting work on pool entry with ID ${workerHandle.id}.`);\n\n // Perform an export on a puppeteer level\n const exportCounter = measureTime();\n const result = await puppeteerExport(workerHandle.page, chart, options);\n\n // Check if it's an error\n if (result instanceof Error) {\n // NOTE: If there's a rasterization timeout, we want need to flush the page.\n // This is because the page may be in a state where it's waiting for\n // the screenshot to finish even though the timeout has occured.\n // Which of course causes a lot of issues with the event system,\n // and page consistency.\n //\n // NOTE: Only page.screenshot will throw this, timeouts for PDF's are\n // handled by the page.pdf function itself.\n //\n // ...yes, this is ugly.\n if (result.message === 'Rasterization timeout') {\n workerHandle.workCount = poolConfig.workLimit + 1;\n workerHandle.page = null;\n }\n\n if (\n result.name === 'TimeoutError' ||\n result.message === 'Rasterization timeout'\n ) {\n throw new ExportError(\n 'Rasterization timeout: your chart may be too complex or large, and failed to render within the allotted time.'\n ).setError(result);\n } else {\n throw new ExportError(\n (options.payload?.requestId\n ? `For request with ID ${options.payload?.requestId} - `\n : '') + `Error encountered during export: ${exportCounter()}ms.`\n ).setError(result);\n }\n }\n\n // Check the Puppeteer export time\n if (options.server.benchmarking) {\n log(\n 5,\n options.payload?.requestId\n ? `[benchmark] Request with ID ${options.payload?.requestId} -`\n : '[benchmark]',\n `Exported a chart sucessfully: ${exportCounter()}ms.`\n );\n }\n\n // Release the resource back to the pool\n pool.release(workerHandle);\n\n // Used for statistics in averageTime and processedWorkCount, which\n // in turn is used by the /health route.\n const workEnd = new Date().getTime();\n const exportTime = workEnd - workStart;\n stats.timeSpent += exportTime;\n stats.spentAverage = stats.timeSpent / ++stats.performedExports;\n\n log(4, `[pool] Work completed in ${exportTime} ms.`);\n\n // Otherwise return the result\n return {\n result,\n options\n };\n } catch (error) {\n ++stats.droppedExports;\n\n if (workerHandle) {\n pool.release(workerHandle);\n }\n\n throw new ExportError(`[pool] In pool.postWork: ${error.message}`).setError(\n error\n );\n }\n};\n\n/**\n * Retrieves the current pool instance.\n *\n * @returns {Object|null} The current pool instance if initialized, or null\n * if the pool has not been created.\n */\nexport const getPool = () => pool;\n\n/**\n * Retrieves pool information in JSON format, including minimum and maximum\n * workers, available workers, workers in use, and pending acquire requests.\n *\n * @returns {Object} Pool information in JSON format.\n */\nexport const getPoolInfoJSON = () => ({\n min: pool.min,\n max: pool.max,\n all: pool.numFree() + pool.numUsed(),\n available: pool.numFree(),\n used: pool.numUsed(),\n pending: pool.numPendingAcquires()\n});\n\n/**\n * Logs information about the current state of the pool, including the minimum\n * and maximum workers, available workers, workers in use, and pending acquire\n * requests.\n */\nexport function getPoolInfo() {\n const { min, max, all, available, used, pending } = getPoolInfoJSON();\n\n log(5, `[pool] The minimum number of resources allowed by pool: ${min}.`);\n log(5, `[pool] The maximum number of resources allowed by pool: ${max}.`);\n log(5, `[pool] The number of all created resources: ${all}.`);\n log(5, `[pool] The number of available resources: ${available}.`);\n log(5, `[pool] The number of acquired resources: ${used}.`);\n log(5, `[pool] The number of resources waiting to be acquired: ${pending}.`);\n}\n\nexport default {\n initPool,\n killPool,\n postWork,\n getPool,\n getPoolInfo,\n getPoolInfoJSON,\n getStats: () => stats\n};\n","/*******************************************************************************\n\nHighcharts Export Server\n\nCopyright (c) 2016-2024, Highsoft\n\nLicenced under the MIT licence.\n\nAdditionally a valid Highcharts license is required for use.\n\nSee LICENSE file in root for details.\n\n*******************************************************************************/\n\nimport { readFileSync, writeFileSync } from 'fs';\n\nimport { getOptions, initExportSettings } from './config.js';\nimport { log, logWithStack } from './logger.js';\nimport { killPool, postWork, stats } from './pool.js';\nimport {\n fixType,\n handleResources,\n isCorrectJSON,\n optionsStringify,\n roundNumber,\n toBoolean,\n wrapAround\n} from './utils.js';\nimport { sanitize } from './sanitize.js';\nimport ExportError from './errors/ExportError.js';\n\nlet allowCodeExecution = false;\n\n/**\n * Starts an export process. The `settings` contains final options gathered\n * from all possible sources (config, env, cli, json). The `endCallback` is\n * called when the export is completed, with an error object as the first\n * argument and the second containing the base64 respresentation of a chart.\n *\n * @param {Object} settings - The settings object containing export\n * configuration.\n * @param {function} endCallback - The callback function to be invoked upon\n * finalizing work or upon error occurance of the exporting process.\n *\n * @returns {void} This function does not return a value directly; instead,\n * it communicates results via the endCallback.\n */\nexport const startExport = async (settings, endCallback) => {\n // Starting exporting process message\n log(4, '[chart] Starting the exporting process.');\n\n // Initialize options\n const options = initExportSettings(settings, getOptions());\n\n // Get the export options\n const exportOptions = options.export;\n\n // If SVG is an input (argument can be sent only by the request)\n if (options.payload?.svg && options.payload.svg !== '') {\n try {\n log(4, '[chart] Attempting to export from a SVG input.');\n\n const result = exportAsString(\n sanitize(options.payload.svg), // #209\n options,\n endCallback\n );\n\n ++stats.exportFromSvgAttempts;\n return result;\n } catch (error) {\n return endCallback(\n new ExportError('[chart] Error loading SVG input.').setError(error)\n );\n }\n }\n\n // Export using options from the file\n if (exportOptions.infile && exportOptions.infile.length) {\n // Try to read the file to get the string representation\n try {\n log(4, '[chart] Attempting to export from an input file.');\n options.export.instr = readFileSync(exportOptions.infile, 'utf8');\n return exportAsString(options.export.instr.trim(), options, endCallback);\n } catch (error) {\n return endCallback(\n new ExportError('[chart] Error loading input file.').setError(error)\n );\n }\n }\n\n // Export with options from the raw representation\n if (\n (exportOptions.instr && exportOptions.instr !== '') ||\n (exportOptions.options && exportOptions.options !== '')\n ) {\n try {\n log(4, '[chart] Attempting to export from a raw input.');\n\n // Use whichever one is available\n exportOptions.instr = exportOptions.instr || exportOptions.options;\n\n // Perform a direct inject when forced\n if (toBoolean(options.customLogic?.allowCodeExecution)) {\n return doStraightInject(options, endCallback);\n }\n\n // Either try to parse to JSON first or do the direct export\n return typeof exportOptions.instr === 'string'\n ? exportAsString(exportOptions.instr.trim(), options, endCallback)\n : doExport(\n options,\n exportOptions.instr || exportOptions.options,\n endCallback\n );\n } catch (error) {\n return endCallback(\n new ExportError('[chart] Error loading raw input.').setError(error)\n );\n }\n }\n\n // No input specified, pass an error message to the callback\n return endCallback(\n new ExportError(\n `[chart] No valid input specified. Check if at least one of the following parameters is correctly set: 'infile', 'instr', 'options', or 'svg'.`\n )\n );\n};\n\n/**\n * Starts a batch export process for multiple charts based on the information\n * in the batch option. The batch is a string in the following format:\n * \"infile1.json=outfile1.png;infile2.json=outfile2.png;...\"\n *\n * @param {Object} options - The options object containing configuration for\n * a batch export.\n *\n * @returns {Promise} A Promise that resolves once the batch export\n * process is completed.\n *\n * @throws {ExportError} Throws an ExportError if an error occurs during\n * any of the batch export process.\n */\nexport const batchExport = async (options) => {\n const batchFunctions = [];\n\n // Split and pair the --batch arguments\n for (let pair of options.export.batch.split(';')) {\n pair = pair.split('=');\n if (pair.length === 2) {\n batchFunctions.push(\n startExport(\n {\n ...options,\n export: {\n ...options.export,\n infile: pair[0],\n outfile: pair[1]\n }\n },\n (error, info) => {\n // Throw an error\n if (error) {\n throw error;\n }\n\n // Save the base64 from a buffer to a correct image file\n writeFileSync(\n info.options.export.outfile,\n info.options.export.type !== 'svg'\n ? Buffer.from(info.result, 'base64')\n : info.result\n );\n }\n )\n );\n }\n }\n\n try {\n // Await all exports are done\n await Promise.all(batchFunctions);\n\n // Kill pool and close browser after finishing batch export\n await killPool();\n } catch (error) {\n throw new ExportError(\n '[chart] Error encountered during batch export.'\n ).setError(error);\n }\n};\n\n/**\n * Starts a single export process based on the specified options.\n *\n * @param {Object} options - The options object containing configuration for\n * a single export.\n *\n * @returns {Promise} A Promise that resolves once the single export\n * process is completed.\n *\n * @throws {ExportError} Throws an ExportError if an error occurs during\n * the single export process.\n */\nexport const singleExport = async (options) => {\n // Use instr or its alias, options\n options.export.instr = options.export.instr || options.export.options;\n\n // Perform an export\n await startExport(options, async (error, info) => {\n // Exit process when error\n if (error) {\n throw error;\n }\n\n const { outfile, type } = info.options.export;\n\n // Save the base64 from a buffer to a correct image file\n writeFileSync(\n outfile || `chart.${type}`,\n type !== 'svg' ? Buffer.from(info.result, 'base64') : info.result\n );\n\n // Kill pool and close browser after finishing single export\n await killPool();\n });\n};\n\n/**\n * Determines the size and scale for chart export based on the provided options.\n *\n * @param {Object} options - The options object containing configuration for\n * chart export.\n *\n * @returns {Object} An object containing the calculated height, width,\n * and scale for the chart export.\n */\nexport const findChartSize = (options) => {\n const { chart, exporting } =\n options.export?.options || isCorrectJSON(options.export?.instr);\n\n // See if globalOptions holds chart or exporting size\n const globalOptions = isCorrectJSON(options.export?.globalOptions);\n\n // Secure scale value\n let scale =\n options.export?.scale ||\n exporting?.scale ||\n globalOptions?.exporting?.scale ||\n options.export?.defaultScale ||\n 1;\n\n // the scale cannot be lower than 0.1 and cannot be higher than 5.0\n scale = Math.max(0.1, Math.min(scale, 5.0));\n\n // we want to round the numbers like 0.23234 -> 0.23\n scale = roundNumber(scale, 2);\n\n // Find chart size and scale\n const size = {\n height:\n options.export?.height ||\n exporting?.sourceHeight ||\n chart?.height ||\n globalOptions?.exporting?.sourceHeight ||\n globalOptions?.chart?.height ||\n options.export?.defaultHeight ||\n 400,\n width:\n options.export?.width ||\n exporting?.sourceWidth ||\n chart?.width ||\n globalOptions?.exporting?.sourceWidth ||\n globalOptions?.chart?.width ||\n options.export?.defaultWidth ||\n 600,\n scale\n };\n\n // Get rid of potential px and %\n for (let [param, value] of Object.entries(size)) {\n size[param] =\n typeof value === 'string' ? +value.replace(/px|%/gi, '') : value;\n }\n return size;\n};\n\n/**\n * Function for finalizing options before export.\n *\n * @param {Object} options - The options object containing configuration for\n * the export process.\n * @param {Object} chartJson - The JSON representation of the chart.\n * @param {Function} endCallback - The callback function to be called upon\n * completion or error.\n * @param {string} svg - The SVG representation of the chart.\n *\n * @returns {Promise} A Promise that resolves once the export process\n * is completed.\n */\nconst doExport = async (options, chartJson, endCallback, svg) => {\n let { export: exportOptions, customLogic: customLogicOptions } = options;\n\n const allowCodeExecutionScoped =\n typeof customLogicOptions.allowCodeExecution === 'boolean'\n ? customLogicOptions.allowCodeExecution\n : allowCodeExecution;\n\n if (!customLogicOptions) {\n customLogicOptions = options.customLogic = {};\n } else if (allowCodeExecutionScoped) {\n if (typeof options.customLogic.resources === 'string') {\n // Process resources\n options.customLogic.resources = handleResources(\n options.customLogic.resources,\n toBoolean(options.customLogic.allowFileResources)\n );\n } else if (!options.customLogic.resources) {\n try {\n const resources = readFileSync('resources.json', 'utf8');\n options.customLogic.resources = handleResources(\n resources,\n toBoolean(options.customLogic.allowFileResources)\n );\n } catch (error) {\n log(2, `[chart] Unable to load the default resources.json file.`);\n }\n }\n }\n\n // If the allowCodeExecution flag isn't set, we should refuse the usage\n // of callback, resources, and custom code. Additionally, the worker will\n // refuse to run arbitrary JavaScript. Prioritized should be the scoped\n // option, then we should take a look at the overall pool option.\n if (!allowCodeExecutionScoped && customLogicOptions) {\n if (\n customLogicOptions.callback ||\n customLogicOptions.resources ||\n customLogicOptions.customCode\n ) {\n // Send back a friendly message saying that the exporter does not support\n // these settings.\n return endCallback(\n new ExportError(\n `[chart] The 'callback', 'resources' and 'customCode' options have been disabled for this server.`\n )\n );\n }\n\n // Reset all additional custom code\n customLogicOptions.callback = false;\n customLogicOptions.resources = false;\n customLogicOptions.customCode = false;\n }\n\n // Clean properties to keep it lean and mean\n if (chartJson) {\n chartJson.chart = chartJson.chart || {};\n chartJson.exporting = chartJson.exporting || {};\n chartJson.exporting.enabled = false;\n }\n\n exportOptions.constr = exportOptions.constr || 'chart';\n exportOptions.type = fixType(exportOptions.type, exportOptions.outfile);\n if (exportOptions.type === 'svg') {\n exportOptions.width = false;\n }\n\n // Prepare global and theme options\n ['globalOptions', 'themeOptions'].forEach((optionsName) => {\n try {\n if (exportOptions && exportOptions[optionsName]) {\n if (\n typeof exportOptions[optionsName] === 'string' &&\n exportOptions[optionsName].endsWith('.json')\n ) {\n exportOptions[optionsName] = isCorrectJSON(\n readFileSync(exportOptions[optionsName], 'utf8'),\n true\n );\n } else {\n exportOptions[optionsName] = isCorrectJSON(\n exportOptions[optionsName],\n true\n );\n }\n }\n } catch (error) {\n exportOptions[optionsName] = {};\n logWithStack(2, error, `[chart] The '${optionsName}' cannot be loaded.`);\n }\n });\n\n // Prepare the customCode\n if (customLogicOptions.allowCodeExecution) {\n try {\n customLogicOptions.customCode = wrapAround(\n customLogicOptions.customCode,\n customLogicOptions.allowFileResources\n );\n } catch (error) {\n logWithStack(2, error, `[chart] The 'customCode' cannot be loaded.`);\n }\n }\n\n // Get the callback\n if (\n customLogicOptions &&\n customLogicOptions.callback &&\n customLogicOptions.callback?.indexOf('{') < 0\n ) {\n // The allowFileResources is always set to false for HTTP requests to avoid\n // injecting arbitrary files from the fs\n if (customLogicOptions.allowFileResources) {\n try {\n customLogicOptions.callback = readFileSync(\n customLogicOptions.callback,\n 'utf8'\n );\n } catch (error) {\n customLogicOptions.callback = false;\n logWithStack(2, error, `[chart] The 'callback' cannot be loaded.`);\n }\n } else {\n customLogicOptions.callback = false;\n }\n }\n\n // Size search\n options.export = {\n ...options.export,\n ...findChartSize(options)\n };\n\n // Post the work to the pool\n try {\n const result = await postWork(\n exportOptions.strInj || chartJson || svg,\n options\n );\n return endCallback(false, result);\n } catch (error) {\n return endCallback(error);\n }\n};\n\n/**\n * Performs a direct inject of options before export. The function attempts\n * to stringify the provided options and removes unnecessary characters,\n * ensuring a clean and formatted input. The resulting string is saved as\n * a \"stright inject\" string in the export options. It then invokes the\n * doExport function with the updated options.\n *\n * IMPORTANT: Dangerous and must be used deliberately by someone who sets up\n * a server (see the --allowCodeExecution option).\n *\n * @param {Object} options - The export options containing the input\n * to be injected.\n * @param {function} endCallback - The callback function to be invoked\n * at the end of the process.\n *\n * @returns {Promise} A Promise that resolves with the result of the export\n * operation or rejects with an error if any issues occur during the process.\n */\nconst doStraightInject = (options, endCallback) => {\n try {\n let strInj;\n let instr = options.export.instr || options.export.options;\n\n if (typeof instr !== 'string') {\n // Try to stringify options\n strInj = instr = optionsStringify(\n instr,\n options.customLogic?.allowCodeExecution\n );\n }\n strInj = instr.replaceAll(/\\t|\\n|\\r/g, '').trim();\n\n // Get rid of the ;\n if (strInj[strInj.length - 1] === ';') {\n strInj = strInj.substring(0, strInj.length - 1);\n }\n\n // Save as stright inject string\n options.export.strInj = strInj;\n return doExport(options, false, endCallback);\n } catch (error) {\n return endCallback(\n new ExportError(\n `[chart] Malformed input detected for ${options.export?.requestId || '?'}. Please make sure that your JSON/JavaScript options are sent using the \"options\" attribute, and that if you're using SVG, it is unescaped.`\n ).setError(error)\n );\n }\n};\n\n/**\n * Exports a string based on the provided options and invokes an end callback.\n *\n * @param {string} stringToExport - The string content to be exported.\n * @param {Object} options - Export options, including customLogic with\n * allowCodeExecution flag.\n * @param {Function} endCallback - Callback function to be invoked at the end\n * of the export process.\n *\n * @returns {any} Result of the export process or an error if encountered.\n */\nconst exportAsString = (stringToExport, options, endCallback) => {\n const { allowCodeExecution } = options.customLogic;\n\n // Check if it is SVG\n if (\n stringToExport.indexOf('= 0 ||\n stringToExport.indexOf('= 0\n ) {\n log(4, '[chart] Parsing input as SVG.');\n return doExport(options, false, endCallback, stringToExport);\n }\n\n try {\n // Try to parse to JSON and call the doExport function\n const chartJSON = JSON.parse(stringToExport.replaceAll(/\\t|\\n|\\r/g, ' '));\n\n // If a correct JSON, do the export\n return doExport(options, chartJSON, endCallback);\n } catch (error) {\n // Not a valid JSON\n if (toBoolean(allowCodeExecution)) {\n return doStraightInject(options, endCallback);\n } else {\n // Do not allow straight injection without the allowCodeExecution flag\n return endCallback(\n new ExportError(\n '[chart] Only JSON configurations and SVG are allowed for this server. If this is your server, JavaScript custom code can be enabled by starting the server with the --allowCodeExecution flag.'\n ).setError(error)\n );\n }\n }\n};\n\n/**\n * Retrieves and returns the current status of code execution permission.\n *\n * @returns {any} The value of allowCodeExecution.\n */\nexport const getAllowCodeExecution = () => allowCodeExecution;\n\n/**\n * Sets the code execution permission based on the provided boolean value.\n *\n * @param {any} value - The value to be converted and assigned\n * to allowCodeExecution.\n */\nexport const setAllowCodeExecution = (value) => {\n allowCodeExecution = toBoolean(value);\n};\n\nexport default {\n batchExport,\n singleExport,\n getAllowCodeExecution,\n setAllowCodeExecution,\n startExport,\n findChartSize\n};\n","/*******************************************************************************\n\nHighcharts Export Server\n\nCopyright (c) 2016-2024, Highsoft\n\nLicenced under the MIT licence.\n\nAdditionally a valid Highcharts license is required for use.\n\nSee LICENSE file in root for details.\n\n*******************************************************************************/\n\n/**\n * @overview Used to sanitize the strings coming from the exporting module\n * to prevent XSS attacks (with the DOMPurify library).\n **/\n\nimport { JSDOM } from 'jsdom';\nimport DOMPurify from 'dompurify';\n\nimport { envs } from './envs.js';\n/**\n * Sanitizes a given HTML string by removing tags and any content within them.\n *\n * @param {string} input The HTML string to be sanitized.\n * @returns {string} The sanitized HTML string.\n */\nexport function sanitize(input) {\n const forbidden = [];\n\n if (!envs.OTHER_ALLOW_XLINK) {\n forbidden.push('xlink:href');\n }\n\n const window = new JSDOM('').window;\n const purify = DOMPurify(window);\n return purify.sanitize(input, {\n ADD_TAGS: ['foreignObject'],\n FORBID_ATTR: forbidden\n });\n}\n\nexport default sanitize;\n","/*******************************************************************************\n\nHighcharts Export Server\n\nCopyright (c) 2016-2024, Highsoft\n\nLicenced under the MIT licence.\n\nAdditionally a valid Highcharts license is required for use.\n\nSee LICENSE file in root for details.\n\n*******************************************************************************/\n\nimport { log } from './logger.js';\n\n// Array that contains ids of all ongoing intervals\nconst intervalIds = [];\n\n/**\n * Adds id of a setInterval to the intervalIds array.\n *\n * @param {NodeJS.Timeout} id - Id of an interval.\n */\nexport const addInterval = (id) => {\n intervalIds.push(id);\n};\n\n/**\n * Clears all of ongoing intervals by ids gathered in the intervalIds array.\n */\nexport const clearAllIntervals = () => {\n log(4, `[server] Clearing all registered intervals.`);\n for (const id of intervalIds) {\n clearInterval(id);\n }\n};\n\nexport default {\n addInterval,\n clearAllIntervals\n};\n","import { envs } from '../envs.js';\nimport { logWithStack } from '../logger.js';\n\n/**\n * Middleware for logging errors with stack trace and handling error response.\n *\n * @param {Error} error - The error object.\n * @param {Express.Request} req - The Express request object.\n * @param {Express.Response} res - The Express response object.\n * @param {Function} next - The next middleware function.\n */\nconst logErrorMiddleware = (error, req, res, next) => {\n // Display the error with stack in a correct format\n logWithStack(1, error);\n\n // Delete the stack for the environment other than the development\n if (envs.OTHER_NODE_ENV !== 'development') {\n delete error.stack;\n }\n\n // Call the returnErrorMiddleware\n next(error);\n};\n\n/**\n * Middleware for returning error response.\n *\n * @param {Error} error - The error object.\n * @param {Express.Request} req - The Express request object.\n * @param {Express.Response} res - The Express response object.\n * @param {Function} next - The next middleware function.\n */\nconst returnErrorMiddleware = (error, req, res, next) => {\n // Gather all requied information for the response\n const { statusCode: stCode, status, message, stack } = error;\n const statusCode = stCode || status || 400;\n\n // Set and return response\n res.status(statusCode).json({ statusCode, message, stack });\n};\n\nexport default (app) => {\n // Add log error middleware\n app.use(logErrorMiddleware);\n\n // Add set status and return error middleware\n app.use(returnErrorMiddleware);\n};\n","/*******************************************************************************\n\nHighcharts Export Server\n\nCopyright (c) 2016-2024, Highsoft\n\nLicenced under the MIT licence.\n\nAdditionally a valid Highcharts license is required for use.\n\nSee LICENSE file in root for details.\n\n*******************************************************************************/\n\nimport rateLimit from 'express-rate-limit';\n\nimport { log } from '../logger.js';\n\n/**\n * Middleware for enabling rate limiting on the specified Express app.\n *\n * @param {Express} app - The Express app instance.\n * @param {Object} limitConfig - Configuration options for rate limiting.\n */\nexport default (app, limitConfig) => {\n const msg =\n 'Too many requests, you have been rate limited. Please try again later.';\n\n // Options for the rate limiter\n const rateOptions = {\n max: limitConfig.maxRequests || 30,\n window: limitConfig.window || 1,\n delay: limitConfig.delay || 0,\n trustProxy: limitConfig.trustProxy || false,\n skipKey: limitConfig.skipKey || false,\n skipToken: limitConfig.skipToken || false\n };\n\n // Set if behind a proxy\n if (rateOptions.trustProxy) {\n app.enable('trust proxy');\n }\n\n // Create a limiter\n const limiter = rateLimit({\n windowMs: rateOptions.window * 60 * 1000,\n // Limit each IP to 100 requests per windowMs\n max: rateOptions.max,\n // Disable delaying, full speed until the max limit is reached\n delayMs: rateOptions.delay,\n handler: (request, response) => {\n response.format({\n json: () => {\n response.status(429).send({ message: msg });\n },\n default: () => {\n response.status(429).send(msg);\n }\n });\n },\n skip: (request) => {\n // Allow bypassing the limiter if a valid key/token has been sent\n if (\n rateOptions.skipKey !== false &&\n rateOptions.skipToken !== false &&\n request.query.key === rateOptions.skipKey &&\n request.query.access_token === rateOptions.skipToken\n ) {\n log(4, '[rate limiting] Skipping rate limiter.');\n return true;\n }\n return false;\n }\n });\n\n // Use a limiter as a middleware\n app.use(limiter);\n\n log(\n 3,\n `[rate limiting] Enabled rate limiting with ${rateOptions.max} requests per ${rateOptions.window} minute for each IP, trusting proxy: ${rateOptions.trustProxy}.`\n );\n};\n","import ExportError from './ExportError.js';\n\nclass HttpError extends ExportError {\n constructor(message, status) {\n super(message);\n this.status = this.statusCode = status;\n }\n\n setStatus(status) {\n this.status = status;\n return this;\n }\n}\n\nexport default HttpError;\n","/*******************************************************************************\n\nHighcharts Export Server\n\nCopyright (c) 2016-2024, Highsoft\n\nLicenced under the MIT licence.\n\nAdditionally a valid Highcharts license is required for use.\n\nSee LICENSE file in root for details.\n\n*******************************************************************************/\n\nimport { updateVersion, version } from '../../cache.js';\nimport { envs } from '../../envs.js';\n\nimport HttpError from '../../errors/HttpError.js';\n\n/**\n * Adds the POST /change_hc_version/:newVersion route that can be utilized to modify\n * the Highcharts version on the server.\n *\n * TODO: Add auth token and connect to API\n */\nexport default (app) =>\n !app\n ? false\n : app.post(\n '/version/change/:newVersion',\n async (request, response, next) => {\n try {\n const adminToken = envs.HIGHCHARTS_ADMIN_TOKEN;\n\n // Check the existence of the token\n if (!adminToken || !adminToken.length) {\n throw new HttpError(\n 'The server is not configured to perform run-time version changes: HIGHCHARTS_ADMIN_TOKEN is not set.',\n 401\n );\n }\n\n // Check if the hc-auth header contain a correct token\n const token = request.get('hc-auth');\n if (!token || token !== adminToken) {\n throw new HttpError(\n 'Invalid or missing token: Set the token in the hc-auth header.',\n 401\n );\n }\n\n // Compare versions\n const newVersion = request.params.newVersion;\n if (newVersion) {\n try {\n // eslint-disable-next-line import/no-named-as-default-member\n await updateVersion(newVersion);\n } catch (error) {\n throw new HttpError(\n `Version change: ${error.message}`,\n error.statusCode\n ).setError(error);\n }\n\n // Success\n response.status(200).send({\n statusCode: 200,\n version: version(),\n message: `Successfully updated Highcharts to version: ${newVersion}.`\n });\n } else {\n // No version specified\n throw new HttpError('No new version supplied.', 400);\n }\n } catch (error) {\n next(error);\n }\n }\n );\n","/*******************************************************************************\n\nHighcharts Export Server\n\nCopyright (c) 2016-2024, Highsoft\n\nLicenced under the MIT licence.\n\nAdditionally a valid Highcharts license is required for use.\n\nSee LICENSE file in root for details.\n\n*******************************************************************************/\n\nimport { v4 as uuid } from 'uuid';\n\nimport { getAllowCodeExecution, startExport } from '../../chart.js';\nimport { getOptions, mergeConfigOptions } from '../../config.js';\nimport { log } from '../../logger.js';\nimport {\n fixType,\n isCorrectJSON,\n isObjectEmpty,\n isPrivateRangeUrlFound,\n optionsStringify,\n measureTime\n} from '../../utils.js';\n\nimport HttpError from '../../errors/HttpError.js';\n\n// Reversed MIME types\nconst reversedMime = {\n png: 'image/png',\n jpeg: 'image/jpeg',\n gif: 'image/gif',\n pdf: 'application/pdf',\n svg: 'image/svg+xml'\n};\n\n// The requests counter\nlet requestsCounter = 0;\n\n// The array of callbacks to call before a request\nconst beforeRequest = [];\n\n// The array of callbacks to call after a request\nconst afterRequest = [];\n\n/**\n * Invokes an array of callback functions with specified parameters, allowing\n * customization of request handling.\n *\n * @param {Function[]} callbacks - An array of callback functions\n * to be executed.\n * @param {Express.Request} request - The Express request object.\n * @param {Express.Response} response - The Express response object.\n * @param {Object} data - An object containing parameters like id, uniqueId,\n * type, and body.\n *\n * @returns {boolean} - Returns a boolean indicating the overall result\n * of the callback invocations.\n */\nconst doCallbacks = (callbacks, request, response, data) => {\n let result = true;\n const { id, uniqueId, type, body } = data;\n\n callbacks.some((callback) => {\n if (callback) {\n let callResponse = callback(request, response, id, uniqueId, type, body);\n\n if (callResponse !== undefined && callResponse !== true) {\n result = callResponse;\n }\n\n return true;\n }\n });\n\n return result;\n};\n\n/**\n * Handles the export requests from the client.\n *\n * @param {Express.Request} request - The Express request object.\n * @param {Express.Response} response - The Express response object.\n * @param {Function} next - The next middleware function.\n *\n * @returns {Promise} - A promise that resolves once the export process\n * is complete.\n */\nconst exportHandler = async (request, response, next) => {\n try {\n // Start counting time\n const stopCounter = measureTime();\n\n // Create a unique ID for a request\n const uniqueId = uuid().replace(/-/g, '');\n\n // Get the current server's general options\n const defaultOptions = getOptions();\n\n const body = request.body;\n const id = ++requestsCounter;\n\n let type = fixType(body.type);\n\n // Throw 'Bad Request' if there's no body\n if (!body || isObjectEmpty(body)) {\n throw new HttpError(\n 'The request body is required. Please ensure that your Content-Type header is correct (accepted types are application/json and multipart/form-data).',\n 400\n );\n }\n\n // All of the below can be used\n let instr = isCorrectJSON(body.infile || body.options || body.data);\n\n // Throw 'Bad Request' if there's no JSON or SVG to export\n if (!instr && !body.svg) {\n log(\n 2,\n `The request with ID ${uniqueId} from ${\n request.headers['x-forwarded-for'] || request.connection.remoteAddress\n } was incorrect:\n Content-Type: ${request.headers['content-type']}. \n Chart constructor: ${body.constr}.\n Dimensions: ${body.width}x${body.height} @ ${body.scale} scale.\n Type: ${type}.\n Is SVG set? ${typeof body.svg !== 'undefined'}.\n B64? ${typeof body.b64 !== 'undefined'}.\n No download? ${typeof body.noDownload !== 'undefined'}.\n\n Payload received: ${JSON.stringify(body.infile || body.options || body.data || body.svg)}\n\n `\n );\n\n throw new HttpError(\n \"No correct chart data found. Ensure that you are using either application/json or multipart/form-data headers. If sending JSON, make sure the chart data is in the 'infile', 'options', or 'data' attribute. If sending SVG, ensure it is in the 'svg' attribute.\",\n 400\n );\n }\n\n let callResponse = false;\n\n // Call the before request functions\n callResponse = doCallbacks(beforeRequest, request, response, {\n id,\n uniqueId,\n type,\n body\n });\n\n // Block the request if one of a callbacks failed\n if (callResponse !== true) {\n return response.send(callResponse);\n }\n\n let connectionAborted = false;\n\n // In case the connection is closed, force to abort further actions\n request.socket.on('close', (hadErrors) => {\n if (hadErrors) {\n connectionAborted = true;\n }\n });\n\n log(4, `[export] Got an incoming HTTP request with ID ${uniqueId}.`);\n\n body.constr = (typeof body.constr === 'string' && body.constr) || 'chart';\n\n // Gather and organize options from the payload\n const requestOptions = {\n export: {\n instr,\n type,\n constr: body.constr[0].toLowerCase() + body.constr.substr(1),\n height: body.height,\n width: body.width,\n scale: body.scale || defaultOptions.export.scale,\n globalOptions: isCorrectJSON(body.globalOptions, true),\n themeOptions: isCorrectJSON(body.themeOptions, true)\n },\n customLogic: {\n allowCodeExecution: getAllowCodeExecution(),\n allowFileResources: false,\n resources: isCorrectJSON(body.resources, true),\n callback: body.callback,\n customCode: body.customCode\n }\n };\n\n if (instr) {\n // Stringify JSON with options\n requestOptions.export.instr = optionsStringify(\n instr,\n requestOptions.customLogic.allowCodeExecution\n );\n }\n\n // Merge the request options into default ones\n const options = mergeConfigOptions(defaultOptions, requestOptions);\n\n // Save the JSON if exists\n options.export.options = instr;\n\n // Lastly, add the server specific arguments into options as payload\n options.payload = {\n svg: body.svg || false,\n b64: body.b64 || false,\n noDownload: body.noDownload || false,\n requestId: uniqueId\n };\n\n // Test xlink:href elements from payload's SVG\n if (body.svg && isPrivateRangeUrlFound(options.payload.svg)) {\n throw new HttpError(\n 'SVG potentially contain at least one forbidden URL in xlink:href element. Please review the SVG content and ensure that all referenced URLs comply with security policies.',\n 400\n );\n }\n\n // Start the export process\n await startExport(options, (error, info) => {\n // Remove the close event from the socket\n request.socket.removeAllListeners('close');\n\n // After the whole exporting process\n if (defaultOptions.server.benchmarking) {\n log(\n 5,\n `[benchmark] Request with ID ${uniqueId} - After the whole exporting process: ${stopCounter()}ms.`\n );\n }\n\n // If the connection was closed, do nothing\n if (connectionAborted) {\n return log(\n 3,\n `[export] The client closed the connection before the chart finished processing.`\n );\n }\n\n // If error, log it and send it to the error middleware\n if (error) {\n throw error;\n }\n\n // If data is missing, log the message and send it to the error middleware\n if (!info || !info.result) {\n throw new HttpError(\n `Unexpected return from chart generation. Please check your request data. For the request with ID ${uniqueId}, the result is ${info.result}.`,\n 400\n );\n }\n\n // Get the type from options\n type = info.options.export.type;\n\n // The after request callbacks\n doCallbacks(afterRequest, request, response, { id, body: info.result });\n\n if (info.result) {\n // If only base64 is required, return it\n if (body.b64) {\n // SVG Exception for the Highcharts 11.3.0 version\n if (type === 'pdf' || type == 'svg') {\n return response.send(\n Buffer.from(info.result, 'utf8').toString('base64')\n );\n }\n\n return response.send(info.result);\n }\n\n // Set correct content type\n response.header('Content-Type', reversedMime[type] || 'image/png');\n\n // Decide whether to download or not chart file\n if (!body.noDownload) {\n response.attachment(\n `${request.params.filename || request.body.filename || 'chart'}.${\n type || 'png'\n }`\n );\n }\n\n // If SVG, return plain content\n return type === 'svg'\n ? response.send(info.result)\n : response.send(Buffer.from(info.result, 'base64'));\n }\n });\n } catch (error) {\n next(error);\n }\n};\n\nexport default (app) => {\n /**\n * Adds the POST / a route for handling POST requests at the root endpoint.\n */\n app.post('/', exportHandler);\n\n /**\n * Adds the POST /:filename a route for handling POST requests with\n * a specified filename parameter.\n */\n app.post('/:filename', exportHandler);\n};\n","/*******************************************************************************\n\nHighcharts Export Server\n\nCopyright (c) 2016-2024, Highsoft\n\nLicenced under the MIT licence.\n\nAdditionally a valid Highcharts license is required for use.\n\nSee LICENSE file in root for details.\n\n*******************************************************************************/\n\nimport { readFileSync } from 'fs';\nimport { join as pather } from 'path';\nimport { log } from '../../logger.js';\n\nimport { version } from '../../cache.js';\nimport { addInterval } from '../../intervals.js';\nimport pool from '../../pool.js';\nimport { __dirname } from '../../utils.js';\n\nconst pkgFile = JSON.parse(readFileSync(pather(__dirname, 'package.json')));\n\nconst serverStartTime = new Date();\n\nconst successRates = [];\nconst recordInterval = 60 * 1000; // record every minute\nconst windowSize = 30; // 30 minutes\n\n/**\n * Calculates moving average indicator based on the data from the successRates\n * array.\n *\n * @returns {number} - A moving average for success ratio of the server exports.\n */\nfunction calculateMovingAverage() {\n const sum = successRates.reduce((a, b) => a + b, 0);\n return sum / successRates.length;\n}\n\n/**\n * Starts the interval responsible for calculating current success rate ratio\n * and gathers\n *\n * @returns {NodeJS.Timeout} id - Id of an interval.\n */\nexport const startSuccessRate = () =>\n setInterval(() => {\n const stats = pool.getStats();\n const successRatio =\n stats.exportAttempts === 0\n ? 1\n : (stats.performedExports / stats.exportAttempts) * 100;\n\n successRates.push(successRatio);\n if (successRates.length > windowSize) {\n successRates.shift();\n }\n }, recordInterval);\n\n/**\n * Adds the /health and /success-moving-average routes\n * which output basic stats for the server.\n */\nexport default function addHealthRoutes(app) {\n if (!app) {\n return false;\n }\n\n // Start processing success rate ratio interval and save its id to the array\n // for the graceful clearing on shutdown with injected addInterval funtion\n addInterval(startSuccessRate());\n\n app.get('/health', (_, res) => {\n const stats = pool.getStats();\n const period = successRates.length;\n const movingAverage = calculateMovingAverage();\n\n log(4, '[health.js] GET /health [200] - returning server health.');\n\n res.send({\n status: 'OK',\n bootTime: serverStartTime,\n uptime:\n Math.floor(\n (new Date().getTime() - serverStartTime.getTime()) / 1000 / 60\n ) + ' minutes',\n version: pkgFile.version,\n highchartsVersion: version(),\n averageProcessingTime: stats.spentAverage,\n performedExports: stats.performedExports,\n failedExports: stats.droppedExports,\n exportAttempts: stats.exportAttempts,\n sucessRatio: (stats.performedExports / stats.exportAttempts) * 100,\n // eslint-disable-next-line import/no-named-as-default-member\n pool: pool.getPoolInfoJSON(),\n\n // Moving average\n period,\n movingAverage,\n message:\n isNaN(movingAverage) || !successRates.length\n ? 'Too early to report. No exports made yet. Please check back soon.'\n : `Last ${period} minutes had a success rate of ${movingAverage.toFixed(2)}%.`,\n\n // SVG/JSON attempts\n svgExportAttempts: stats.exportFromSvgAttempts,\n jsonExportAttempts: stats.performedExports - stats.exportFromSvgAttempts\n });\n });\n}\n","/*******************************************************************************\n\nHighcharts Export Server\n\nCopyright (c) 2016-2024, Highsoft\n\nLicenced under the MIT licence.\n\nAdditionally a valid Highcharts license is required for use.\n\nSee LICENSE file in root for details.\n\n*******************************************************************************/\n\nimport { promises as fsPromises } from 'fs';\nimport { posix } from 'path';\n\nimport cors from 'cors';\nimport express from 'express';\nimport http from 'http';\nimport https from 'https';\nimport multer from 'multer';\n\nimport errorHandler from './error.js';\nimport rateLimit from './rate_limit.js';\nimport { log, logWithStack } from '../logger.js';\nimport { __dirname } from '../utils.js';\n\nimport vSwitchRoute from './routes/change_hc_version.js';\nimport exportRoutes from './routes/export.js';\nimport healthRoute from './routes/health.js';\nimport uiRoute from './routes/ui.js';\n\nimport ExportError from '../errors/ExportError.js';\n\n// Array of an active servers\nconst activeServers = new Map();\n\n// Create express app\nconst app = express();\n\n// Disable the X-Powered-By header\napp.disable('x-powered-by');\n\n// Enable CORS support\napp.use(cors());\n\n// Getting a lot of RangeNotSatisfiableError exception.\n// Even though this is a deprecated options, let's try to set it to false.\napp.use((_req, res, next) => {\n res.set('Accept-Ranges', 'none');\n next();\n});\n\n/**\n * Attach error handlers to the server.\n *\n * @param {http.Server} server - The HTTP/HTTPS server instance.\n */\nconst attachServerErrorHandlers = (server) => {\n server.on('clientError', (error, socket) => {\n logWithStack(\n 1,\n error,\n `[server] Client error: ${error.message}, destroying socket.`\n );\n socket.destroy();\n });\n\n server.on('error', (error) => {\n logWithStack(1, error, `[server] Server error: ${error.message}`);\n });\n\n server.on('connection', (socket) => {\n socket.on('error', (error) => {\n logWithStack(1, error, `[server] Socket error: ${error.message}`);\n });\n });\n};\n\n/**\n * Starts an HTTP server based on the provided configuration. The `serverConfig`\n * object contains all server related properties (see the `server` section\n * in the `lib/schemas/config.js` file for a reference).\n *\n * @param {Object} serverConfig - The server configuration object.\n *\n * @throws {ExportError} - Throws an error if the server cannot be configured\n * and started.\n */\nexport const startServer = async (serverConfig) => {\n try {\n // TODO: Read from config/env\n // NOTE:\n // Too big limits lead to timeouts in the export process when the\n // rasterization timeout is set too low.\n const uploadLimitMiB = serverConfig.maxUploadSize || 3;\n const uploadLimitBytes = uploadLimitMiB * 1024 * 1024;\n\n // Enable parsing of form data (files) with Multer package\n const storage = multer.memoryStorage();\n const upload = multer({\n storage,\n limits: {\n fieldSize: uploadLimitBytes\n }\n });\n\n // Enable body parser\n app.use(express.json({ limit: uploadLimitBytes }));\n app.use(express.urlencoded({ extended: true, limit: uploadLimitBytes }));\n\n // Use only non-file multipart form fields\n app.use(upload.none());\n\n // Stop if not enabled\n if (!serverConfig.enable) {\n return false;\n }\n\n // Listen HTTP server\n if (!serverConfig.ssl.force) {\n // Main server instance (HTTP)\n const httpServer = http.createServer(app);\n\n // Attach error handlers and listen to the server\n attachServerErrorHandlers(httpServer);\n\n // Listen\n httpServer.listen(serverConfig.port, serverConfig.host);\n\n // Save the reference to HTTP server\n activeServers.set(serverConfig.port, httpServer);\n\n log(\n 3,\n `[server] Started HTTP server on ${serverConfig.host}:${serverConfig.port}.`\n );\n }\n\n // Listen HTTPS server\n if (serverConfig.ssl.enable) {\n // Set up an SSL server also\n let key, cert;\n\n try {\n // Get the SSL key\n key = await fsPromises.readFile(\n posix.join(serverConfig.ssl.certPath, 'server.key'),\n 'utf8'\n );\n\n // Get the SSL certificate\n cert = await fsPromises.readFile(\n posix.join(serverConfig.ssl.certPath, 'server.crt'),\n 'utf8'\n );\n } catch (error) {\n log(\n 2,\n `[server] Unable to load key/certificate from the '${serverConfig.ssl.certPath}' path. Could not run secured layer server.`\n );\n }\n\n if (key && cert) {\n // Main server instance (HTTPS)\n const httpsServer = https.createServer({ key, cert }, app);\n\n // Attach error handlers and listen to the server\n attachServerErrorHandlers(httpsServer);\n\n // Listen\n httpsServer.listen(serverConfig.ssl.port, serverConfig.host);\n\n // Save the reference to HTTPS server\n activeServers.set(serverConfig.ssl.port, httpsServer);\n\n log(\n 3,\n `[server] Started HTTPS server on ${serverConfig.host}:${serverConfig.ssl.port}.`\n );\n }\n }\n\n // Enable the rate limiter if config says so\n if (\n serverConfig.rateLimiting &&\n serverConfig.rateLimiting.enable &&\n ![0, NaN].includes(serverConfig.rateLimiting.maxRequests)\n ) {\n rateLimit(app, serverConfig.rateLimiting);\n }\n\n // Set up static folder's route\n app.use(express.static(posix.join(__dirname, 'public')));\n\n // Set up routes\n healthRoute(app);\n exportRoutes(app);\n uiRoute(app);\n vSwitchRoute(app);\n\n // Set up centralized error handler\n errorHandler(app);\n } catch (error) {\n throw new ExportError(\n '[server] Could not configure and start the server.'\n ).setError(error);\n }\n};\n\n/**\n * Closes all servers associated with Express app instance.\n */\nexport const closeServers = () => {\n log(4, `[server] Closing all servers.`);\n for (const [port, server] of activeServers) {\n server.close(() => {\n activeServers.delete(port);\n log(4, `[server] Closed server on port: ${port}.`);\n });\n }\n};\n\n/**\n * Get all servers associated with Express app instance.\n *\n * @returns {Array} - Servers associated with Express app instance.\n */\nexport const getServers = () => activeServers;\n\n/**\n * Enable rate limiting for the server.\n *\n * @param {Object} limitConfig - Configuration object for rate limiting.\n */\nexport const enableRateLimiting = (limitConfig) => rateLimit(app, limitConfig);\n\n/**\n * Get the Express instance.\n *\n * @returns {Object} - The Express instance.\n */\nexport const getExpress = () => express;\n\n/**\n * Get the Express app instance.\n *\n * @returns {Object} - The Express app instance.\n */\nexport const getApp = () => app;\n\n/**\n * Apply middleware(s) to a specific path.\n *\n * @param {string} path - The path to which the middleware(s) should be applied.\n * @param {...Function} middlewares - The middleware functions to be applied.\n */\nexport const use = (path, ...middlewares) => {\n app.use(path, ...middlewares);\n};\n\n/**\n * Set up a route with GET method and apply middleware(s).\n *\n * @param {string} path - The route path.\n * @param {...Function} middlewares - The middleware functions to be applied.\n */\nexport const get = (path, ...middlewares) => {\n app.get(path, ...middlewares);\n};\n\n/**\n * Set up a route with POST method and apply middleware(s).\n *\n * @param {string} path - The route path.\n * @param {...Function} middlewares - The middleware functions to be applied.\n */\nexport const post = (path, ...middlewares) => {\n app.post(path, ...middlewares);\n};\n\nexport default {\n startServer,\n closeServers,\n getServers,\n enableRateLimiting,\n getExpress,\n getApp,\n use,\n get,\n post\n};\n","/*******************************************************************************\n\nHighcharts Export Server\n\nCopyright (c) 2016-2024, Highsoft\n\nLicenced under the MIT licence.\n\nAdditionally a valid Highcharts license is required for use.\n\nSee LICENSE file in root for details.\n\n*******************************************************************************/\n\nimport { join } from 'path';\n\nimport { __dirname } from '../../utils.js';\n\n/**\n * Adds the GET / route for a UI when enabled on the export server.\n */\nexport default (app) =>\n !app\n ? false\n : app.get('/', (_request, response) => {\n response.sendFile(join(__dirname, 'public', 'index.html'), {\n acceptRanges: false\n });\n });\n","/*******************************************************************************\n\nHighcharts Export Server\n\nCopyright (c) 2016-2024, Highsoft\n\nLicenced under the MIT licence.\n\nAdditionally a valid Highcharts license is required for use.\n\nSee LICENSE file in root for details.\n\n*******************************************************************************/\n\nimport { clearAllIntervals } from './intervals.js';\nimport { killPool } from './pool.js';\nimport { closeServers } from './server/server.js';\n\n/**\n * Clean up function to trigger before ending process for the graceful shutdown.\n *\n * @param {number} exitCode - An exit code for the process.exit() function.\n */\nexport const shutdownCleanUp = async (exitCode) => {\n // Await freeing all resources\n await Promise.allSettled([\n // Clear all ongoing intervals\n clearAllIntervals(),\n\n // Get available server instances (HTTP/HTTPS) and close them\n closeServers(),\n\n // Close pool along with its workers and the browser instance, if exists\n killPool()\n ]);\n\n // Exit process with a correct code\n process.exit(exitCode);\n};\n\nexport default {\n shutdownCleanUp\n};\n","/*******************************************************************************\n\nHighcharts Export Server\n\nCopyright (c) 2016-2024, Highsoft\n\nLicenced under the MIT licence.\n\nAdditionally a valid Highcharts license is required for use.\n\nSee LICENSE file in root for details.\n\n*******************************************************************************/\n\nimport 'colors';\n\nimport { checkAndUpdateCache } from './cache.js';\nimport {\n batchExport,\n setAllowCodeExecution,\n singleExport,\n startExport\n} from './chart.js';\nimport { mapToNewConfig, manualConfig, setOptions } from './config.js';\nimport {\n initLogging,\n log,\n logWithStack,\n setLogLevel,\n enableFileLogging\n} from './logger.js';\nimport { initPool, killPool } from './pool.js';\nimport { shutdownCleanUp } from './resource_release.js';\nimport server, { startServer } from './server/server.js';\nimport { printLogo, printUsage } from './utils.js';\n\n/**\n * Attaches exit listeners to the process, ensuring proper cleanup of resources\n * and termination on exit signals. Handles 'exit', 'SIGINT', 'SIGTERM', and\n * 'uncaughtException' events.\n */\nconst attachProcessExitListeners = () => {\n log(3, '[process] Attaching exit listeners to the process.');\n\n // Handler for the 'exit'\n process.on('exit', (code) => {\n log(4, `Process exited with code ${code}.`);\n });\n\n // Handler for the 'SIGINT'\n process.on('SIGINT', async (name, code) => {\n log(4, `The ${name} event with code: ${code}.`);\n await shutdownCleanUp(0);\n });\n\n // Handler for the 'SIGTERM'\n process.on('SIGTERM', async (name, code) => {\n log(4, `The ${name} event with code: ${code}.`);\n await shutdownCleanUp(0);\n });\n\n // Handler for the 'SIGHUP'\n process.on('SIGHUP', async (name, code) => {\n log(4, `The ${name} event with code: ${code}.`);\n await shutdownCleanUp(0);\n });\n\n // Handler for the 'uncaughtException'\n process.on('uncaughtException', async (error, name) => {\n logWithStack(1, error, `The ${name} error.`);\n await shutdownCleanUp(1);\n });\n};\n\n/**\n * Initializes the export process. Tasks such as configuring logging, checking\n * cache and sources, and initializing the pool of resources happen during\n * this stage. Function that is required to be called before trying to export charts or setting a server. The `options` is an object that contains all options.\n *\n * @param {Object} options - All export options.\n *\n * @returns {Promise} Promise resolving to the updated export options.\n */\nconst initExport = async (options) => {\n // Set the allowCodeExecution per export module scope\n setAllowCodeExecution(\n options.customLogic && options.customLogic.allowCodeExecution\n );\n\n // Init the logging\n initLogging(options.logging);\n\n // Attach process' exit listeners\n if (options.other.listenToProcessExits) {\n attachProcessExitListeners();\n }\n\n // Check if cache needs to be updated\n await checkAndUpdateCache(options);\n\n // Init the pool\n await initPool({\n pool: options.pool || {\n minWorkers: 1,\n maxWorkers: 1\n },\n puppeteerArgs: options.puppeteer.args || []\n });\n\n // Return updated options\n return options;\n};\n\nexport default {\n // Server\n server,\n startServer,\n\n // Exporting\n initExport,\n singleExport,\n batchExport,\n startExport,\n\n // Pool\n initPool,\n killPool,\n\n // Other\n setOptions,\n shutdownCleanUp,\n\n // Logs\n log,\n logWithStack,\n setLogLevel,\n enableFileLogging,\n\n // Utils\n mapToNewConfig,\n manualConfig,\n printLogo,\n printUsage\n};\n"],"names":["scriptsNames","core","modules","indicators","custom","defaultConfig","puppeteer","args","value","type","description","tempDir","envLink","highcharts","version","cdnURL","coreScripts","moduleScripts","indicatorScripts","customScripts","forceFetch","cachePath","export","infile","instr","options","outfile","constr","defaultHeight","defaultWidth","defaultScale","height","width","scale","globalOptions","themeOptions","batch","rasterizationTimeout","customLogic","allowCodeExecution","allowFileResources","customCode","callback","resources","loadConfig","legacyName","createConfig","server","maxUploadSize","enable","cliName","host","port","benchmarking","proxy","username","password","timeout","rateLimiting","maxRequests","window","delay","trustProxy","skipKey","skipToken","ssl","force","certPath","pool","minWorkers","maxWorkers","workLimit","acquireTimeout","createTimeout","destroyTimeout","idleTimeout","createRetryInterval","reaperInterval","logging","level","file","dest","toConsole","toFile","ui","route","other","nodeEnv","listenToProcessExits","noLogo","hardResetPage","browserShellMode","debug","headless","devtools","listenToConsole","dumpio","slowMo","debuggingPort","promptsConfig","name","message","initial","join","separator","instructions","choices","hint","min","max","round","absoluteProps","nestedArgs","createNestedArgs","obj","propChain","Object","keys","forEach","k","includes","entry","substring","undefined","dotenv","config","v","filterArray","z","string","transform","split","map","trim","filter","length","enum","values","refine","test","isNaN","parseFloat","envs","object","PUPPETEER_TEMP_DIR","HIGHCHARTS_VERSION","HIGHCHARTS_CDN_URL","startsWith","HIGHCHARTS_CORE_SCRIPTS","HIGHCHARTS_MODULE_SCRIPTS","HIGHCHARTS_INDICATOR_SCRIPTS","HIGHCHARTS_FORCE_FETCH","HIGHCHARTS_CACHE_PATH","HIGHCHARTS_ADMIN_TOKEN","EXPORT_TYPE","EXPORT_CONSTR","EXPORT_DEFAULT_HEIGHT","EXPORT_DEFAULT_WIDTH","EXPORT_DEFAULT_SCALE","EXPORT_RASTERIZATION_TIMEOUT","CUSTOM_LOGIC_ALLOW_CODE_EXECUTION","CUSTOM_LOGIC_ALLOW_FILE_RESOURCES","SERVER_ENABLE","SERVER_HOST","SERVER_PORT","SERVER_MAX_UPLOAD_SIZE","SERVER_BENCHMARKING","SERVER_PROXY_HOST","SERVER_PROXY_PORT","SERVER_PROXY_USERNAME","SERVER_PROXY_PASSWORD","SERVER_PROXY_TIMEOUT","SERVER_RATE_LIMITING_ENABLE","SERVER_RATE_LIMITING_MAX_REQUESTS","SERVER_RATE_LIMITING_WINDOW","SERVER_RATE_LIMITING_DELAY","SERVER_RATE_LIMITING_TRUST_PROXY","SERVER_RATE_LIMITING_SKIP_KEY","SERVER_RATE_LIMITING_SKIP_TOKEN","SERVER_SSL_ENABLE","SERVER_SSL_FORCE","SERVER_SSL_PORT","SERVER_SSL_CERT_PATH","POOL_MIN_WORKERS","POOL_MAX_WORKERS","POOL_WORK_LIMIT","POOL_ACQUIRE_TIMEOUT","POOL_CREATE_TIMEOUT","POOL_DESTROY_TIMEOUT","POOL_IDLE_TIMEOUT","POOL_CREATE_RETRY_INTERVAL","POOL_REAPER_INTERVAL","POOL_BENCHMARKING","LOGGING_LEVEL","LOGGING_FILE","LOGGING_DEST","LOGGING_TO_CONSOLE","LOGGING_TO_FILE","UI_ENABLE","UI_ROUTE","OTHER_NODE_ENV","OTHER_LISTEN_TO_PROCESS_EXITS","OTHER_NO_LOGO","OTHER_HARD_RESET_PAGE","OTHER_BROWSER_SHELL_MODE","OTHER_ALLOW_XLINK","DEBUG_ENABLE","DEBUG_HEADLESS","DEBUG_DEVTOOLS","DEBUG_LISTEN_TO_CONSOLE","DEBUG_DUMPIO","DEBUG_SLOW_MO","DEBUG_DEBUGGING_PORT","partial","parse","process","env","colors","pathCreated","levelsDesc","title","color","listeners","logToFile","texts","prefix","existsSync","mkdirSync","appendFile","concat","error","console","log","newLevel","Date","toString","fn","apply","logWithStack","customMessage","mainMessage","stackMessage","stack","slice","setLogLevel","enableFileLogging","logDest","logFile","endsWith","__dirname","fileURLToPath","URL","url","fixType","formats","outType","pop","find","t","handleResources","allowedProps","handledResources","correctResources","isCorrectJSON","readFileSync","files","propName","item","data","parsedData","JSON","stringify","isObject","Array","isArray","deepCopy","copy","key","prototype","hasOwnProperty","call","optionsStringify","allowFunctions","replaceAll","printUsage","bold","yellow","cycleCategories","option","entries","descName","green","i","blue","category","toUpperCase","red","toBoolean","wrapAround","replace","measureTime","start","hrtime","bigint","Number","generalOptions","getOptions","mergeConfigOptions","newOptions","mergedOptions","updateDefaultConfig","configObj","customObj","customValue","initOptions","items","recursiveProps","objectToUpdate","nestedNames","shift","assign","async","fetch","requestOptions","Promise","resolve","reject","protocol","https","http","getProtocol","get","headers","Referer","res","on","chunk","text","ExportError","Error","constructor","super","this","setError","statusCode","cache","activeManifest","sources","hcVersion","extractVersion","indexOf","fetchAndProcessScript","script","fetchedModules","shouldThrowError","response","updateCache","highchartsOptions","proxyOptions","sourcePath","proxyAgent","HttpsProxyAgent","agent","allFetchPromises","all","fetchScripts","c","m","writeFileSync","checkAndUpdateCache","manifestPath","requestUpdate","manifest","moduleMap","numberOfModules","some","moduleName","newManifest","saveConfigToManifest","setupHighcharts","Highcharts","animObject","duration","triggerExport","chartOptions","displayErrors","_displayErrors","merge","setOptions","wrap","setOptionsObj","chart","animation","strInj","isRenderComplete","Chart","proceed","userOptions","cb","exporting","enabled","plotOptions","series","label","tooltip","onHighchartsRender","addEvent","Series","Function","finalOptions","finalCallback","defaultOptions","prop","template","browser","newPage","page","setCacheEnabled","setPageContent","isClosed","$eval","element","errorMessage","innerHTML","setPageEvents","clearPageResources","injectedResources","resource","dispose","evaluate","oldCharts","charts","oldChart","destroy","scriptsToRemove","document","getElementsByTagName","stylesToRemove","linksToRemove","remove","setContent","waitUntil","addScriptTag","path","setAsConfig","totalSize","Buffer","byteLength","toFixed","puppeteerExport","exportOptions","debugger","isSVG","svgTemplate","injectedJs","js","push","content","isLocal","jsResource","injectedCss","css","cssImports","match","cssImportPath","cssResource","addStyleTag","addPageResources","size","svgElement","querySelector","chartHeight","baseVal","chartWidth","body","style","zoom","margin","viewportHeight","Math","abs","ceil","viewportWidth","x","y","getBoundingClientRect","trunc","getClipRegion","setViewport","deviceScaleFactor","outerHTML","createSVG","encoding","clip","race","screenshot","captureBeyondViewport","fullPage","optimizeForSpeed","quality","omitBackground","_resolve","setTimeout","createImage","emulateMediaType","pdf","createPDF","stats","performedExports","exportAttempts","exportFromSvgAttempts","timeSpent","droppedExports","spentAverage","poolConfig","factory","create","id","uuid","startDate","getTime","workCount","random","validate","workerHandle","close","initPool","puppeteerArgs","puppeteerOptions","enabledDebug","debugOptions","launchOptions","userDataDir","handleSIGINT","handleSIGTERM","handleSIGHUP","waitForInitialPage","defaultViewport","maxTries","tryCount","open","launch","createBrowser","parseInt","Pool","acquireTimeoutMillis","createTimeoutMillis","destroyTimeoutMillis","idleTimeoutMillis","createRetryIntervalMillis","reapIntervalMillis","propagateCreateError","r","hardReset","goto","clearPage","eventId","initialResources","acquire","promise","release","killPool","worker","used","destroyed","connected","closeBrowser","postWork","getPoolInfo","acquireCounter","payload","requestId","workStart","exportCounter","result","exportTime","getPoolInfoJSON","numFree","numUsed","available","pending","numPendingAcquires","pool$1","startExport","settings","endCallback","svg","initExportSettings","exportAsString","input","forbidden","JSDOM","DOMPurify","sanitize","ADD_TAGS","FORBID_ATTR","doStraightInject","doExport","findChartSize","precision","multiplier","pow","roundNumber","sourceHeight","sourceWidth","param","chartJson","customLogicOptions","allowCodeExecutionScoped","optionsName","stringToExport","chartJSON","intervalIds","clearAllIntervals","clearInterval","logErrorMiddleware","req","next","returnErrorMiddleware","stCode","status","json","rateLimit","app","limitConfig","msg","rateOptions","limiter","windowMs","delayMs","handler","request","format","send","default","skip","query","access_token","use","HttpError","setStatus","vSwitchRoute","post","adminToken","token","newVersion","params","updateVersion","reversedMime","png","jpeg","gif","requestsCounter","beforeRequest","afterRequest","doCallbacks","callbacks","uniqueId","callResponse","exportHandler","stopCounter","connection","remoteAddress","b64","noDownload","connectionAborted","socket","hadErrors","toLowerCase","substr","pattern","isPrivateRangeUrlFound","info","removeAllListeners","from","header","attachment","filename","pkgFile","pather","serverStartTime","successRates","addHealthRoutes","setInterval","successRatio","_","period","movingAverage","reduce","a","b","bootTime","uptime","floor","highchartsVersion","averageProcessingTime","failedExports","sucessRatio","svgExportAttempts","jsonExportAttempts","activeServers","Map","express","disable","cors","_req","set","attachServerErrorHandlers","startServer","serverConfig","uploadLimitBytes","storage","multer","memoryStorage","upload","limits","fieldSize","limit","urlencoded","extended","none","httpServer","createServer","listen","cert","fsPromises","readFile","posix","httpsServer","NaN","static","healthRoute","exportRoutes","_request","sendFile","acceptRanges","uiRoute","errorHandler","closeServers","delete","getServers","enableRateLimiting","getExpress","getApp","middlewares","shutdownCleanUp","exitCode","allSettled","exit","index","initExport","loggingOptions","initLogging","code","singleExport","batchExport","batchFunctions","pair","configIndex","findIndex","arg","fileName","loadConfigFile","showUsage","propertiesChain","argumentType","pairArgumentValue","mapToNewConfig","oldOptions","manualConfig","configFileName","configFile","choice","prompts","onSubmit","p","categories","questionsCounter","allQuestions","section","prompt","answer","module","writeFile","printLogo","packageVersion"],"mappings":"0lBAeO,MAAMA,EAAe,CAC1BC,KAAM,CAAC,aAAc,kBAAmB,iBACxCC,QAAS,CACP,QACA,MACA,QACA,YACA,uBACA,gBAEA,eACA,QACA,OACA,aACA,mBACA,eACA,cACA,UACA,UACA,cACA,WACA,UACA,YACA,cACA,YACA,sBACA,SACA,SACA,WACA,aACA,YACA,eACA,yBACA,SACA,eACA,YACA,kBACA,SACA,cACA,mBACA,eACA,kBACA,cACA,eAEA,cACA,WACA,eACA,WACA,SACA,OACA,WACA,YACA,SACA,qBACA,aACA,WACA,WACA,WACA,WACA,eACA,UACA,kBACA,oBACA,aACA,UACA,cACA,YACA,YAEFC,WAAY,CAAC,kBACbC,OAAQ,CACN,wEACA,mGAMSC,EAAgB,CAC3BC,UAAW,CACTC,KAAM,CACJC,MAAO,CACL,mCACA,kBACA,0CACA,2BACA,kCACA,kCACA,wCACA,2CACA,qBACA,4BACA,2CACA,uDACA,6BACA,yBACA,0BACA,+BACA,uBACA,uFACA,yBACA,oCACA,oBACA,0BACA,8CACA,2BACA,0BACA,6BACA,mCACA,wCACA,mCACA,2BACA,kCACA,uBACA,iBACA,yBACA,8BACA,oBACA,2BACA,eACA,6BACA,iBACA,aACA,SAEA,sBAEA,yBACA,oBACA,uBAEFC,KAAM,WACNC,YAAa,yCAEfC,QAAS,CACPH,MAAO,SACPC,KAAM,SACNG,QAAS,qBACTF,YAAa,0DAGjBG,WAAY,CACVC,QAAS,CACPN,MAAO,SACPC,KAAM,SACNG,QAAS,qBACTF,YAAa,sCAEfK,OAAQ,CACNP,MAAO,+BACPC,KAAM,SACNG,QAAS,qBACTF,YAAa,kDAEfM,YAAa,CACXR,MAAOR,EAAaC,KACpBQ,KAAM,WACNG,QAAS,0BACTF,YAAa,yCAEfO,cAAe,CACbT,MAAOR,EAAaE,QACpBO,KAAM,WACNG,QAAS,4BACTF,YAAa,uCAEfQ,iBAAkB,CAChBV,MAAOR,EAAaG,WACpBM,KAAM,WACNG,QAAS,+BACTF,YAAa,0CAEfS,cAAe,CACbX,MAAOR,EAAaI,OACpBK,KAAM,WACN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"} \ No newline at end of file