@bitgo-beta/sdk-coin-dot 2.2.8-beta.21 → 2.2.8-beta.2100
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{src → cjs/src}/dot.d.ts +38 -28
- package/dist/cjs/src/dot.d.ts.map +1 -0
- package/dist/cjs/src/dot.js +688 -0
- package/dist/cjs/src/index.d.ts.map +1 -0
- package/dist/{src → cjs/src}/index.js +6 -2
- package/dist/cjs/src/lib/addressInitializationBuilder.d.ts.map +1 -0
- package/dist/cjs/src/lib/addressInitializationBuilder.js +182 -0
- package/dist/{src → cjs/src}/lib/batchTransactionBuilder.d.ts +1 -0
- package/dist/cjs/src/lib/batchTransactionBuilder.d.ts.map +1 -0
- package/dist/cjs/src/lib/batchTransactionBuilder.js +229 -0
- package/dist/cjs/src/lib/claimBuilder.d.ts.map +1 -0
- package/dist/cjs/src/lib/claimBuilder.js +117 -0
- package/dist/cjs/src/lib/errors.d.ts.map +1 -0
- package/dist/cjs/src/lib/errors.js +19 -0
- package/dist/{src → cjs/src}/lib/iface.d.ts +17 -14
- package/dist/cjs/src/lib/iface.d.ts.map +1 -0
- package/dist/cjs/src/lib/iface.js +128 -0
- package/dist/cjs/src/lib/iface_utils.d.ts.map +1 -0
- package/dist/cjs/src/lib/iface_utils.js +92 -0
- package/dist/{src → cjs/src}/lib/index.d.ts +2 -0
- package/dist/cjs/src/lib/index.d.ts.map +1 -0
- package/dist/cjs/src/lib/index.js +73 -0
- package/dist/{src → cjs/src}/lib/keyPair.d.ts +7 -0
- package/dist/cjs/src/lib/keyPair.d.ts.map +1 -0
- package/dist/cjs/src/lib/keyPair.js +117 -0
- package/dist/cjs/src/lib/nativeTransferBuilder.d.ts.map +1 -0
- package/dist/cjs/src/lib/nativeTransferBuilder.js +219 -0
- package/dist/cjs/src/lib/proxyBuilder.d.ts.map +1 -0
- package/dist/cjs/src/lib/proxyBuilder.js +116 -0
- package/dist/cjs/src/lib/singletonRegistry.d.ts.map +1 -0
- package/dist/cjs/src/lib/singletonRegistry.js +20 -0
- package/dist/cjs/src/lib/stakingBuilder.d.ts.map +1 -0
- package/dist/cjs/src/lib/stakingBuilder.js +167 -0
- package/dist/{src → cjs/src}/lib/transaction.d.ts +0 -1
- package/dist/cjs/src/lib/transaction.d.ts.map +1 -0
- package/dist/cjs/src/lib/transaction.js +624 -0
- package/dist/{src → cjs/src}/lib/transactionBuilder.d.ts +0 -1
- package/dist/cjs/src/lib/transactionBuilder.d.ts.map +1 -0
- package/dist/cjs/src/lib/transactionBuilder.js +351 -0
- package/dist/cjs/src/lib/transactionBuilderFactory.d.ts.map +1 -0
- package/dist/cjs/src/lib/transactionBuilderFactory.js +104 -0
- package/dist/cjs/src/lib/transferBuilder.d.ts.map +1 -0
- package/dist/cjs/src/lib/transferBuilder.js +11 -0
- package/dist/cjs/src/lib/txnSchema.d.ts.map +1 -0
- package/dist/cjs/src/lib/txnSchema.js +117 -0
- package/dist/cjs/src/lib/unnominateBuilder.d.ts.map +1 -0
- package/dist/cjs/src/lib/unnominateBuilder.js +48 -0
- package/dist/cjs/src/lib/unstakeBuilder.d.ts.map +1 -0
- package/dist/cjs/src/lib/unstakeBuilder.js +87 -0
- package/dist/{src → cjs/src}/lib/utils.d.ts +10 -2
- package/dist/cjs/src/lib/utils.d.ts.map +1 -0
- package/dist/cjs/src/lib/utils.js +491 -0
- package/dist/cjs/src/lib/wasmParser.d.ts +57 -0
- package/dist/cjs/src/lib/wasmParser.d.ts.map +1 -0
- package/dist/cjs/src/lib/wasmParser.js +345 -0
- package/dist/cjs/src/lib/withdrawUnstakedBuilder.d.ts.map +1 -0
- package/dist/cjs/src/lib/withdrawUnstakedBuilder.js +88 -0
- package/dist/cjs/src/register.d.ts.map +1 -0
- package/dist/cjs/src/register.js +11 -0
- package/dist/cjs/src/resources/index.d.ts +5 -0
- package/dist/cjs/src/resources/index.d.ts.map +1 -0
- package/dist/cjs/src/resources/index.js +21 -0
- package/dist/cjs/src/resources/mainnet.d.ts +2 -0
- package/dist/cjs/src/resources/mainnet.d.ts.map +1 -0
- package/dist/cjs/src/resources/mainnet.js +5 -0
- package/dist/cjs/src/resources/polkadotAssetHub.d.ts +2 -0
- package/dist/cjs/src/resources/polkadotAssetHub.d.ts.map +1 -0
- package/dist/cjs/src/resources/polkadotAssetHub.js +5 -0
- package/dist/cjs/src/resources/westend.d.ts +2 -0
- package/dist/cjs/src/resources/westend.d.ts.map +1 -0
- package/dist/cjs/src/resources/westend.js +5 -0
- package/dist/cjs/src/resources/westendAssetHub.d.ts +2 -0
- package/dist/cjs/src/resources/westendAssetHub.d.ts.map +1 -0
- package/dist/cjs/src/resources/westendAssetHub.js +5 -0
- package/dist/cjs/src/tdot.d.ts.map +1 -0
- package/dist/cjs/src/tdot.js +27 -0
- package/dist/cjs/test/fixtures.d.ts +283 -0
- package/dist/cjs/test/fixtures.d.ts.map +1 -0
- package/dist/cjs/test/fixtures.js +439 -0
- package/dist/cjs/test/resources/index.d.ts +141 -0
- package/dist/cjs/test/resources/index.d.ts.map +1 -0
- package/dist/cjs/test/resources/index.js +157 -0
- package/dist/cjs/test/resources/materialData.json +8 -0
- package/dist/cjs/test/resources/materialDataModified.json +8 -0
- package/dist/cjs/test/resources/testnet.d.ts +2 -0
- package/dist/cjs/test/resources/testnet.d.ts.map +1 -0
- package/dist/cjs/test/resources/testnet.js +5 -0
- package/dist/cjs/test/unit/address.d.ts +2 -0
- package/dist/cjs/test/unit/address.d.ts.map +1 -0
- package/dist/cjs/test/unit/address.js +45 -0
- package/dist/cjs/test/unit/dot.d.ts +2 -0
- package/dist/cjs/test/unit/dot.d.ts.map +1 -0
- package/dist/cjs/test/unit/dot.js +1314 -0
- package/dist/cjs/test/unit/keypair.d.ts +2 -0
- package/dist/cjs/test/unit/keypair.d.ts.map +1 -0
- package/dist/cjs/test/unit/keypair.js +111 -0
- package/dist/cjs/test/unit/transaction.d.ts +2 -0
- package/dist/cjs/test/unit/transaction.d.ts.map +1 -0
- package/dist/cjs/test/unit/transaction.js +269 -0
- package/dist/cjs/test/unit/transactionBuilder/addressInitializationBuilder.d.ts +2 -0
- package/dist/cjs/test/unit/transactionBuilder/addressInitializationBuilder.d.ts.map +1 -0
- package/dist/cjs/test/unit/transactionBuilder/addressInitializationBuilder.js +265 -0
- package/dist/cjs/test/unit/transactionBuilder/base.d.ts +8 -0
- package/dist/cjs/test/unit/transactionBuilder/base.d.ts.map +1 -0
- package/dist/cjs/test/unit/transactionBuilder/base.js +233 -0
- package/dist/cjs/test/unit/transactionBuilder/batchTransactionBuilder.d.ts +2 -0
- package/dist/cjs/test/unit/transactionBuilder/batchTransactionBuilder.d.ts.map +1 -0
- package/dist/cjs/test/unit/transactionBuilder/batchTransactionBuilder.js +521 -0
- package/dist/cjs/test/unit/transactionBuilder/claimBuilder.d.ts +2 -0
- package/dist/cjs/test/unit/transactionBuilder/claimBuilder.d.ts.map +1 -0
- package/dist/cjs/test/unit/transactionBuilder/claimBuilder.js +129 -0
- package/dist/cjs/test/unit/transactionBuilder/proxyBuilder.d.ts +2 -0
- package/dist/cjs/test/unit/transactionBuilder/proxyBuilder.d.ts.map +1 -0
- package/dist/cjs/test/unit/transactionBuilder/proxyBuilder.js +88 -0
- package/dist/cjs/test/unit/transactionBuilder/singeltonRegistry.d.ts +2 -0
- package/dist/cjs/test/unit/transactionBuilder/singeltonRegistry.d.ts.map +1 -0
- package/dist/cjs/test/unit/transactionBuilder/singeltonRegistry.js +59 -0
- package/dist/cjs/test/unit/transactionBuilder/stakingBuilder.d.ts +2 -0
- package/dist/cjs/test/unit/transactionBuilder/stakingBuilder.d.ts.map +1 -0
- package/dist/cjs/test/unit/transactionBuilder/stakingBuilder.js +235 -0
- package/dist/cjs/test/unit/transactionBuilder/transactionBuilderFactory.d.ts +2 -0
- package/dist/cjs/test/unit/transactionBuilder/transactionBuilderFactory.d.ts.map +1 -0
- package/dist/cjs/test/unit/transactionBuilder/transactionBuilderFactory.js +107 -0
- package/dist/cjs/test/unit/transactionBuilder/transferBuilder.d.ts +2 -0
- package/dist/cjs/test/unit/transactionBuilder/transferBuilder.d.ts.map +1 -0
- package/dist/cjs/test/unit/transactionBuilder/transferBuilder.js +444 -0
- package/dist/cjs/test/unit/transactionBuilder/unnominateBuilder.d.ts +2 -0
- package/dist/cjs/test/unit/transactionBuilder/unnominateBuilder.d.ts.map +1 -0
- package/dist/cjs/test/unit/transactionBuilder/unnominateBuilder.js +97 -0
- package/dist/cjs/test/unit/transactionBuilder/unstakeBuilder.d.ts +2 -0
- package/dist/cjs/test/unit/transactionBuilder/unstakeBuilder.d.ts.map +1 -0
- package/dist/cjs/test/unit/transactionBuilder/unstakeBuilder.js +116 -0
- package/dist/cjs/test/unit/transactionBuilder/withdrawUnstakedBuilder.d.ts +2 -0
- package/dist/cjs/test/unit/transactionBuilder/withdrawUnstakedBuilder.d.ts.map +1 -0
- package/dist/cjs/test/unit/transactionBuilder/withdrawUnstakedBuilder.js +115 -0
- package/dist/cjs/test/unit/utils.d.ts +2 -0
- package/dist/cjs/test/unit/utils.d.ts.map +1 -0
- package/dist/cjs/test/unit/utils.js +117 -0
- package/dist/cjs/test/unit/wasmBuilderByteComparison.d.ts +22 -0
- package/dist/cjs/test/unit/wasmBuilderByteComparison.d.ts.map +1 -0
- package/dist/cjs/test/unit/wasmBuilderByteComparison.js +197 -0
- package/dist/cjs/test/unit/wasmParserExplanation.d.ts +15 -0
- package/dist/cjs/test/unit/wasmParserExplanation.d.ts.map +1 -0
- package/dist/cjs/test/unit/wasmParserExplanation.js +147 -0
- package/dist/cjs/tsconfig.tsbuildinfo +1 -0
- package/dist/esm/dot.d.ts +163 -0
- package/dist/esm/dot.d.ts.map +1 -0
- package/dist/esm/dot.js +648 -0
- package/dist/esm/index.d.ts +5 -0
- package/dist/esm/index.js +5 -0
- package/dist/esm/lib/addressInitializationBuilder.d.ts +79 -0
- package/dist/esm/lib/addressInitializationBuilder.js +175 -0
- package/dist/esm/lib/batchTransactionBuilder.d.ts +62 -0
- package/dist/{src → esm}/lib/batchTransactionBuilder.d.ts.map +1 -1
- package/dist/esm/lib/batchTransactionBuilder.js +222 -0
- package/dist/esm/lib/claimBuilder.d.ts +58 -0
- package/dist/esm/lib/claimBuilder.js +110 -0
- package/dist/esm/lib/errors.d.ts +8 -0
- package/dist/esm/lib/errors.js +14 -0
- package/dist/esm/lib/iface.d.ts +337 -0
- package/dist/esm/lib/iface.d.ts.map +1 -0
- package/dist/esm/lib/iface.js +125 -0
- package/dist/esm/lib/iface_utils.d.ts +59 -0
- package/dist/esm/lib/iface_utils.js +83 -0
- package/dist/esm/lib/index.d.ts +21 -0
- package/dist/{src → esm}/lib/index.d.ts.map +1 -1
- package/dist/esm/lib/index.js +20 -0
- package/dist/esm/lib/keyPair.d.ts +38 -0
- package/dist/esm/lib/keyPair.d.ts.map +1 -0
- package/dist/esm/lib/keyPair.js +77 -0
- package/dist/esm/lib/nativeTransferBuilder.d.ts +84 -0
- package/dist/esm/lib/nativeTransferBuilder.js +212 -0
- package/dist/esm/lib/proxyBuilder.d.ts +54 -0
- package/dist/esm/lib/proxyBuilder.js +109 -0
- package/dist/esm/lib/singletonRegistry.d.ts +7 -0
- package/dist/esm/lib/singletonRegistry.js +16 -0
- package/dist/esm/lib/stakingBuilder.d.ts +66 -0
- package/dist/{src → esm}/lib/stakingBuilder.d.ts.map +1 -1
- package/dist/esm/lib/stakingBuilder.js +160 -0
- package/dist/esm/lib/transaction.d.ts +83 -0
- package/dist/esm/lib/transaction.d.ts.map +1 -0
- package/dist/esm/lib/transaction.js +584 -0
- package/dist/esm/lib/transactionBuilder.d.ts +131 -0
- package/dist/esm/lib/transactionBuilder.d.ts.map +1 -0
- package/dist/esm/lib/transactionBuilder.js +311 -0
- package/dist/esm/lib/transactionBuilderFactory.d.ts +28 -0
- package/dist/esm/lib/transactionBuilderFactory.js +97 -0
- package/dist/esm/lib/transferBuilder.d.ts +11 -0
- package/dist/esm/lib/transferBuilder.js +7 -0
- package/dist/esm/lib/txnSchema.d.ts +15 -0
- package/dist/esm/lib/txnSchema.js +111 -0
- package/dist/esm/lib/unnominateBuilder.d.ts +24 -0
- package/dist/esm/lib/unnominateBuilder.js +44 -0
- package/dist/esm/lib/unstakeBuilder.d.ts +38 -0
- package/dist/esm/lib/unstakeBuilder.js +80 -0
- package/dist/esm/lib/utils.d.ts +261 -0
- package/dist/esm/lib/utils.d.ts.map +1 -0
- package/dist/esm/lib/utils.js +451 -0
- package/dist/esm/lib/wasmParser.d.ts +57 -0
- package/dist/esm/lib/wasmParser.d.ts.map +1 -0
- package/dist/esm/lib/wasmParser.js +341 -0
- package/dist/esm/lib/withdrawUnstakedBuilder.d.ts +38 -0
- package/dist/esm/lib/withdrawUnstakedBuilder.js +81 -0
- package/dist/esm/register.d.ts +3 -0
- package/dist/esm/register.js +7 -0
- package/dist/esm/resources/index.d.ts +5 -0
- package/dist/esm/resources/index.d.ts.map +1 -0
- package/dist/esm/resources/index.js +5 -0
- package/dist/esm/resources/mainnet.d.ts +2 -0
- package/dist/esm/resources/mainnet.d.ts.map +1 -0
- package/dist/esm/resources/mainnet.js +2 -0
- package/dist/esm/resources/polkadotAssetHub.d.ts +2 -0
- package/dist/esm/resources/polkadotAssetHub.d.ts.map +1 -0
- package/dist/esm/resources/polkadotAssetHub.js +2 -0
- package/dist/esm/resources/westend.d.ts +2 -0
- package/dist/esm/resources/westend.d.ts.map +1 -0
- package/dist/esm/resources/westend.js +2 -0
- package/dist/esm/resources/westendAssetHub.d.ts +2 -0
- package/dist/esm/resources/westendAssetHub.d.ts.map +1 -0
- package/dist/esm/resources/westendAssetHub.js +2 -0
- package/dist/esm/tdot.d.ts +12 -0
- package/dist/esm/tdot.js +23 -0
- package/package.json +43 -20
- package/.eslintignore +0 -5
- package/.mocharc.yml +0 -8
- package/CHANGELOG.md +0 -124
- package/dist/src/dot.d.ts.map +0 -1
- package/dist/src/dot.js +0 -378
- package/dist/src/lib/addressInitializationBuilder.js +0 -184
- package/dist/src/lib/batchTransactionBuilder.js +0 -221
- package/dist/src/lib/claimBuilder.js +0 -119
- package/dist/src/lib/errors.js +0 -19
- package/dist/src/lib/iface.d.ts.map +0 -1
- package/dist/src/lib/iface.js +0 -128
- package/dist/src/lib/iface_utils.js +0 -93
- package/dist/src/lib/index.js +0 -57
- package/dist/src/lib/keyPair.d.ts.map +0 -1
- package/dist/src/lib/keyPair.js +0 -70
- package/dist/src/lib/nativeTransferBuilder.js +0 -221
- package/dist/src/lib/proxyBuilder.js +0 -118
- package/dist/src/lib/singletonRegistry.js +0 -20
- package/dist/src/lib/stakingBuilder.js +0 -170
- package/dist/src/lib/transaction.d.ts.map +0 -1
- package/dist/src/lib/transaction.js +0 -590
- package/dist/src/lib/transactionBuilder.d.ts.map +0 -1
- package/dist/src/lib/transactionBuilder.js +0 -337
- package/dist/src/lib/transactionBuilderFactory.js +0 -105
- package/dist/src/lib/transferBuilder.js +0 -11
- package/dist/src/lib/txnSchema.js +0 -117
- package/dist/src/lib/unnominateBuilder.js +0 -50
- package/dist/src/lib/unstakeBuilder.js +0 -89
- package/dist/src/lib/utils.d.ts.map +0 -1
- package/dist/src/lib/utils.js +0 -460
- package/dist/src/lib/withdrawUnstakedBuilder.js +0 -90
- package/dist/src/register.js +0 -11
- package/dist/src/tdot.js +0 -27
- /package/dist/{src → cjs/src}/index.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/addressInitializationBuilder.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/claimBuilder.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/errors.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/iface_utils.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/nativeTransferBuilder.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/proxyBuilder.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/singletonRegistry.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/stakingBuilder.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/transactionBuilderFactory.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/transferBuilder.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/txnSchema.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/unnominateBuilder.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/unstakeBuilder.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/withdrawUnstakedBuilder.d.ts +0 -0
- /package/dist/{src → cjs/src}/register.d.ts +0 -0
- /package/dist/{src → cjs/src}/tdot.d.ts +0 -0
- /package/dist/{src → esm}/index.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/addressInitializationBuilder.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/claimBuilder.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/errors.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/iface_utils.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/nativeTransferBuilder.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/proxyBuilder.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/singletonRegistry.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/transactionBuilderFactory.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/transferBuilder.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/txnSchema.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/unnominateBuilder.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/unstakeBuilder.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/withdrawUnstakedBuilder.d.ts.map +0 -0
- /package/dist/{src → esm}/register.d.ts.map +0 -0
- /package/dist/{src → esm}/tdot.d.ts.map +0 -0
|
@@ -0,0 +1,688 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.Dot = exports.DEFAULT_SCAN_FACTOR = void 0;
|
|
40
|
+
const assert_1 = __importDefault(require("assert"));
|
|
41
|
+
const _ = __importStar(require("lodash"));
|
|
42
|
+
const sdk_core_1 = require("@bitgo-beta/sdk-core");
|
|
43
|
+
const statics_1 = require("@bitgo-beta/statics");
|
|
44
|
+
const lib_1 = require("./lib");
|
|
45
|
+
require("@polkadot/api-augment");
|
|
46
|
+
const api_1 = require("@polkadot/api");
|
|
47
|
+
const bignumber_js_1 = __importDefault(require("bignumber.js"));
|
|
48
|
+
const sdk_lib_mpc_1 = require("@bitgo-beta/sdk-lib-mpc");
|
|
49
|
+
const tweetnacl_1 = __importDefault(require("tweetnacl"));
|
|
50
|
+
exports.DEFAULT_SCAN_FACTOR = 20; // default number of receive addresses to scan for funds
|
|
51
|
+
const dotUtils = lib_1.Utils.default;
|
|
52
|
+
function isEddsaSigningMaterial(value) {
|
|
53
|
+
if (typeof value !== 'object' || value === null) {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
if (!('version' in value)) {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
if (value.version === 'v1') {
|
|
60
|
+
return 'userPrv' in value && typeof value.userPrv === 'string';
|
|
61
|
+
}
|
|
62
|
+
if (value.version === 'v2') {
|
|
63
|
+
return 'encryptedUserKey' in value && typeof value.encryptedUserKey === 'string';
|
|
64
|
+
}
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
class Dot extends sdk_core_1.BaseCoin {
|
|
68
|
+
constructor(bitgo, staticsCoin) {
|
|
69
|
+
super(bitgo);
|
|
70
|
+
this.MAX_VALIDITY_DURATION = 2400;
|
|
71
|
+
this.SWEEP_TXN_DURATION = 64;
|
|
72
|
+
if (!staticsCoin) {
|
|
73
|
+
throw new Error('missing required constructor parameter staticsCoin');
|
|
74
|
+
}
|
|
75
|
+
this._staticsCoin = staticsCoin;
|
|
76
|
+
}
|
|
77
|
+
static createInstance(bitgo, staticsCoin) {
|
|
78
|
+
return new Dot(bitgo, staticsCoin);
|
|
79
|
+
}
|
|
80
|
+
getChain() {
|
|
81
|
+
return 'dot';
|
|
82
|
+
}
|
|
83
|
+
getBaseChain() {
|
|
84
|
+
return 'dot';
|
|
85
|
+
}
|
|
86
|
+
getFamily() {
|
|
87
|
+
return 'dot';
|
|
88
|
+
}
|
|
89
|
+
getFullName() {
|
|
90
|
+
return 'Polkadot';
|
|
91
|
+
}
|
|
92
|
+
getBaseFactor() {
|
|
93
|
+
return Math.pow(10, this._staticsCoin.decimalPlaces);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Flag for sending value of 0
|
|
97
|
+
* @returns {boolean} True if okay to send 0 value, false otherwise
|
|
98
|
+
*/
|
|
99
|
+
valuelessTransferAllowed() {
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
/** @inheritDoc */
|
|
103
|
+
supportsTss() {
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
/** inherited doc */
|
|
107
|
+
getDefaultMultisigType() {
|
|
108
|
+
return sdk_core_1.multisigTypes.tss;
|
|
109
|
+
}
|
|
110
|
+
getMPCAlgorithm() {
|
|
111
|
+
return 'eddsa';
|
|
112
|
+
}
|
|
113
|
+
allowsAccountConsolidations() {
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Generate ed25519 key pair
|
|
118
|
+
*
|
|
119
|
+
* @param seed
|
|
120
|
+
* @returns {Object} object with generated pub, prv
|
|
121
|
+
*/
|
|
122
|
+
generateKeyPair(seed) {
|
|
123
|
+
const keyPair = seed ? dotUtils.keyPairFromSeed(new Uint8Array(seed)) : new lib_1.KeyPair();
|
|
124
|
+
const keys = keyPair.getKeys();
|
|
125
|
+
if (!keys.prv) {
|
|
126
|
+
throw new Error('Missing prv in key generation.');
|
|
127
|
+
}
|
|
128
|
+
return {
|
|
129
|
+
pub: keys.pub,
|
|
130
|
+
prv: keys.prv,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Return boolean indicating whether input is valid public key for the coin.
|
|
135
|
+
*
|
|
136
|
+
* @param {String} pub the pub to be checked
|
|
137
|
+
* @returns {Boolean} is it valid?
|
|
138
|
+
*/
|
|
139
|
+
isValidPub(pub) {
|
|
140
|
+
return dotUtils.isValidPublicKey(pub);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Return boolean indicating whether the supplied private key is a valid dot private key
|
|
144
|
+
*
|
|
145
|
+
* @param {String} prv the prv to be checked
|
|
146
|
+
* @returns {Boolean} is it valid?
|
|
147
|
+
*/
|
|
148
|
+
isValidPrv(prv) {
|
|
149
|
+
return dotUtils.isValidPrivateKey(prv);
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Return boolean indicating whether input is valid public key for the coin
|
|
153
|
+
*
|
|
154
|
+
* @param {String} address the pub to be checked
|
|
155
|
+
* @returns {Boolean} is it valid?
|
|
156
|
+
*/
|
|
157
|
+
isValidAddress(address) {
|
|
158
|
+
return dotUtils.isValidAddress(address);
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Sign message with private key
|
|
162
|
+
*
|
|
163
|
+
* @param key
|
|
164
|
+
* @param message
|
|
165
|
+
* @return {Buffer} A signature over the given message using the given key
|
|
166
|
+
*/
|
|
167
|
+
async signMessage(key, message) {
|
|
168
|
+
const msg = Buffer.isBuffer(message) ? message.toString('utf8') : message;
|
|
169
|
+
// reconstitute keys and sign
|
|
170
|
+
return Buffer.from(new lib_1.KeyPair({ prv: key.prv }).signMessage(msg));
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Explain/parse transaction
|
|
174
|
+
* @param unsignedTransaction
|
|
175
|
+
*/
|
|
176
|
+
async explainTransaction(unsignedTransaction) {
|
|
177
|
+
let outputAmount = 0;
|
|
178
|
+
unsignedTransaction.parsedTx.outputs.forEach((o) => {
|
|
179
|
+
outputAmount += parseInt(o.valueString, 10);
|
|
180
|
+
});
|
|
181
|
+
const explanationResult = {
|
|
182
|
+
displayOrder: [
|
|
183
|
+
'outputAmount',
|
|
184
|
+
'changeAmount',
|
|
185
|
+
'outputs',
|
|
186
|
+
'changeOutputs',
|
|
187
|
+
'fee',
|
|
188
|
+
'type',
|
|
189
|
+
'sequenceId',
|
|
190
|
+
'id',
|
|
191
|
+
'blockNumber',
|
|
192
|
+
],
|
|
193
|
+
sequenceId: unsignedTransaction.parsedTx.sequenceId,
|
|
194
|
+
fee: unsignedTransaction.feeInfo?.feeString,
|
|
195
|
+
id: unsignedTransaction.parsedTx.id,
|
|
196
|
+
type: unsignedTransaction.parsedTx.type,
|
|
197
|
+
outputs: unsignedTransaction.parsedTx.outputs,
|
|
198
|
+
blockNumber: unsignedTransaction.coinSpecific?.blockNumber,
|
|
199
|
+
outputAmount: outputAmount,
|
|
200
|
+
changeOutputs: [],
|
|
201
|
+
changeAmount: '0',
|
|
202
|
+
};
|
|
203
|
+
return explanationResult;
|
|
204
|
+
}
|
|
205
|
+
verifySignTransactionParams(params) {
|
|
206
|
+
const prv = params.prv;
|
|
207
|
+
const txHex = params.txPrebuild.txHex;
|
|
208
|
+
if (!txHex) {
|
|
209
|
+
throw new Error('missing txPrebuild parameter');
|
|
210
|
+
}
|
|
211
|
+
if (!_.isString(txHex)) {
|
|
212
|
+
throw new Error(`txPrebuild must be an object, got type ${typeof txHex}`);
|
|
213
|
+
}
|
|
214
|
+
if (!prv) {
|
|
215
|
+
throw new Error('missing prv parameter to sign transaction');
|
|
216
|
+
}
|
|
217
|
+
if (!_.isString(prv)) {
|
|
218
|
+
throw new Error(`prv must be a string, got type ${typeof prv}`);
|
|
219
|
+
}
|
|
220
|
+
if (!_.has(params, 'pubs')) {
|
|
221
|
+
throw new Error('missing public key parameter to sign transaction');
|
|
222
|
+
}
|
|
223
|
+
return { txHex, prv };
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Assemble keychain and half-sign prebuilt transaction
|
|
227
|
+
*
|
|
228
|
+
* @param params
|
|
229
|
+
* @param params.txPrebuild {TransactionPrebuild} prebuild object returned by platform
|
|
230
|
+
* @param params.prv {String} user prv
|
|
231
|
+
* @returns {Promise<SignedTransaction>}
|
|
232
|
+
*/
|
|
233
|
+
async signTransaction(params) {
|
|
234
|
+
const { txHex, prv } = this.verifySignTransactionParams(params);
|
|
235
|
+
const factory = this.getBuilder();
|
|
236
|
+
const txBuilder = factory.from(txHex);
|
|
237
|
+
const keyPair = new lib_1.KeyPair({ prv: prv });
|
|
238
|
+
const { referenceBlock, blockNumber, transactionVersion, sender } = params.txPrebuild.transaction;
|
|
239
|
+
txBuilder
|
|
240
|
+
.validity({ firstValid: blockNumber, maxDuration: this.MAX_VALIDITY_DURATION })
|
|
241
|
+
.referenceBlock(referenceBlock)
|
|
242
|
+
.version(transactionVersion)
|
|
243
|
+
.sender({ address: sender })
|
|
244
|
+
.sign({ key: keyPair.getKeys().prv });
|
|
245
|
+
const transaction = await txBuilder.build();
|
|
246
|
+
if (!transaction) {
|
|
247
|
+
throw new Error('Invalid transaction');
|
|
248
|
+
}
|
|
249
|
+
const signedTxHex = transaction.toBroadcastFormat();
|
|
250
|
+
return { txHex: signedTxHex };
|
|
251
|
+
}
|
|
252
|
+
async getInitializedNodeAPI() {
|
|
253
|
+
if (!Dot.nodeApiInitialized) {
|
|
254
|
+
const wsProvider = new api_1.WsProvider(sdk_core_1.Environments[this.bitgo.getEnv()].dotNodeUrls);
|
|
255
|
+
Dot.API = await api_1.ApiPromise.create({ provider: wsProvider });
|
|
256
|
+
Dot.nodeApiInitialized = true;
|
|
257
|
+
}
|
|
258
|
+
return Dot.API;
|
|
259
|
+
}
|
|
260
|
+
async getAccountInfo(walletAddr) {
|
|
261
|
+
const api = await this.getInitializedNodeAPI();
|
|
262
|
+
const { nonce, data: balance } = await api.query.system.account(walletAddr);
|
|
263
|
+
return { nonce: nonce.toNumber(), freeBalance: balance.free.toNumber() };
|
|
264
|
+
}
|
|
265
|
+
async getHeaderInfo() {
|
|
266
|
+
const api = await this.getInitializedNodeAPI();
|
|
267
|
+
const finalizedHash = await api.rpc.chain.getFinalizedHead();
|
|
268
|
+
const { number, hash } = await api.rpc.chain.getHeader(finalizedHash);
|
|
269
|
+
return { headerNumber: number.toNumber(), headerHash: hash.toString() };
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
*
|
|
273
|
+
* Estimate the fee of the transaction
|
|
274
|
+
*
|
|
275
|
+
* @param {string} destAddr destination wallet address
|
|
276
|
+
* @param {string} srcAddr source wallet address
|
|
277
|
+
* @param {string} amount amount to transfer
|
|
278
|
+
* @returns {number} the estimated fee the transaction will cost
|
|
279
|
+
*
|
|
280
|
+
* @see https://polkadot.js.org/docs/api/cookbook/tx#how-do-i-estimate-the-transaction-fees
|
|
281
|
+
*/
|
|
282
|
+
async getFee(destAddr, srcAddr, amount) {
|
|
283
|
+
const api = await this.getInitializedNodeAPI();
|
|
284
|
+
const info = await api.tx.balances.transferAllowDeath(destAddr, amount).paymentInfo(srcAddr);
|
|
285
|
+
return info.partialFee.toNumber();
|
|
286
|
+
}
|
|
287
|
+
async getMaterial() {
|
|
288
|
+
const api = await this.getInitializedNodeAPI();
|
|
289
|
+
return {
|
|
290
|
+
genesisHash: api.genesisHash.toString(),
|
|
291
|
+
chainName: api.runtimeChain.toString(),
|
|
292
|
+
specName: api.runtimeVersion.specName.toString(),
|
|
293
|
+
specVersion: api.runtimeVersion.specVersion.toNumber(),
|
|
294
|
+
txVersion: api.runtimeVersion.transactionVersion.toNumber(),
|
|
295
|
+
metadata: api.runtimeMetadata.toHex(),
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Builds a funds recovery transaction without BitGo
|
|
300
|
+
* @param {MPCRecoveryOptions} params parameters needed to construct and
|
|
301
|
+
* (maybe) sign the transaction
|
|
302
|
+
* @param {EddsaSigningMaterial} [precomputedMaterial] optional decrypted
|
|
303
|
+
* material from recoverConsolidations; non-matching values are ignored
|
|
304
|
+
*
|
|
305
|
+
* @returns {MPCTx} the serialized transaction hex string and index
|
|
306
|
+
* of the address being swept
|
|
307
|
+
*/
|
|
308
|
+
async recover(params, precomputedMaterial) {
|
|
309
|
+
if (!params.bitgoKey) {
|
|
310
|
+
throw new Error('missing bitgoKey');
|
|
311
|
+
}
|
|
312
|
+
if (!params.recoveryDestination || !this.isValidAddress(params.recoveryDestination)) {
|
|
313
|
+
throw new Error('invalid recoveryDestination');
|
|
314
|
+
}
|
|
315
|
+
const bitgoKey = params.bitgoKey.replace(/\s/g, '');
|
|
316
|
+
const isUnsignedSweep = !params.userKey && !params.backupKey && !params.walletPassphrase;
|
|
317
|
+
const MPC = await sdk_core_1.EDDSAMethods.getInitializedMpcInstance();
|
|
318
|
+
const index = params.index || 0;
|
|
319
|
+
const currPath = params.seed ? (0, sdk_lib_mpc_1.getDerivationPath)(params.seed) + `/${index}` : `m/${index}`;
|
|
320
|
+
const accountId = MPC.deriveUnhardened(bitgoKey, currPath).slice(0, 64);
|
|
321
|
+
const senderAddr = this.getAddressFromPublicKey(accountId);
|
|
322
|
+
let accountInfo;
|
|
323
|
+
let partialFee;
|
|
324
|
+
try {
|
|
325
|
+
accountInfo = await this.getAccountInfo(senderAddr);
|
|
326
|
+
partialFee = await this.getFee(params.recoveryDestination, senderAddr, accountInfo.freeBalance);
|
|
327
|
+
}
|
|
328
|
+
catch (e) {
|
|
329
|
+
throw new sdk_core_1.RecoveryProviderError(`Failed to query account balance or fee for ${senderAddr}`, e);
|
|
330
|
+
}
|
|
331
|
+
const { nonce, freeBalance } = accountInfo;
|
|
332
|
+
const value = new bignumber_js_1.default(freeBalance).minus(new bignumber_js_1.default(partialFee));
|
|
333
|
+
if (value.isLessThanOrEqualTo(0)) {
|
|
334
|
+
throw new sdk_core_1.ErrorNoInputToRecover('Did not find address with funds to recover');
|
|
335
|
+
}
|
|
336
|
+
// first build the unsigned txn
|
|
337
|
+
let headerInfo;
|
|
338
|
+
let material;
|
|
339
|
+
try {
|
|
340
|
+
headerInfo = await this.getHeaderInfo();
|
|
341
|
+
material = await this.getMaterial();
|
|
342
|
+
}
|
|
343
|
+
catch (e) {
|
|
344
|
+
throw new sdk_core_1.RecoveryProviderError('Failed to query chain header or material', e);
|
|
345
|
+
}
|
|
346
|
+
const { headerNumber, headerHash } = headerInfo;
|
|
347
|
+
const validityWindow = { firstValid: headerNumber, maxDuration: this.MAX_VALIDITY_DURATION };
|
|
348
|
+
const txnBuilder = this.getBuilder().getTransferBuilder().material(material);
|
|
349
|
+
txnBuilder
|
|
350
|
+
.sweep(false)
|
|
351
|
+
.to({ address: params.recoveryDestination })
|
|
352
|
+
.sender({ address: senderAddr })
|
|
353
|
+
.validity(validityWindow)
|
|
354
|
+
.referenceBlock(headerHash)
|
|
355
|
+
.sequenceId({ name: 'Nonce', keyword: 'nonce', value: nonce })
|
|
356
|
+
.fee({ amount: 0, type: 'tip' });
|
|
357
|
+
const unsignedTransaction = (await txnBuilder.build());
|
|
358
|
+
let serializedTx = unsignedTransaction.toBroadcastFormat();
|
|
359
|
+
if (!isUnsignedSweep) {
|
|
360
|
+
(0, assert_1.default)(params.userKey, 'missing userKey');
|
|
361
|
+
(0, assert_1.default)(params.backupKey, 'missing backupKey');
|
|
362
|
+
(0, assert_1.default)(params.walletPassphrase, 'missing wallet passphrase');
|
|
363
|
+
const signingMaterial = isEddsaSigningMaterial(precomputedMaterial)
|
|
364
|
+
? precomputedMaterial
|
|
365
|
+
: await this.getEddsaSigningMaterial(params.userKey, params.walletPassphrase);
|
|
366
|
+
await this.addRecoverySignature(signingMaterial, params.backupKey.replace(/\s/g, ''), params.walletPassphrase, txnBuilder, accountId, unsignedTransaction, currPath, bitgoKey);
|
|
367
|
+
const signedTransaction = await txnBuilder.build();
|
|
368
|
+
serializedTx = signedTransaction.toBroadcastFormat();
|
|
369
|
+
}
|
|
370
|
+
else {
|
|
371
|
+
const value = new bignumber_js_1.default(freeBalance);
|
|
372
|
+
const walletCoin = this.getChain();
|
|
373
|
+
const inputs = [
|
|
374
|
+
{
|
|
375
|
+
address: unsignedTransaction.inputs[0].address,
|
|
376
|
+
valueString: value.toString(),
|
|
377
|
+
value: value.toNumber(),
|
|
378
|
+
},
|
|
379
|
+
];
|
|
380
|
+
const outputs = [
|
|
381
|
+
{
|
|
382
|
+
address: unsignedTransaction.outputs[0].address,
|
|
383
|
+
valueString: value.toString(),
|
|
384
|
+
coinName: walletCoin,
|
|
385
|
+
},
|
|
386
|
+
];
|
|
387
|
+
const spendAmount = value.toString();
|
|
388
|
+
const parsedTx = { inputs: inputs, outputs: outputs, spendAmount: spendAmount, type: '' };
|
|
389
|
+
const feeInfo = { fee: 0, feeString: '0' };
|
|
390
|
+
const transaction = {
|
|
391
|
+
serializedTx: serializedTx,
|
|
392
|
+
scanIndex: index,
|
|
393
|
+
coin: walletCoin,
|
|
394
|
+
signableHex: unsignedTransaction.signablePayload.toString('hex'),
|
|
395
|
+
derivationPath: currPath,
|
|
396
|
+
parsedTx: parsedTx,
|
|
397
|
+
feeInfo: feeInfo,
|
|
398
|
+
coinSpecific: { ...validityWindow, commonKeychain: bitgoKey },
|
|
399
|
+
};
|
|
400
|
+
const unsignedTx = { unsignedTx: transaction, signatureShares: [] };
|
|
401
|
+
const transactions = [unsignedTx];
|
|
402
|
+
const txRequest = {
|
|
403
|
+
transactions: transactions,
|
|
404
|
+
walletCoin: walletCoin,
|
|
405
|
+
};
|
|
406
|
+
const txRequests = { txRequests: [txRequest] };
|
|
407
|
+
return txRequests;
|
|
408
|
+
}
|
|
409
|
+
const transaction = { serializedTx: serializedTx, scanIndex: index };
|
|
410
|
+
return transaction;
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* Builds native DOT recoveries of receive addresses in batch without BitGo.
|
|
414
|
+
* Funds will be recovered to base address first. You need to initiate another sweep txn after that.
|
|
415
|
+
*
|
|
416
|
+
* @param {MPCConsolidationRecoveryOptions} params - options for consolidation recovery.
|
|
417
|
+
* @param {string} [params.startingScanIndex] - receive address index to start scanning from. default to 1 (inclusive).
|
|
418
|
+
* @param {string} [params.endingScanIndex] - receive address index to end scanning at. default to startingScanIndex + 20 (exclusive).
|
|
419
|
+
*/
|
|
420
|
+
async recoverConsolidations(params) {
|
|
421
|
+
const isUnsignedSweep = !params.userKey && !params.backupKey && !params.walletPassphrase;
|
|
422
|
+
const startIdx = params.startingScanIndex || 1;
|
|
423
|
+
const endIdx = params.endingScanIndex || startIdx + exports.DEFAULT_SCAN_FACTOR;
|
|
424
|
+
if (startIdx < 1 || endIdx <= startIdx || endIdx - startIdx > 10 * exports.DEFAULT_SCAN_FACTOR) {
|
|
425
|
+
throw new Error(`Invalid starting or ending index to scan for addresses. startingScanIndex: ${startIdx}, endingScanIndex: ${endIdx}.`);
|
|
426
|
+
}
|
|
427
|
+
const bitgoKey = params.bitgoKey.replace(/\s/g, '');
|
|
428
|
+
const MPC = await sdk_core_1.EDDSAMethods.getInitializedMpcInstance();
|
|
429
|
+
const baseIndex = 0;
|
|
430
|
+
const basePath = params.seed ? (0, sdk_lib_mpc_1.getDerivationPath)(params.seed) + `/${baseIndex}` : `m/${baseIndex}`;
|
|
431
|
+
const accountId = MPC.deriveUnhardened(bitgoKey, basePath).slice(0, 64);
|
|
432
|
+
const baseAddress = this.getAddressFromPublicKey(accountId);
|
|
433
|
+
// Detect signing material once to avoid re-decrypting the keycard on every loop iteration.
|
|
434
|
+
const signingMaterial = params.walletPassphrase && params.userKey
|
|
435
|
+
? await this.getEddsaSigningMaterial(params.userKey.replace(/\s/g, ''), params.walletPassphrase)
|
|
436
|
+
: undefined;
|
|
437
|
+
const consolidationTransactions = [];
|
|
438
|
+
let lastScanIndex = startIdx;
|
|
439
|
+
for (let i = startIdx; i < endIdx; i++) {
|
|
440
|
+
const recoverParams = {
|
|
441
|
+
userKey: params.userKey,
|
|
442
|
+
backupKey: params.backupKey,
|
|
443
|
+
bitgoKey: params.bitgoKey,
|
|
444
|
+
walletPassphrase: params.walletPassphrase,
|
|
445
|
+
recoveryDestination: baseAddress,
|
|
446
|
+
seed: params.seed,
|
|
447
|
+
index: i,
|
|
448
|
+
};
|
|
449
|
+
let recoveryTransaction;
|
|
450
|
+
try {
|
|
451
|
+
recoveryTransaction = await this.recover(recoverParams, signingMaterial);
|
|
452
|
+
}
|
|
453
|
+
catch (e) {
|
|
454
|
+
if (e instanceof sdk_core_1.ErrorNoInputToRecover) {
|
|
455
|
+
lastScanIndex = i;
|
|
456
|
+
continue;
|
|
457
|
+
}
|
|
458
|
+
throw e;
|
|
459
|
+
}
|
|
460
|
+
if (isUnsignedSweep) {
|
|
461
|
+
consolidationTransactions.push(recoveryTransaction.txRequests[0]);
|
|
462
|
+
}
|
|
463
|
+
else {
|
|
464
|
+
consolidationTransactions.push(recoveryTransaction);
|
|
465
|
+
}
|
|
466
|
+
lastScanIndex = i;
|
|
467
|
+
}
|
|
468
|
+
if (consolidationTransactions.length == 0) {
|
|
469
|
+
throw new sdk_core_1.ErrorNoInputToRecover('Did not find an address with funds to recover');
|
|
470
|
+
}
|
|
471
|
+
if (isUnsignedSweep) {
|
|
472
|
+
// lastScanIndex will be used to inform user the last address index scanned for available funds (so they can
|
|
473
|
+
// appropriately adjust the scan range on the next iteration of consolidation recoveries). In the case of unsigned
|
|
474
|
+
// sweep consolidations, this lastScanIndex will be provided in the coinSpecific of the last txn made.
|
|
475
|
+
const lastTransactionCoinSpecific = {
|
|
476
|
+
firstValid: consolidationTransactions[consolidationTransactions.length - 1].transactions[0].unsignedTx.coinSpecific
|
|
477
|
+
.firstValid,
|
|
478
|
+
maxDuration: consolidationTransactions[consolidationTransactions.length - 1].transactions[0].unsignedTx.coinSpecific
|
|
479
|
+
.maxDuration,
|
|
480
|
+
commonKeychain: consolidationTransactions[consolidationTransactions.length - 1].transactions[0].unsignedTx.coinSpecific
|
|
481
|
+
.commonKeychain,
|
|
482
|
+
lastScanIndex: lastScanIndex,
|
|
483
|
+
};
|
|
484
|
+
consolidationTransactions[consolidationTransactions.length - 1].transactions[0].unsignedTx.coinSpecific =
|
|
485
|
+
lastTransactionCoinSpecific;
|
|
486
|
+
const consolidationSweepTransactions = { txRequests: consolidationTransactions };
|
|
487
|
+
return consolidationSweepTransactions;
|
|
488
|
+
}
|
|
489
|
+
return { transactions: consolidationTransactions, lastScanIndex };
|
|
490
|
+
}
|
|
491
|
+
/** inherited doc */
|
|
492
|
+
async createBroadcastableSweepTransaction(params) {
|
|
493
|
+
const req = params.signatureShares;
|
|
494
|
+
const broadcastableTransactions = [];
|
|
495
|
+
let lastScanIndex = 0;
|
|
496
|
+
for (let i = 0; i < req.length; i++) {
|
|
497
|
+
const MPC = await sdk_core_1.EDDSAMethods.getInitializedMpcInstance();
|
|
498
|
+
const transaction = req[i].txRequest.transactions[0].unsignedTx;
|
|
499
|
+
const ovc = req[i].ovc?.[0];
|
|
500
|
+
const mpcv2SignatureHex = ovc?.eddsaMpcv2Signature;
|
|
501
|
+
if (!ovc || (!mpcv2SignatureHex && !ovc.eddsaSignature)) {
|
|
502
|
+
throw new Error('Missing signature(s)');
|
|
503
|
+
}
|
|
504
|
+
if (!transaction.signableHex) {
|
|
505
|
+
throw new Error('Missing signable hex');
|
|
506
|
+
}
|
|
507
|
+
const messageBuffer = Buffer.from(transaction.signableHex, 'hex');
|
|
508
|
+
if (!transaction.coinSpecific ||
|
|
509
|
+
!transaction.coinSpecific?.firstValid ||
|
|
510
|
+
!transaction.coinSpecific?.maxDuration) {
|
|
511
|
+
throw new Error('missing validity window');
|
|
512
|
+
}
|
|
513
|
+
const validityWindow = {
|
|
514
|
+
firstValid: transaction.coinSpecific?.firstValid,
|
|
515
|
+
maxDuration: transaction.coinSpecific?.maxDuration,
|
|
516
|
+
};
|
|
517
|
+
const material = await this.getMaterial();
|
|
518
|
+
if (!transaction.coinSpecific?.commonKeychain) {
|
|
519
|
+
throw new Error('Missing common keychain');
|
|
520
|
+
}
|
|
521
|
+
const commonKeychain = transaction.coinSpecific.commonKeychain;
|
|
522
|
+
if (!transaction.derivationPath) {
|
|
523
|
+
throw new Error('Missing derivation path');
|
|
524
|
+
}
|
|
525
|
+
const derivationPath = transaction.derivationPath;
|
|
526
|
+
const accountId = MPC.deriveUnhardened(commonKeychain, derivationPath).slice(0, 64);
|
|
527
|
+
const senderAddr = this.getAddressFromPublicKey(accountId);
|
|
528
|
+
let signatureHex;
|
|
529
|
+
if (mpcv2SignatureHex) {
|
|
530
|
+
// MPCv2 (OVC 5-pass): raw 64-byte Ed25519 signature. Verify against the
|
|
531
|
+
// same derived public key the transaction is signed under, then embed as-is.
|
|
532
|
+
const signature = Buffer.from(mpcv2SignatureHex, 'hex');
|
|
533
|
+
const isValid = tweetnacl_1.default.sign.detached.verify(messageBuffer, signature, Buffer.from(accountId, 'hex'));
|
|
534
|
+
if (!isValid) {
|
|
535
|
+
throw new Error('Invalid signature');
|
|
536
|
+
}
|
|
537
|
+
signatureHex = signature;
|
|
538
|
+
}
|
|
539
|
+
else {
|
|
540
|
+
const result = MPC.verify(messageBuffer, ovc.eddsaSignature);
|
|
541
|
+
if (!result) {
|
|
542
|
+
throw new Error('Invalid signature');
|
|
543
|
+
}
|
|
544
|
+
signatureHex = Buffer.concat([
|
|
545
|
+
Buffer.from(ovc.eddsaSignature.R, 'hex'),
|
|
546
|
+
Buffer.from(ovc.eddsaSignature.sigma, 'hex'),
|
|
547
|
+
]);
|
|
548
|
+
}
|
|
549
|
+
const txnBuilder = this.getBuilder()
|
|
550
|
+
.material(material)
|
|
551
|
+
.from(transaction.serializedTx)
|
|
552
|
+
.sender({ address: senderAddr })
|
|
553
|
+
.validity(validityWindow);
|
|
554
|
+
const dotKeyPair = new lib_1.KeyPair({ pub: accountId });
|
|
555
|
+
txnBuilder.addSignature({ pub: dotKeyPair.getKeys().pub }, signatureHex);
|
|
556
|
+
const signedTransaction = await txnBuilder.build();
|
|
557
|
+
const serializedTx = signedTransaction.toBroadcastFormat();
|
|
558
|
+
broadcastableTransactions.push({
|
|
559
|
+
serializedTx: serializedTx,
|
|
560
|
+
scanIndex: transaction.scanIndex,
|
|
561
|
+
});
|
|
562
|
+
if (i === req.length - 1 && transaction.coinSpecific.lastScanIndex) {
|
|
563
|
+
lastScanIndex = transaction.coinSpecific.lastScanIndex;
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
return { transactions: broadcastableTransactions, lastScanIndex };
|
|
567
|
+
}
|
|
568
|
+
async parseTransaction(params) {
|
|
569
|
+
return {};
|
|
570
|
+
}
|
|
571
|
+
async isWalletAddress(params) {
|
|
572
|
+
return (0, sdk_core_1.verifyEddsaTssWalletAddress)(params, (address) => this.isValidAddress(address), (publicKey) => this.getAddressFromPublicKey(publicKey));
|
|
573
|
+
}
|
|
574
|
+
async verifyTransaction(params) {
|
|
575
|
+
const { txPrebuild, txParams, verification, wallet, reqId } = params;
|
|
576
|
+
if (!txParams) {
|
|
577
|
+
throw new Error('missing txParams');
|
|
578
|
+
}
|
|
579
|
+
if (!txPrebuild) {
|
|
580
|
+
throw new Error('missing txPrebuild');
|
|
581
|
+
}
|
|
582
|
+
if (!txPrebuild.txHex) {
|
|
583
|
+
throw new Error('missing txHex in txPrebuild');
|
|
584
|
+
}
|
|
585
|
+
const chain = this.getChain();
|
|
586
|
+
let txTo;
|
|
587
|
+
let txAmount;
|
|
588
|
+
let isSweep;
|
|
589
|
+
if (chain === 'tdot') {
|
|
590
|
+
const material = lib_1.Utils.default.getMaterial(statics_1.coins.get(chain));
|
|
591
|
+
const explained = (0, lib_1.explainDotTransaction)({ txHex: txPrebuild.txHex, material });
|
|
592
|
+
txTo = explained.outputs[0]?.address ?? '';
|
|
593
|
+
txAmount = String(explained.outputs[0]?.amount ?? '0');
|
|
594
|
+
isSweep = explained.methodName === 'balances.transferAll';
|
|
595
|
+
}
|
|
596
|
+
else {
|
|
597
|
+
const factory = this.getBuilder();
|
|
598
|
+
const txBuilder = factory.from(txPrebuild.txHex);
|
|
599
|
+
txTo = txBuilder['_to'];
|
|
600
|
+
txAmount = txBuilder['_amount'];
|
|
601
|
+
isSweep = txBuilder['_sweepFreeBalance'] === true;
|
|
602
|
+
}
|
|
603
|
+
if (verification?.consolidationToBaseAddress) {
|
|
604
|
+
const baseAddress = wallet?.coinSpecific()?.rootAddress || wallet?.coinSpecific()?.baseAddress;
|
|
605
|
+
if (!baseAddress) {
|
|
606
|
+
throw new Error('Unable to determine base address for consolidation');
|
|
607
|
+
}
|
|
608
|
+
if (txTo !== baseAddress) {
|
|
609
|
+
throw new sdk_core_1.TxIntentMismatchRecipientError(`Transaction destination address ${txTo} does not match wallet base address ${baseAddress}`, reqId, [txParams], txPrebuild.txHex, [{ address: txTo, amount: txAmount }]);
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
if (txParams.recipients !== undefined) {
|
|
613
|
+
if (txParams.recipients.length === 0) {
|
|
614
|
+
throw new Error('missing recipients in txParams');
|
|
615
|
+
}
|
|
616
|
+
if (Array.isArray(txParams.recipients) && txParams.recipients.length > 1) {
|
|
617
|
+
throw new Error(`${this.getChain()} doesn't support sending to more than 1 destination address within a single transaction. Try again, using only a single recipient.`);
|
|
618
|
+
}
|
|
619
|
+
if (txParams.recipients[0].address !== txTo) {
|
|
620
|
+
throw new sdk_core_1.TxIntentMismatchRecipientError(`Recipient address ${txParams.recipients[0].address} does not match transaction destination address ${txTo}`, reqId, [txParams], txPrebuild.txHex, [{ address: txTo, amount: txAmount }]);
|
|
621
|
+
}
|
|
622
|
+
if (!isSweep && txParams.recipients[0].amount !== txAmount) {
|
|
623
|
+
throw new sdk_core_1.TxIntentMismatchRecipientError(`Recipient amount ${txParams.recipients[0].amount} does not match transaction amount ${txAmount}`, reqId, [txParams], txPrebuild.txHex, [{ address: txTo, amount: txAmount }]);
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
return true;
|
|
627
|
+
}
|
|
628
|
+
getAddressFromPublicKey(Pubkey) {
|
|
629
|
+
return new lib_1.KeyPair({ pub: Pubkey }).getAddress(lib_1.Utils.default.getAddressFormat(this.getChain()));
|
|
630
|
+
}
|
|
631
|
+
getBuilder() {
|
|
632
|
+
return new lib_1.TransactionBuilderFactory(statics_1.coins.get(this.getChain()));
|
|
633
|
+
}
|
|
634
|
+
/**
|
|
635
|
+
* Detects whether a keycard's decrypted plaintext is MPCv1 JSON or MPCv2 CBOR.
|
|
636
|
+
* Unsigned sweeps (no walletPassphrase) have no keycard to inspect and default to MPCv1.
|
|
637
|
+
*/
|
|
638
|
+
async getEddsaSigningMaterial(userKey, walletPassphrase) {
|
|
639
|
+
return (0, sdk_core_1.getEddsaSigningMaterial)(userKey.replace(/\s/g, ''), walletPassphrase, this.bitgo);
|
|
640
|
+
}
|
|
641
|
+
async signDotMpcV2Recovery(params) {
|
|
642
|
+
return (0, sdk_core_1.signEddsaMpcV2RecoveryTx)(params);
|
|
643
|
+
}
|
|
644
|
+
/**
|
|
645
|
+
* Adds an MPCv1 or MPCv2 signature to a DOT transaction builder.
|
|
646
|
+
*
|
|
647
|
+
* Transaction#constructSignedPayload already prepends the 0x00 type-tag (the Substrate
|
|
648
|
+
* MultiSignature enum discriminant for Ed25519) to whatever signature buffer is passed to
|
|
649
|
+
* addSignature, so both paths here hand off the raw 64-byte signature untouched.
|
|
650
|
+
*/
|
|
651
|
+
async addRecoverySignature(signingMaterial, backupKey, walletPassphrase, txnBuilder, accountId, unsignedTransaction, currPath, bitgoKey) {
|
|
652
|
+
const dotKeyPair = new lib_1.KeyPair({ pub: accountId });
|
|
653
|
+
if (signingMaterial.version === 'v2') {
|
|
654
|
+
const rawSig = await this.signDotMpcV2Recovery({
|
|
655
|
+
message: unsignedTransaction.signablePayload,
|
|
656
|
+
userKey: signingMaterial.encryptedUserKey,
|
|
657
|
+
backupKey,
|
|
658
|
+
walletPassphrase,
|
|
659
|
+
bitgoKey,
|
|
660
|
+
derivationPath: currPath,
|
|
661
|
+
bitgo: this.bitgo,
|
|
662
|
+
});
|
|
663
|
+
txnBuilder.addSignature({ pub: dotKeyPair.getKeys().pub }, rawSig);
|
|
664
|
+
}
|
|
665
|
+
else {
|
|
666
|
+
/** TODO BG-52419 Implement Codec for parsing */
|
|
667
|
+
const userSigningMaterial = JSON.parse(signingMaterial.userPrv);
|
|
668
|
+
const backupPrv = await (0, sdk_core_1.decryptKeychainPrivateKey)(this.bitgo, { encryptedPrv: backupKey }, walletPassphrase);
|
|
669
|
+
if (!backupPrv) {
|
|
670
|
+
throw new Error('Error decrypting backup keychain: invalid password or corrupted key');
|
|
671
|
+
}
|
|
672
|
+
const backupSigningMaterial = JSON.parse(backupPrv);
|
|
673
|
+
const signatureHex = await sdk_core_1.EDDSAMethods.getTSSSignature(userSigningMaterial, backupSigningMaterial, currPath, unsignedTransaction);
|
|
674
|
+
txnBuilder.addSignature({ pub: dotKeyPair.getKeys().pub }, signatureHex);
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
/** @inheritDoc */
|
|
678
|
+
auditDecryptedKey({ publicKey, prv, multiSigType }) {
|
|
679
|
+
if (multiSigType !== 'tss') {
|
|
680
|
+
throw new Error('Unsupported multiSigType');
|
|
681
|
+
}
|
|
682
|
+
(0, sdk_lib_mpc_1.auditEddsaPrivateKey)(prv, publicKey ?? '');
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
exports.Dot = Dot;
|
|
686
|
+
Dot.initialized = false;
|
|
687
|
+
Dot.nodeApiInitialized = false;
|
|
688
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG90LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2RvdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxvREFBNEI7QUFDNUIsMENBQTRCO0FBQzVCLG1EQXFDOEI7QUFDOUIsaURBQStGO0FBQy9GLCtCQVFlO0FBQ2YsaUNBQStCO0FBQy9CLHVDQUF1RDtBQUV2RCxnRUFBcUM7QUFDckMseURBQWtGO0FBQ2xGLDBEQUE2QjtBQUVoQixRQUFBLG1CQUFtQixHQUFHLEVBQUUsQ0FBQyxDQUFDLHdEQUF3RDtBQWlCL0YsTUFBTSxRQUFRLEdBQUcsV0FBSyxDQUFDLE9BQU8sQ0FBQztBQUUvQixTQUFTLHNCQUFzQixDQUFDLEtBQWM7SUFDNUMsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLElBQUksS0FBSyxLQUFLLElBQUksRUFBRSxDQUFDO1FBQ2hELE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUNELElBQUksQ0FBQyxDQUFDLFNBQVMsSUFBSSxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQzFCLE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUNELElBQUksS0FBSyxDQUFDLE9BQU8sS0FBSyxJQUFJLEVBQUUsQ0FBQztRQUMzQixPQUFPLFNBQVMsSUFBSSxLQUFLLElBQUksT0FBTyxLQUFLLENBQUMsT0FBTyxLQUFLLFFBQVEsQ0FBQztJQUNqRSxDQUFDO0lBQ0QsSUFBSSxLQUFLLENBQUMsT0FBTyxLQUFLLElBQUksRUFBRSxDQUFDO1FBQzNCLE9BQU8sa0JBQWtCLElBQUksS0FBSyxJQUFJLE9BQU8sS0FBSyxDQUFDLGdCQUFnQixLQUFLLFFBQVEsQ0FBQztJQUNuRixDQUFDO0lBQ0QsT0FBTyxLQUFLLENBQUM7QUFDZixDQUFDO0FBRUQsTUFBYSxHQUFJLFNBQVEsbUJBQVE7SUFLL0IsWUFBWSxLQUFnQixFQUFFLFdBQXVDO1FBQ25FLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUpOLDBCQUFxQixHQUFHLElBQUksQ0FBQztRQUM3Qix1QkFBa0IsR0FBRyxFQUFFLENBQUM7UUFLL0IsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ2pCLE1BQU0sSUFBSSxLQUFLLENBQUMsb0RBQW9ELENBQUMsQ0FBQztRQUN4RSxDQUFDO1FBRUQsSUFBSSxDQUFDLFlBQVksR0FBRyxXQUFXLENBQUM7SUFDbEMsQ0FBQztJQU9ELE1BQU0sQ0FBQyxjQUFjLENBQUMsS0FBZ0IsRUFBRSxXQUF1QztRQUM3RSxPQUFPLElBQUksR0FBRyxDQUFDLEtBQUssRUFBRSxXQUFXLENBQUMsQ0FBQztJQUNyQyxDQUFDO0lBRUQsUUFBUTtRQUNOLE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVELFlBQVk7UUFDVixPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFRCxTQUFTO1FBQ1AsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRUQsV0FBVztRQUNULE9BQU8sVUFBVSxDQUFDO0lBQ3BCLENBQUM7SUFFRCxhQUFhO1FBQ1gsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxJQUFJLENBQUMsWUFBWSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQ3ZELENBQUM7SUFFRDs7O09BR0c7SUFDSCx3QkFBd0I7UUFDdEIsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsa0JBQWtCO0lBQ2xCLFdBQVc7UUFDVCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxvQkFBb0I7SUFDcEIsc0JBQXNCO1FBQ3BCLE9BQU8sd0JBQWEsQ0FBQyxHQUFHLENBQUM7SUFDM0IsQ0FBQztJQUVELGVBQWU7UUFDYixPQUFPLE9BQU8sQ0FBQztJQUNqQixDQUFDO0lBRUQsMkJBQTJCO1FBQ3pCLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsZUFBZSxDQUFDLElBQWE7UUFDM0IsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsZUFBZSxDQUFDLElBQUksVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksYUFBVSxFQUFFLENBQUM7UUFDekYsTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQy9CLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7WUFDZCxNQUFNLElBQUksS0FBSyxDQUFDLGdDQUFnQyxDQUFDLENBQUM7UUFDcEQsQ0FBQztRQUNELE9BQU87WUFDTCxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUc7WUFDYixHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUc7U0FDZCxDQUFDO0lBQ0osQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsVUFBVSxDQUFDLEdBQVc7UUFDcEIsT0FBTyxRQUFRLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDeEMsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsVUFBVSxDQUFDLEdBQVc7UUFDcEIsT0FBTyxRQUFRLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDekMsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsY0FBYyxDQUFDLE9BQWU7UUFDNUIsT0FBTyxRQUFRLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQzFDLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSCxLQUFLLENBQUMsV0FBVyxDQUFDLEdBQVksRUFBRSxPQUF3QjtRQUN0RCxNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUM7UUFDMUUsNkJBQTZCO1FBQzdCLE9BQU8sTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLGFBQVUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUN4RSxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsS0FBSyxDQUFDLGtCQUFrQixDQUFDLG1CQUF3QztRQUMvRCxJQUFJLFlBQVksR0FBRyxDQUFDLENBQUM7UUFDckIsbUJBQW1CLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRTtZQUNqRCxZQUFZLElBQUksUUFBUSxDQUFDLENBQUMsQ0FBQyxXQUFXLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDOUMsQ0FBQyxDQUFDLENBQUM7UUFDSCxNQUFNLGlCQUFpQixHQUFzQjtZQUMzQyxZQUFZLEVBQUU7Z0JBQ1osY0FBYztnQkFDZCxjQUFjO2dCQUNkLFNBQVM7Z0JBQ1QsZUFBZTtnQkFDZixLQUFLO2dCQUNMLE1BQU07Z0JBQ04sWUFBWTtnQkFDWixJQUFJO2dCQUNKLGFBQWE7YUFDZDtZQUNELFVBQVUsRUFBRSxtQkFBbUIsQ0FBQyxRQUFRLENBQUMsVUFBVTtZQUNuRCxHQUFHLEVBQUUsbUJBQW1CLENBQUMsT0FBTyxFQUFFLFNBQVM7WUFDM0MsRUFBRSxFQUFFLG1CQUFtQixDQUFDLFFBQVEsQ0FBQyxFQUFFO1lBQ25DLElBQUksRUFBRSxtQkFBbUIsQ0FBQyxRQUFRLENBQUMsSUFBSTtZQUN2QyxPQUFPLEVBQUUsbUJBQW1CLENBQUMsUUFBUSxDQUFDLE9BQU87WUFDN0MsV0FBVyxFQUFFLG1CQUFtQixDQUFDLFlBQVksRUFBRSxXQUFXO1lBQzFELFlBQVksRUFBRSxZQUFZO1lBQzFCLGFBQWEsRUFBRSxFQUFFO1lBQ2pCLFlBQVksRUFBRSxHQUFHO1NBQ2xCLENBQUM7UUFFRixPQUFPLGlCQUFpQixDQUFDO0lBQzNCLENBQUM7SUFFRCwyQkFBMkIsQ0FBQyxNQUE4QjtRQUN4RCxNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDO1FBRXZCLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDO1FBRXRDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNYLE1BQU0sSUFBSSxLQUFLLENBQUMsOEJBQThCLENBQUMsQ0FBQztRQUNsRCxDQUFDO1FBRUQsSUFBSSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUN2QixNQUFNLElBQUksS0FBSyxDQUFDLDBDQUEwQyxPQUFPLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDNUUsQ0FBQztRQUVELElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUNULE1BQU0sSUFBSSxLQUFLLENBQUMsMkNBQTJDLENBQUMsQ0FBQztRQUMvRCxDQUFDO1FBRUQsSUFBSSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUNyQixNQUFNLElBQUksS0FBSyxDQUFDLGtDQUFrQyxPQUFPLEdBQUcsRUFBRSxDQUFDLENBQUM7UUFDbEUsQ0FBQztRQUVELElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsRUFBRSxDQUFDO1lBQzNCLE1BQU0sSUFBSSxLQUFLLENBQUMsa0RBQWtELENBQUMsQ0FBQztRQUN0RSxDQUFDO1FBRUQsT0FBTyxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsQ0FBQztJQUN4QixDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNILEtBQUssQ0FBQyxlQUFlLENBQUMsTUFBOEI7UUFDbEQsTUFBTSxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsMkJBQTJCLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDaEUsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ2xDLE1BQU0sU0FBUyxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDdEMsTUFBTSxPQUFPLEdBQUcsSUFBSSxhQUFVLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztRQUM3QyxNQUFNLEVBQUUsY0FBYyxFQUFFLFdBQVcsRUFBRSxrQkFBa0IsRUFBRSxNQUFNLEVBQUUsR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLFdBQVcsQ0FBQztRQUVsRyxTQUFTO2FBQ04sUUFBUSxDQUFDLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBRSxXQUFXLEVBQUUsSUFBSSxDQUFDLHFCQUFxQixFQUFFLENBQUM7YUFDOUUsY0FBYyxDQUFDLGNBQWMsQ0FBQzthQUM5QixPQUFPLENBQUMsa0JBQWtCLENBQUM7YUFDM0IsTUFBTSxDQUFDLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxDQUFDO2FBQzNCLElBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQztRQUN4QyxNQUFNLFdBQVcsR0FBRyxNQUFNLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUM1QyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDakIsTUFBTSxJQUFJLEtBQUssQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO1FBQ3pDLENBQUM7UUFDRCxNQUFNLFdBQVcsR0FBRyxXQUFXLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztRQUNwRCxPQUFPLEVBQUUsS0FBSyxFQUFFLFdBQVcsRUFBRSxDQUFDO0lBQ2hDLENBQUM7SUFFUyxLQUFLLENBQUMscUJBQXFCO1FBQ25DLElBQUksQ0FBQyxHQUFHLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztZQUM1QixNQUFNLFVBQVUsR0FBRyxJQUFJLGdCQUFVLENBQUMsdUJBQVksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDakYsR0FBRyxDQUFDLEdBQUcsR0FBRyxNQUFNLGdCQUFVLENBQUMsTUFBTSxDQUFDLEVBQUUsUUFBUSxFQUFFLFVBQVUsRUFBRSxDQUFDLENBQUM7WUFDNUQsR0FBRyxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQztRQUNoQyxDQUFDO1FBQ0QsT0FBTyxHQUFHLENBQUMsR0FBRyxDQUFDO0lBQ2pCLENBQUM7SUFFUyxLQUFLLENBQUMsY0FBYyxDQUFDLFVBQWtCO1FBQy9DLE1BQU0sR0FBRyxHQUFHLE1BQU0sSUFBSSxDQUFDLHFCQUFxQixFQUFFLENBQUM7UUFDL0MsTUFBTSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLEdBQUcsTUFBTSxHQUFHLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDNUUsT0FBTyxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsUUFBUSxFQUFFLEVBQUUsV0FBVyxFQUFFLE9BQU8sQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQztJQUMzRSxDQUFDO0lBRVMsS0FBSyxDQUFDLGFBQWE7UUFDM0IsTUFBTSxHQUFHLEdBQUcsTUFBTSxJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQztRQUMvQyxNQUFNLGFBQWEsR0FBRyxNQUFNLEdBQUcsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFDN0QsTUFBTSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsR0FBRyxNQUFNLEdBQUcsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUN0RSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sQ0FBQyxRQUFRLEVBQUUsRUFBRSxVQUFVLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUM7SUFDMUUsQ0FBQztJQUVEOzs7Ozs7Ozs7O09BVUc7SUFDTyxLQUFLLENBQUMsTUFBTSxDQUFDLFFBQWdCLEVBQUUsT0FBZSxFQUFFLE1BQWM7UUFDdEUsTUFBTSxHQUFHLEdBQUcsTUFBTSxJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQztRQUMvQyxNQUFNLElBQUksR0FBRyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLGtCQUFrQixDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDN0YsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQ3BDLENBQUM7SUFFUyxLQUFLLENBQUMsV0FBVztRQUN6QixNQUFNLEdBQUcsR0FBRyxNQUFNLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1FBQy9DLE9BQU87WUFDTCxXQUFXLEVBQUUsR0FBRyxDQUFDLFdBQVcsQ0FBQyxRQUFRLEVBQUU7WUFDdkMsU0FBUyxFQUFFLEdBQUcsQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFO1lBQ3RDLFFBQVEsRUFBRSxHQUFHLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxRQUFRLEVBQTBCO1lBQ3hFLFdBQVcsRUFBRSxHQUFHLENBQUMsY0FBYyxDQUFDLFdBQVcsQ0FBQyxRQUFRLEVBQUU7WUFDdEQsU0FBUyxFQUFFLEdBQUcsQ0FBQyxjQUFjLENBQUMsa0JBQWtCLENBQUMsUUFBUSxFQUFFO1lBQzNELFFBQVEsRUFBRSxHQUFHLENBQUMsZUFBZSxDQUFDLEtBQUssRUFBRTtTQUN0QyxDQUFDO0lBQ0osQ0FBQztJQUVEOzs7Ozs7Ozs7T0FTRztJQUNILEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBMEIsRUFBRSxtQkFBMEM7UUFDbEYsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUNyQixNQUFNLElBQUksS0FBSyxDQUFDLGtCQUFrQixDQUFDLENBQUM7UUFDdEMsQ0FBQztRQUNELElBQUksQ0FBQyxNQUFNLENBQUMsbUJBQW1CLElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxFQUFFLENBQUM7WUFDcEYsTUFBTSxJQUFJLEtBQUssQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDO1FBQ2pELENBQUM7UUFFRCxNQUFNLFFBQVEsR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDcEQsTUFBTSxlQUFlLEdBQUcsQ0FBQyxNQUFNLENBQUMsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQztRQUV6RixNQUFNLEdBQUcsR0FBRyxNQUFNLHVCQUFZLENBQUMseUJBQXlCLEVBQUUsQ0FBQztRQUUzRCxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsS0FBSyxJQUFJLENBQUMsQ0FBQztRQUNoQyxNQUFNLFFBQVEsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFBLCtCQUFpQixFQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLEtBQUssRUFBRSxDQUFDO1FBQzNGLE1BQU0sU0FBUyxHQUFHLEdBQUcsQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUN4RSxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsdUJBQXVCLENBQUMsU0FBUyxDQUFDLENBQUM7UUFFM0QsSUFBSSxXQUFXLENBQUM7UUFDaEIsSUFBSSxVQUFVLENBQUM7UUFDZixJQUFJLENBQUM7WUFDSCxXQUFXLEdBQUcsTUFBTSxJQUFJLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQ3BELFVBQVUsR0FBRyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLG1CQUFtQixFQUFFLFVBQVUsRUFBRSxXQUFXLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDbEcsQ0FBQztRQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDWCxNQUFNLElBQUksZ0NBQXFCLENBQUMsOENBQThDLFVBQVUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ2pHLENBQUM7UUFDRCxNQUFNLEVBQUUsS0FBSyxFQUFFLFdBQVcsRUFBRSxHQUFHLFdBQVcsQ0FBQztRQUUzQyxNQUFNLEtBQUssR0FBRyxJQUFJLHNCQUFTLENBQUMsV0FBVyxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksc0JBQVMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO1FBQzFFLElBQUksS0FBSyxDQUFDLG1CQUFtQixDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDakMsTUFBTSxJQUFJLGdDQUFxQixDQUFDLDRDQUE0QyxDQUFDLENBQUM7UUFDaEYsQ0FBQztRQUVELCtCQUErQjtRQUMvQixJQUFJLFVBQVUsQ0FBQztRQUNmLElBQUksUUFBUSxDQUFDO1FBQ2IsSUFBSSxDQUFDO1lBQ0gsVUFBVSxHQUFHLE1BQU0sSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ3hDLFFBQVEsR0FBRyxNQUFNLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUN0QyxDQUFDO1FBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUNYLE1BQU0sSUFBSSxnQ0FBcUIsQ0FBQywwQ0FBMEMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNqRixDQUFDO1FBQ0QsTUFBTSxFQUFFLFlBQVksRUFBRSxVQUFVLEVBQUUsR0FBRyxVQUFVLENBQUM7UUFDaEQsTUFBTSxjQUFjLEdBQUcsRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLFdBQVcsRUFBRSxJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQztRQUU3RixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUMsa0JBQWtCLEVBQUUsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDN0UsVUFBVTthQUNQLEtBQUssQ0FBQyxLQUFLLENBQUM7YUFDWixFQUFFLENBQUMsRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDLG1CQUFtQixFQUFFLENBQUM7YUFDM0MsTUFBTSxDQUFDLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxDQUFDO2FBQy9CLFFBQVEsQ0FBQyxjQUFjLENBQUM7YUFDeEIsY0FBYyxDQUFDLFVBQVUsQ0FBQzthQUMxQixVQUFVLENBQUMsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxDQUFDO2FBQzdELEdBQUcsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDbkMsTUFBTSxtQkFBbUIsR0FBRyxDQUFDLE1BQU0sVUFBVSxDQUFDLEtBQUssRUFBRSxDQUFnQixDQUFDO1FBRXRFLElBQUksWUFBWSxHQUFHLG1CQUFtQixDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFDM0QsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBQ3JCLElBQUEsZ0JBQU0sRUFBQyxNQUFNLENBQUMsT0FBTyxFQUFFLGlCQUFpQixDQUFDLENBQUM7WUFDMUMsSUFBQSxnQkFBTSxFQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUUsbUJBQW1CLENBQUMsQ0FBQztZQUM5QyxJQUFBLGdCQUFNLEVBQUMsTUFBTSxDQUFDLGdCQUFnQixFQUFFLDJCQUEyQixDQUFDLENBQUM7WUFFN0QsTUFBTSxlQUFlLEdBQUcsc0JBQXNCLENBQUMsbUJBQW1CLENBQUM7Z0JBQ2pFLENBQUMsQ0FBQyxtQkFBbUI7Z0JBQ3JCLENBQUMsQ0FBQyxNQUFNLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1lBQ2hGLE1BQU0sSUFBSSxDQUFDLG9CQUFvQixDQUM3QixlQUFlLEVBQ2YsTUFBTSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxFQUNuQyxNQUFNLENBQUMsZ0JBQWdCLEVBQ3ZCLFVBQVUsRUFDVixTQUFTLEVBQ1QsbUJBQW1CLEVBQ25CLFFBQVEsRUFDUixRQUFRLENBQ1QsQ0FBQztZQUNGLE1BQU0saUJBQWlCLEdBQUcsTUFBTSxVQUFVLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDbkQsWUFBWSxHQUFHLGlCQUFpQixDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFDdkQsQ0FBQzthQUFNLENBQUM7WUFDTixNQUFNLEtBQUssR0FBRyxJQUFJLHNCQUFTLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDekMsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ25DLE1BQU0sTUFBTSxHQUFHO2dCQUNiO29CQUNFLE9BQU8sRUFBRSxtQkFBbUIsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTztvQkFDOUMsV0FBVyxFQUFFLEtBQUssQ0FBQyxRQUFRLEVBQUU7b0JBQzdCLEtBQUssRUFBRSxLQUFLLENBQUMsUUFBUSxFQUFFO2lCQUN4QjthQUNGLENBQUM7WUFDRixNQUFNLE9BQU8sR0FBRztnQkFDZDtvQkFDRSxPQUFPLEVBQUUsbUJBQW1CLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU87b0JBQy9DLFdBQVcsRUFBRSxLQUFLLENBQUMsUUFBUSxFQUFFO29CQUM3QixRQUFRLEVBQUUsVUFBVTtpQkFDckI7YUFDRixDQUFDO1lBQ0YsTUFBTSxXQUFXLEdBQUcsS0FBSyxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ3JDLE1BQU0sUUFBUSxHQUFHLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLFdBQVcsRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxDQUFDO1lBQzFGLE1BQU0sT0FBTyxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLENBQUM7WUFDM0MsTUFBTSxXQUFXLEdBQVU7Z0JBQ3pCLFlBQVksRUFBRSxZQUFZO2dCQUMxQixTQUFTLEVBQUUsS0FBSztnQkFDaEIsSUFBSSxFQUFFLFVBQVU7Z0JBQ2hCLFdBQVcsRUFBRSxtQkFBbUIsQ0FBQyxlQUFlLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQztnQkFDaEUsY0FBYyxFQUFFLFFBQVE7Z0JBQ3hCLFFBQVEsRUFBRSxRQUFRO2dCQUNsQixPQUFPLEVBQUUsT0FBTztnQkFDaEIsWUFBWSxFQUFFLEVBQUUsR0FBRyxjQUFjLEVBQUUsY0FBYyxFQUFFLFFBQVEsRUFBRTthQUM5RCxDQUFDO1lBRUYsTUFBTSxVQUFVLEdBQWtCLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBRSxlQUFlLEVBQUUsRUFBRSxFQUFFLENBQUM7WUFDbkYsTUFBTSxZQUFZLEdBQW9CLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDbkQsTUFBTSxTQUFTLEdBQXNCO2dCQUNuQyxZQUFZLEVBQUUsWUFBWTtnQkFDMUIsVUFBVSxFQUFFLFVBQVU7YUFDdkIsQ0FBQztZQUNGLE1BQU0sVUFBVSxHQUFnQixFQUFFLFVBQVUsRUFBRSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7WUFDNUQsT0FBTyxVQUFVLENBQUM7UUFDcEIsQ0FBQztRQUNELE1BQU0sV0FBVyxHQUFVLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLENBQUM7UUFDNUUsT0FBTyxXQUFXLENBQUM7SUFDckIsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSCxLQUFLLENBQUMscUJBQXFCLENBQUMsTUFBdUM7UUFDakUsTUFBTSxlQUFlLEdBQUcsQ0FBQyxNQUFNLENBQUMsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQztRQUN6RixNQUFNLFFBQVEsR0FBRyxNQUFNLENBQUMsaUJBQWlCLElBQUksQ0FBQyxDQUFDO1FBQy9DLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxlQUFlLElBQUksUUFBUSxHQUFHLDJCQUFtQixDQUFDO1FBRXhFLElBQUksUUFBUSxHQUFHLENBQUMsSUFBSSxNQUFNLElBQUksUUFBUSxJQUFJLE1BQU0sR0FBRyxRQUFRLEdBQUcsRUFBRSxHQUFHLDJCQUFtQixFQUFFLENBQUM7WUFDdkYsTUFBTSxJQUFJLEtBQUssQ0FDYiw4RUFBOEUsUUFBUSxzQkFBc0IsTUFBTSxHQUFHLENBQ3RILENBQUM7UUFDSixDQUFDO1FBRUQsTUFBTSxRQUFRLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ3BELE1BQU0sR0FBRyxHQUFHLE1BQU0sdUJBQVksQ0FBQyx5QkFBeUIsRUFBRSxDQUFDO1FBQzNELE1BQU0sU0FBUyxHQUFHLENBQUMsQ0FBQztRQUNwQixNQUFNLFFBQVEsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFBLCtCQUFpQixFQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLFNBQVMsRUFBRSxDQUFDO1FBQ25HLE1BQU0sU0FBUyxHQUFHLEdBQUcsQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUN4RSxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsdUJBQXVCLENBQUMsU0FBUyxDQUFDLENBQUM7UUFFNUQsMkZBQTJGO1FBQzNGLE1BQU0sZUFBZSxHQUNuQixNQUFNLENBQUMsZ0JBQWdCLElBQUksTUFBTSxDQUFDLE9BQU87WUFDdkMsQ0FBQyxDQUFDLE1BQU0sSUFBSSxDQUFDLHVCQUF1QixDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsRUFBRSxNQUFNLENBQUMsZ0JBQWdCLENBQUM7WUFDaEcsQ0FBQyxDQUFDLFNBQVMsQ0FBQztRQUVoQixNQUFNLHlCQUF5QixHQUFVLEVBQUUsQ0FBQztRQUM1QyxJQUFJLGFBQWEsR0FBRyxRQUFRLENBQUM7UUFDN0IsS0FBSyxJQUFJLENBQUMsR0FBRyxRQUFRLEVBQUUsQ0FBQyxHQUFHLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQ3ZDLE1BQU0sYUFBYSxHQUF1QjtnQkFDeEMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxPQUFPO2dCQUN2QixTQUFTLEVBQUUsTUFBTSxDQUFDLFNBQVM7Z0JBQzNCLFFBQVEsRUFBRSxNQUFNLENBQUMsUUFBUTtnQkFDekIsZ0JBQWdCLEVBQUUsTUFBTSxDQUFDLGdCQUFnQjtnQkFDekMsbUJBQW1CLEVBQUUsV0FBVztnQkFDaEMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJO2dCQUNqQixLQUFLLEVBQUUsQ0FBQzthQUNULENBQUM7WUFFRixJQUFJLG1CQUFtQixDQUFDO1lBQ3hCLElBQUksQ0FBQztnQkFDSCxtQkFBbUIsR0FBRyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxFQUFFLGVBQWUsQ0FBQyxDQUFDO1lBQzNFLENBQUM7WUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO2dCQUNYLElBQUksQ0FBQyxZQUFZLGdDQUFxQixFQUFFLENBQUM7b0JBQ3ZDLGFBQWEsR0FBRyxDQUFDLENBQUM7b0JBQ2xCLFNBQVM7Z0JBQ1gsQ0FBQztnQkFDRCxNQUFNLENBQUMsQ0FBQztZQUNWLENBQUM7WUFFRCxJQUFJLGVBQWUsRUFBRSxDQUFDO2dCQUNwQix5QkFBeUIsQ0FBQyxJQUFJLENBQUUsbUJBQW1DLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDckYsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLHlCQUF5QixDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1lBQ3RELENBQUM7WUFDRCxhQUFhLEdBQUcsQ0FBQyxDQUFDO1FBQ3BCLENBQUM7UUFFRCxJQUFJLHlCQUF5QixDQUFDLE1BQU0sSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUMxQyxNQUFNLElBQUksZ0NBQXFCLENBQUMsK0NBQStDLENBQUMsQ0FBQztRQUNuRixDQUFDO1FBRUQsSUFBSSxlQUFlLEVBQUUsQ0FBQztZQUNwQiw0R0FBNEc7WUFDNUcsa0hBQWtIO1lBQ2xILHNHQUFzRztZQUN0RyxNQUFNLDJCQUEyQixHQUFHO2dCQUNsQyxVQUFVLEVBQ1IseUJBQXlCLENBQUMseUJBQXlCLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsWUFBWTtxQkFDcEcsVUFBVTtnQkFDZixXQUFXLEVBQ1QseUJBQXlCLENBQUMseUJBQXlCLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsWUFBWTtxQkFDcEcsV0FBVztnQkFDaEIsY0FBYyxFQUNaLHlCQUF5QixDQUFDLHlCQUF5QixDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFlBQVk7cUJBQ3BHLGNBQWM7Z0JBQ25CLGFBQWEsRUFBRSxhQUFhO2FBQzdCLENBQUM7WUFDRix5QkFBeUIsQ0FBQyx5QkFBeUIsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxZQUFZO2dCQUNyRywyQkFBMkIsQ0FBQztZQUM5QixNQUFNLDhCQUE4QixHQUFnQixFQUFFLFVBQVUsRUFBRSx5QkFBeUIsRUFBRSxDQUFDO1lBQzlGLE9BQU8sOEJBQThCLENBQUM7UUFDeEMsQ0FBQztRQUVELE9BQU8sRUFBRSxZQUFZLEVBQUUseUJBQXlCLEVBQUUsYUFBYSxFQUFFLENBQUM7SUFDcEUsQ0FBQztJQUVELG9CQUFvQjtJQUNwQixLQUFLLENBQUMsbUNBQW1DLENBQUMsTUFBK0I7UUFDdkUsTUFBTSxHQUFHLEdBQUcsTUFBTSxDQUFDLGVBQWUsQ0FBQztRQUNuQyxNQUFNLHlCQUF5QixHQUFZLEVBQUUsQ0FBQztRQUM5QyxJQUFJLGFBQWEsR0FBRyxDQUFDLENBQUM7UUFFdEIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUNwQyxNQUFNLEdBQUcsR0FBRyxNQUFNLHVCQUFZLENBQUMseUJBQXlCLEVBQUUsQ0FBQztZQUMzRCxNQUFNLFdBQVcsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUM7WUFDaEUsTUFBTSxHQUFHLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzVCLE1BQU0saUJBQWlCLEdBQUcsR0FBRyxFQUFFLG1CQUFtQixDQUFDO1lBQ25ELElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLGlCQUFpQixJQUFJLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQyxFQUFFLENBQUM7Z0JBQ3hELE1BQU0sSUFBSSxLQUFLLENBQUMsc0JBQXNCLENBQUMsQ0FBQztZQUMxQyxDQUFDO1lBQ0QsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLEVBQUUsQ0FBQztnQkFDN0IsTUFBTSxJQUFJLEtBQUssQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1lBQzFDLENBQUM7WUFDRCxNQUFNLGFBQWEsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFZLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDbkUsSUFDRSxDQUFDLFdBQVcsQ0FBQyxZQUFZO2dCQUN6QixDQUFDLFdBQVcsQ0FBQyxZQUFZLEVBQUUsVUFBVTtnQkFDckMsQ0FBQyxXQUFXLENBQUMsWUFBWSxFQUFFLFdBQVcsRUFDdEMsQ0FBQztnQkFDRCxNQUFNLElBQUksS0FBSyxDQUFDLHlCQUF5QixDQUFDLENBQUM7WUFDN0MsQ0FBQztZQUNELE1BQU0sY0FBYyxHQUFHO2dCQUNyQixVQUFVLEVBQUUsV0FBVyxDQUFDLFlBQVksRUFBRSxVQUFVO2dCQUNoRCxXQUFXLEVBQUUsV0FBVyxDQUFDLFlBQVksRUFBRSxXQUFXO2FBQ25ELENBQUM7WUFDRixNQUFNLFFBQVEsR0FBRyxNQUFNLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUMxQyxJQUFJLENBQUMsV0FBVyxDQUFDLFlBQVksRUFBRSxjQUFjLEVBQUUsQ0FBQztnQkFDOUMsTUFBTSxJQUFJLEtBQUssQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO1lBQzdDLENBQUM7WUFDRCxNQUFNLGNBQWMsR0FBRyxXQUFXLENBQUMsWUFBYSxDQUFDLGNBQXlCLENBQUM7WUFDM0UsSUFBSSxDQUFDLFdBQVcsQ0FBQyxjQUFjLEVBQUUsQ0FBQztnQkFDaEMsTUFBTSxJQUFJLEtBQUssQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO1lBQzdDLENBQUM7WUFDRCxNQUFNLGNBQWMsR0FBRyxXQUFXLENBQUMsY0FBd0IsQ0FBQztZQUM1RCxNQUFNLFNBQVMsR0FBRyxHQUFHLENBQUMsZ0JBQWdCLENBQUMsY0FBYyxFQUFFLGNBQWMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDcEYsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLHVCQUF1QixDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQzNELElBQUksWUFBb0IsQ0FBQztZQUN6QixJQUFJLGlCQUFpQixFQUFFLENBQUM7Z0JBQ3RCLHdFQUF3RTtnQkFDeEUsNkVBQTZFO2dCQUM3RSxNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLGlCQUFpQixFQUFFLEtBQUssQ0FBQyxDQUFDO2dCQUN4RCxNQUFNLE9BQU8sR0FBRyxtQkFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLGFBQWEsRUFBRSxTQUFTLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQztnQkFDbkcsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO29CQUNiLE1BQU0sSUFBSSxLQUFLLENBQUMsbUJBQW1CLENBQUMsQ0FBQztnQkFDdkMsQ0FBQztnQkFDRCxZQUFZLEdBQUcsU0FBUyxDQUFDO1lBQzNCLENBQUM7aUJBQU0sQ0FBQztnQkFDTixNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLGFBQWEsRUFBRSxHQUFHLENBQUMsY0FBYyxDQUFDLENBQUM7Z0JBQzdELElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztvQkFDWixNQUFNLElBQUksS0FBSyxDQUFDLG1CQUFtQixDQUFDLENBQUM7Z0JBQ3ZDLENBQUM7Z0JBQ0QsWUFBWSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7b0JBQzNCLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDO29CQUN4QyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQztpQkFDN0MsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztZQUNELE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxVQUFVLEVBQUU7aUJBQ2pDLFFBQVEsQ0FBQyxRQUFRLENBQUM7aUJBQ2xCLElBQUksQ0FBQyxXQUFXLENBQUMsWUFBc0IsQ0FBQztpQkFDeEMsTUFBTSxDQUFDLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxDQUFDO2lCQUMvQixRQUFRLENBQUMsY0FBYyxDQUFDLENBQUM7WUFDNUIsTUFBTSxVQUFVLEdBQUcsSUFBSSxhQUFVLENBQUMsRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBQztZQUN0RCxVQUFVLENBQUMsWUFBWSxDQUFDLEVBQUUsR0FBRyxFQUFFLFVBQVUsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRSxZQUFZLENBQUMsQ0FBQztZQUN6RSxNQUFNLGlCQUFpQixHQUFHLE1BQU0sVUFBVSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ25ELE1BQU0sWUFBWSxHQUFHLGlCQUFpQixDQUFDLGlCQUFpQixFQUFFLENBQUM7WUFFM0QseUJBQXlCLENBQUMsSUFBSSxDQUFDO2dCQUM3QixZQUFZLEVBQUUsWUFBWTtnQkFDMUIsU0FBUyxFQUFFLFdBQVcsQ0FBQyxTQUFTO2FBQ2pDLENBQUMsQ0FBQztZQUVILElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLFdBQVcsQ0FBQyxZQUFhLENBQUMsYUFBYSxFQUFFLENBQUM7Z0JBQ3BFLGFBQWEsR0FBRyxXQUFXLENBQUMsWUFBYSxDQUFDLGFBQXVCLENBQUM7WUFDcEUsQ0FBQztRQUNILENBQUM7UUFDRCxPQUFPLEVBQUUsWUFBWSxFQUFFLHlCQUF5QixFQUFFLGFBQWEsRUFBRSxDQUFDO0lBQ3BFLENBQUM7SUFFRCxLQUFLLENBQUMsZ0JBQWdCLENBQUMsTUFBK0I7UUFDcEQsT0FBTyxFQUFFLENBQUM7SUFDWixDQUFDO0lBRUQsS0FBSyxDQUFDLGVBQWUsQ0FBQyxNQUErQjtRQUNuRCxPQUFPLElBQUEsc0NBQTJCLEVBQ2hDLE1BQU0sRUFDTixDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsRUFDekMsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxTQUFTLENBQUMsQ0FDdkQsQ0FBQztJQUNKLENBQUM7SUFFRCxLQUFLLENBQUMsaUJBQWlCLENBQUMsTUFBZ0M7UUFDdEQsTUFBTSxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsR0FBRyxNQUFNLENBQUM7UUFDckUsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ2QsTUFBTSxJQUFJLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1FBQ3RDLENBQUM7UUFFRCxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDaEIsTUFBTSxJQUFJLEtBQUssQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1FBQ3hDLENBQUM7UUFFRCxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ3RCLE1BQU0sSUFBSSxLQUFLLENBQUMsNkJBQTZCLENBQUMsQ0FBQztRQUNqRCxDQUFDO1FBRUQsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQzlCLElBQUksSUFBWSxDQUFDO1FBQ2pCLElBQUksUUFBZ0IsQ0FBQztRQUNyQixJQUFJLE9BQWdCLENBQUM7UUFFckIsSUFBSSxLQUFLLEtBQUssTUFBTSxFQUFFLENBQUM7WUFDckIsTUFBTSxRQUFRLEdBQUcsV0FBSyxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsZUFBSyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1lBQzdELE1BQU0sU0FBUyxHQUFHLElBQUEsMkJBQXFCLEVBQUMsRUFBRSxLQUFLLEVBQUUsVUFBVSxDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFDO1lBQy9FLElBQUksR0FBRyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLE9BQU8sSUFBSSxFQUFFLENBQUM7WUFDM0MsUUFBUSxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLE1BQU0sSUFBSSxHQUFHLENBQUMsQ0FBQztZQUN2RCxPQUFPLEdBQUcsU0FBUyxDQUFDLFVBQVUsS0FBSyxzQkFBc0IsQ0FBQztRQUM1RCxDQUFDO2FBQU0sQ0FBQztZQUNOLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUNsQyxNQUFNLFNBQVMsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQXFDLENBQUM7WUFDckYsSUFBSSxHQUFHLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUN4QixRQUFRLEdBQUcsU0FBUyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQ2hDLE9BQU8sR0FBRyxTQUFTLENBQUMsbUJBQW1CLENBQUMsS0FBSyxJQUFJLENBQUM7UUFDcEQsQ0FBQztRQUVELElBQUksWUFBWSxFQUFFLDBCQUEwQixFQUFFLENBQUM7WUFDN0MsTUFBTSxXQUFXLEdBQUcsTUFBTSxFQUFFLFlBQVksRUFBRSxFQUFFLFdBQVcsSUFBSSxNQUFNLEVBQUUsWUFBWSxFQUFFLEVBQUUsV0FBVyxDQUFDO1lBQy9GLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztnQkFDakIsTUFBTSxJQUFJLEtBQUssQ0FBQyxvREFBb0QsQ0FBQyxDQUFDO1lBQ3hFLENBQUM7WUFDRCxJQUFJLElBQUksS0FBSyxXQUFXLEVBQUUsQ0FBQztnQkFDekIsTUFBTSxJQUFJLHlDQUE4QixDQUN0QyxtQ0FBbUMsSUFBSSx1Q0FBdUMsV0FBVyxFQUFFLEVBQzNGLEtBQUssRUFDTCxDQUFDLFFBQVEsQ0FBQyxFQUNWLFVBQVUsQ0FBQyxLQUFLLEVBQ2hCLENBQUMsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUN0QyxDQUFDO1lBQ0osQ0FBQztRQUNILENBQUM7UUFFRCxJQUFJLFFBQVEsQ0FBQyxVQUFVLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDdEMsSUFBSSxRQUFRLENBQUMsVUFBVSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztnQkFDckMsTUFBTSxJQUFJLEtBQUssQ0FBQyxnQ0FBZ0MsQ0FBQyxDQUFDO1lBQ3BELENBQUM7WUFFRCxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxJQUFJLFFBQVEsQ0FBQyxVQUFVLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUN6RSxNQUFNLElBQUksS0FBSyxDQUNiLEdBQUcsSUFBSSxDQUFDLFFBQVEsRUFBRSxvSUFBb0ksQ0FDdkosQ0FBQztZQUNKLENBQUM7WUFFRCxJQUFJLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxLQUFLLElBQUksRUFBRSxDQUFDO2dCQUM1QyxNQUFNLElBQUkseUNBQThCLENBQ3RDLHFCQUFxQixRQUFRLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sbURBQW1ELElBQUksRUFBRSxFQUM1RyxLQUFLLEVBQ0wsQ0FBQyxRQUFRLENBQUMsRUFDVixVQUFVLENBQUMsS0FBSyxFQUNoQixDQUFDLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FDdEMsQ0FBQztZQUNKLENBQUM7WUFFRCxJQUFJLENBQUMsT0FBTyxJQUFJLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxLQUFLLFFBQVEsRUFBRSxDQUFDO2dCQUMzRCxNQUFNLElBQUkseUNBQThCLENBQ3RDLG9CQUFvQixRQUFRLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sc0NBQXNDLFFBQVEsRUFBRSxFQUNqRyxLQUFLLEVBQ0wsQ0FBQyxRQUFRLENBQUMsRUFDVixVQUFVLENBQUMsS0FBSyxFQUNoQixDQUFDLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FDdEMsQ0FBQztZQUNKLENBQUM7UUFDSCxDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsdUJBQXVCLENBQUMsTUFBYztRQUNwQyxPQUFPLElBQUksYUFBVSxDQUFDLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUMsVUFBVSxDQUFDLFdBQUssQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBbUIsQ0FBQyxDQUFDLENBQUM7SUFDdEgsQ0FBQztJQUVPLFVBQVU7UUFDaEIsT0FBTyxJQUFJLCtCQUF5QixDQUFDLGVBQUssQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUNuRSxDQUFDO0lBRUQ7OztPQUdHO0lBQ08sS0FBSyxDQUFDLHVCQUF1QixDQUFDLE9BQWUsRUFBRSxnQkFBd0I7UUFDL0UsT0FBTyxJQUFBLGtDQUE2QixFQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxFQUFFLGdCQUFnQixFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNqRyxDQUFDO0lBRVMsS0FBSyxDQUFDLG9CQUFvQixDQUFDLE1BQXNEO1FBQ3pGLE9BQU8sSUFBQSxtQ0FBd0IsRUFBQyxNQUFNLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ssS0FBSyxDQUFDLG9CQUFvQixDQUNoQyxlQUFxQyxFQUNyQyxTQUFpQixFQUNqQixnQkFBd0IsRUFDeEIsVUFBaUMsRUFDakMsU0FBaUIsRUFDakIsbUJBQWdDLEVBQ2hDLFFBQWdCLEVBQ2hCLFFBQWdCO1FBRWhCLE1BQU0sVUFBVSxHQUFHLElBQUksYUFBVSxDQUFDLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxDQUFDLENBQUM7UUFFdEQsSUFBSSxlQUFlLENBQUMsT0FBTyxLQUFLLElBQUksRUFBRSxDQUFDO1lBQ3JDLE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLG9CQUFvQixDQUFDO2dCQUM3QyxPQUFPLEVBQUUsbUJBQW1CLENBQUMsZUFBZTtnQkFDNUMsT0FBTyxFQUFFLGVBQWUsQ0FBQyxnQkFBZ0I7Z0JBQ3pDLFNBQVM7Z0JBQ1QsZ0JBQWdCO2dCQUNoQixRQUFRO2dCQUNSLGNBQWMsRUFBRSxRQUFRO2dCQUN4QixLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUs7YUFDbEIsQ0FBQyxDQUFDO1lBQ0gsVUFBVSxDQUFDLFlBQVksQ0FBQyxFQUFFLEdBQUcsRUFBRSxVQUFVLENBQUMsT0FBTyxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDckUsQ0FBQzthQUFNLENBQUM7WUFDTixnREFBZ0Q7WUFDaEQsTUFBTSxtQkFBbUIsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQXlDLENBQUM7WUFDeEcsTUFBTSxTQUFTLEdBQUcsTUFBTSxJQUFBLG9DQUF5QixFQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsRUFBRSxZQUFZLEVBQUUsU0FBUyxFQUFFLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztZQUM3RyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7Z0JBQ2YsTUFBTSxJQUFJLEtBQUssQ0FBQyxxRUFBcUUsQ0FBQyxDQUFDO1lBQ3pGLENBQUM7WUFDRCxNQUFNLHFCQUFxQixHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUEyQyxDQUFDO1lBRTlGLE1BQU0sWUFBWSxHQUFHLE1BQU0sdUJBQVksQ0FBQyxlQUFlLENBQ3JELG1CQUFtQixFQUNuQixxQkFBcUIsRUFDckIsUUFBUSxFQUNSLG1CQUFtQixDQUNwQixDQUFDO1lBQ0YsVUFBVSxDQUFDLFlBQVksQ0FBQyxFQUFFLEdBQUcsRUFBRSxVQUFVLENBQUMsT0FBTyxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFDM0UsQ0FBQztJQUNILENBQUM7SUFFRCxrQkFBa0I7SUFDbEIsaUJBQWlCLENBQUMsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLFlBQVksRUFBMkI7UUFDekUsSUFBSSxZQUFZLEtBQUssS0FBSyxFQUFFLENBQUM7WUFDM0IsTUFBTSxJQUFJLEtBQUssQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO1FBQzlDLENBQUM7UUFDRCxJQUFBLGtDQUFvQixFQUFDLEdBQUcsRUFBRSxTQUFTLElBQUksRUFBRSxDQUFDLENBQUM7SUFDN0MsQ0FBQzs7QUE5dUJILGtCQSt1QkM7QUFodUJrQixlQUFXLEdBQUcsS0FBSyxBQUFSLENBQVM7QUFFcEIsc0JBQWtCLEdBQUcsS0FBSyxBQUFSLENBQVMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5pbXBvcnQgKiBhcyBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQge1xuICBCYXNlQ29pbixcbiAgQml0R29CYXNlLFxuICBEb3RBc3NldFR5cGVzLFxuICBFZGRzYSxcbiAgRW52aXJvbm1lbnRzLFxuICBFcnJvck5vSW5wdXRUb1JlY292ZXIsXG4gIEV4cGxhbmF0aW9uUmVzdWx0LFxuICBLZXlQYWlyLFxuICBNUENBbGdvcml0aG0sXG4gIFBhcnNlZFRyYW5zYWN0aW9uLFxuICBQYXJzZVRyYW5zYWN0aW9uT3B0aW9ucyxcbiAgU2lnbmVkVHJhbnNhY3Rpb24sXG4gIFNpZ25UcmFuc2FjdGlvbk9wdGlvbnMgYXMgQmFzZVNpZ25UcmFuc2FjdGlvbk9wdGlvbnMsXG4gIFVuc2lnbmVkVHJhbnNhY3Rpb24sXG4gIFZlcmlmeVRyYW5zYWN0aW9uT3B0aW9ucyxcbiAgVHNzVmVyaWZ5QWRkcmVzc09wdGlvbnMsXG4gIEVERFNBTWV0aG9kcyxcbiAgRUREU0FNZXRob2RUeXBlcyxcbiAgTVBDVHgsXG4gIE1QQ1JlY292ZXJ5T3B0aW9ucyxcbiAgTVBDQ29uc29saWRhdGlvblJlY292ZXJ5T3B0aW9ucyxcbiAgTVBDU3dlZXBUeHMsXG4gIFJlY292ZXJ5VHhSZXF1ZXN0LFxuICBSZWNvdmVyeVByb3ZpZGVyRXJyb3IsXG4gIE1QQ1Vuc2lnbmVkVHgsXG4gIE1QQ1N3ZWVwUmVjb3ZlcnlPcHRpb25zLFxuICBNUENUeHMsXG4gIE11bHRpc2lnVHlwZSxcbiAgbXVsdGlzaWdUeXBlcyxcbiAgQXVkaXREZWNyeXB0ZWRLZXlQYXJhbXMsXG4gIHZlcmlmeUVkZHNhVHNzV2FsbGV0QWRkcmVzcyxcbiAgVHhJbnRlbnRNaXNtYXRjaFJlY2lwaWVudEVycm9yLFxuICBnZXRFZGRzYVNpZ25pbmdNYXRlcmlhbCBhcyBzaGFyZWRHZXRFZGRzYVNpZ25pbmdNYXRlcmlhbCxcbiAgc2lnbkVkZHNhTXBjVjJSZWNvdmVyeVR4LFxuICBFZGRzYVNpZ25pbmdNYXRlcmlhbCxcbiAgZGVjcnlwdEtleWNoYWluUHJpdmF0ZUtleSxcbn0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWNvcmUnO1xuaW1wb3J0IHsgQmFzZUNvaW4gYXMgU3RhdGljc0Jhc2VDb2luLCBjb2lucywgUG9sa2Fkb3RTcGVjTmFtZVR5cGUgfSBmcm9tICdAYml0Z28tYmV0YS9zdGF0aWNzJztcbmltcG9ydCB7XG4gIEludGVyZmFjZSxcbiAgS2V5UGFpciBhcyBEb3RLZXlQYWlyLFxuICBOYXRpdmVUcmFuc2ZlckJ1aWxkZXIsXG4gIFRyYW5zYWN0aW9uLFxuICBUcmFuc2FjdGlvbkJ1aWxkZXJGYWN0b3J5LFxuICBVdGlscyxcbiAgZXhwbGFpbkRvdFRyYW5zYWN0aW9uLFxufSBmcm9tICcuL2xpYic7XG5pbXBvcnQgJ0Bwb2xrYWRvdC9hcGktYXVnbWVudCc7XG5pbXBvcnQgeyBBcGlQcm9taXNlLCBXc1Byb3ZpZGVyIH0gZnJvbSAnQHBvbGthZG90L2FwaSc7XG5pbXBvcnQgeyBNYXRlcmlhbCB9IGZyb20gJy4vbGliL2lmYWNlJztcbmltcG9ydCBCaWdOdW1iZXIgZnJvbSAnYmlnbnVtYmVyLmpzJztcbmltcG9ydCB7IGF1ZGl0RWRkc2FQcml2YXRlS2V5LCBnZXREZXJpdmF0aW9uUGF0aCB9IGZyb20gJ0BiaXRnby1iZXRhL3Nkay1saWItbXBjJztcbmltcG9ydCBuYWNsIGZyb20gJ3R3ZWV0bmFjbCc7XG5cbmV4cG9ydCBjb25zdCBERUZBVUxUX1NDQU5fRkFDVE9SID0gMjA7IC8vIGRlZmF1bHQgbnVtYmVyIG9mIHJlY2VpdmUgYWRkcmVzc2VzIHRvIHNjYW4gZm9yIGZ1bmRzXG5cbmV4cG9ydCBpbnRlcmZhY2UgU2lnblRyYW5zYWN0aW9uT3B0aW9ucyBleHRlbmRzIEJhc2VTaWduVHJhbnNhY3Rpb25PcHRpb25zIHtcbiAgdHhQcmVidWlsZDogVHJhbnNhY3Rpb25QcmVidWlsZDtcbiAgcHJ2OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHJhbnNhY3Rpb25QcmVidWlsZCB7XG4gIHR4SGV4OiBzdHJpbmc7XG4gIHRyYW5zYWN0aW9uOiBJbnRlcmZhY2UuVHhEYXRhO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFZlcmlmaWVkVHJhbnNhY3Rpb25QYXJhbWV0ZXJzIHtcbiAgdHhIZXg6IHN0cmluZztcbiAgcHJ2OiBzdHJpbmc7XG59XG5cbmNvbnN0IGRvdFV0aWxzID0gVXRpbHMuZGVmYXVsdDtcblxuZnVuY3Rpb24gaXNFZGRzYVNpZ25pbmdNYXRlcmlhbCh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIEVkZHNhU2lnbmluZ01hdGVyaWFsIHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ29iamVjdCcgfHwgdmFsdWUgPT09IG51bGwpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKCEoJ3ZlcnNpb24nIGluIHZhbHVlKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAodmFsdWUudmVyc2lvbiA9PT0gJ3YxJykge1xuICAgIHJldHVybiAndXNlclBydicgaW4gdmFsdWUgJiYgdHlwZW9mIHZhbHVlLnVzZXJQcnYgPT09ICdzdHJpbmcnO1xuICB9XG4gIGlmICh2YWx1ZS52ZXJzaW9uID09PSAndjInKSB7XG4gICAgcmV0dXJuICdlbmNyeXB0ZWRVc2VyS2V5JyBpbiB2YWx1ZSAmJiB0eXBlb2YgdmFsdWUuZW5jcnlwdGVkVXNlcktleSA9PT0gJ3N0cmluZyc7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5leHBvcnQgY2xhc3MgRG90IGV4dGVuZHMgQmFzZUNvaW4ge1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgX3N0YXRpY3NDb2luOiBSZWFkb25seTxTdGF0aWNzQmFzZUNvaW4+O1xuICByZWFkb25seSBNQVhfVkFMSURJVFlfRFVSQVRJT04gPSAyNDAwO1xuICByZWFkb25seSBTV0VFUF9UWE5fRFVSQVRJT04gPSA2NDtcblxuICBjb25zdHJ1Y3RvcihiaXRnbzogQml0R29CYXNlLCBzdGF0aWNzQ29pbj86IFJlYWRvbmx5PFN0YXRpY3NCYXNlQ29pbj4pIHtcbiAgICBzdXBlcihiaXRnbyk7XG5cbiAgICBpZiAoIXN0YXRpY3NDb2luKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgcmVxdWlyZWQgY29uc3RydWN0b3IgcGFyYW1ldGVyIHN0YXRpY3NDb2luJyk7XG4gICAgfVxuXG4gICAgdGhpcy5fc3RhdGljc0NvaW4gPSBzdGF0aWNzQ29pbjtcbiAgfVxuXG4gIHByb3RlY3RlZCBzdGF0aWMgaW5pdGlhbGl6ZWQgPSBmYWxzZTtcbiAgcHJvdGVjdGVkIHN0YXRpYyBNUEM6IEVkZHNhO1xuICBwcm90ZWN0ZWQgc3RhdGljIG5vZGVBcGlJbml0aWFsaXplZCA9IGZhbHNlO1xuICBwcm90ZWN0ZWQgc3RhdGljIEFQSTogQXBpUHJvbWlzZTtcblxuICBzdGF0aWMgY3JlYXRlSW5zdGFuY2UoYml0Z286IEJpdEdvQmFzZSwgc3RhdGljc0NvaW4/OiBSZWFkb25seTxTdGF0aWNzQmFzZUNvaW4+KTogQmFzZUNvaW4ge1xuICAgIHJldHVybiBuZXcgRG90KGJpdGdvLCBzdGF0aWNzQ29pbik7XG4gIH1cblxuICBnZXRDaGFpbigpOiBzdHJpbmcge1xuICAgIHJldHVybiAnZG90JztcbiAgfVxuXG4gIGdldEJhc2VDaGFpbigpOiBzdHJpbmcge1xuICAgIHJldHVybiAnZG90JztcbiAgfVxuXG4gIGdldEZhbWlseSgpOiBzdHJpbmcge1xuICAgIHJldHVybiAnZG90JztcbiAgfVxuXG4gIGdldEZ1bGxOYW1lKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuICdQb2xrYWRvdCc7XG4gIH1cblxuICBnZXRCYXNlRmFjdG9yKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIE1hdGgucG93KDEwLCB0aGlzLl9zdGF0aWNzQ29pbi5kZWNpbWFsUGxhY2VzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGbGFnIGZvciBzZW5kaW5nIHZhbHVlIG9mIDBcbiAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgb2theSB0byBzZW5kIDAgdmFsdWUsIGZhbHNlIG90aGVyd2lzZVxuICAgKi9cbiAgdmFsdWVsZXNzVHJhbnNmZXJBbGxvd2VkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqIEBpbmhlcml0RG9jICovXG4gIHN1cHBvcnRzVHNzKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqIGluaGVyaXRlZCBkb2MgKi9cbiAgZ2V0RGVmYXVsdE11bHRpc2lnVHlwZSgpOiBNdWx0aXNpZ1R5cGUge1xuICAgIHJldHVybiBtdWx0aXNpZ1R5cGVzLnRzcztcbiAgfVxuXG4gIGdldE1QQ0FsZ29yaXRobSgpOiBNUENBbGdvcml0aG0ge1xuICAgIHJldHVybiAnZWRkc2EnO1xuICB9XG5cbiAgYWxsb3dzQWNjb3VudENvbnNvbGlkYXRpb25zKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlIGVkMjU1MTkga2V5IHBhaXJcbiAgICpcbiAgICogQHBhcmFtIHNlZWRcbiAgICogQHJldHVybnMge09iamVjdH0gb2JqZWN0IHdpdGggZ2VuZXJhdGVkIHB1YiwgcHJ2XG4gICAqL1xuICBnZW5lcmF0ZUtleVBhaXIoc2VlZD86IEJ1ZmZlcik6IEtleVBhaXIge1xuICAgIGNvbnN0IGtleVBhaXIgPSBzZWVkID8gZG90VXRpbHMua2V5UGFpckZyb21TZWVkKG5ldyBVaW50OEFycmF5KHNlZWQpKSA6IG5ldyBEb3RLZXlQYWlyKCk7XG4gICAgY29uc3Qga2V5cyA9IGtleVBhaXIuZ2V0S2V5cygpO1xuICAgIGlmICgha2V5cy5wcnYpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyBwcnYgaW4ga2V5IGdlbmVyYXRpb24uJyk7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICBwdWI6IGtleXMucHViLFxuICAgICAgcHJ2OiBrZXlzLnBydixcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiBib29sZWFuIGluZGljYXRpbmcgd2hldGhlciBpbnB1dCBpcyB2YWxpZCBwdWJsaWMga2V5IGZvciB0aGUgY29pbi5cbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmd9IHB1YiB0aGUgcHViIHRvIGJlIGNoZWNrZWRcbiAgICogQHJldHVybnMge0Jvb2xlYW59IGlzIGl0IHZhbGlkP1xuICAgKi9cbiAgaXNWYWxpZFB1YihwdWI6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBkb3RVdGlscy5pc1ZhbGlkUHVibGljS2V5KHB1Yik7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIGJvb2xlYW4gaW5kaWNhdGluZyB3aGV0aGVyIHRoZSBzdXBwbGllZCBwcml2YXRlIGtleSBpcyBhIHZhbGlkIGRvdCBwcml2YXRlIGtleVxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHJ2IHRoZSBwcnYgdG8gYmUgY2hlY2tlZFxuICAgKiBAcmV0dXJucyB7Qm9vbGVhbn0gaXMgaXQgdmFsaWQ/XG4gICAqL1xuICBpc1ZhbGlkUHJ2KHBydjogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGRvdFV0aWxzLmlzVmFsaWRQcml2YXRlS2V5KHBydik7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIGJvb2xlYW4gaW5kaWNhdGluZyB3aGV0aGVyIGlucHV0IGlzIHZhbGlkIHB1YmxpYyBrZXkgZm9yIHRoZSBjb2luXG4gICAqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBhZGRyZXNzIHRoZSBwdWIgdG8gYmUgY2hlY2tlZFxuICAgKiBAcmV0dXJucyB7Qm9vbGVhbn0gaXMgaXQgdmFsaWQ/XG4gICAqL1xuICBpc1ZhbGlkQWRkcmVzcyhhZGRyZXNzOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gZG90VXRpbHMuaXNWYWxpZEFkZHJlc3MoYWRkcmVzcyk7XG4gIH1cblxuICAvKipcbiAgICogU2lnbiBtZXNzYWdlIHdpdGggcHJpdmF0ZSBrZXlcbiAgICpcbiAgICogQHBhcmFtIGtleVxuICAgKiBAcGFyYW0gbWVzc2FnZVxuICAgKiBAcmV0dXJuIHtCdWZmZXJ9IEEgc2lnbmF0dXJlIG92ZXIgdGhlIGdpdmVuIG1lc3NhZ2UgdXNpbmcgdGhlIGdpdmVuIGtleVxuICAgKi9cbiAgYXN5bmMgc2lnbk1lc3NhZ2Uoa2V5OiBLZXlQYWlyLCBtZXNzYWdlOiBzdHJpbmcgfCBCdWZmZXIpOiBQcm9taXNlPEJ1ZmZlcj4ge1xuICAgIGNvbnN0IG1zZyA9IEJ1ZmZlci5pc0J1ZmZlcihtZXNzYWdlKSA/IG1lc3NhZ2UudG9TdHJpbmcoJ3V0ZjgnKSA6IG1lc3NhZ2U7XG4gICAgLy8gcmVjb25zdGl0dXRlIGtleXMgYW5kIHNpZ25cbiAgICByZXR1cm4gQnVmZmVyLmZyb20obmV3IERvdEtleVBhaXIoeyBwcnY6IGtleS5wcnYgfSkuc2lnbk1lc3NhZ2UobXNnKSk7XG4gIH1cblxuICAvKipcbiAgICogRXhwbGFpbi9wYXJzZSB0cmFuc2FjdGlvblxuICAgKiBAcGFyYW0gdW5zaWduZWRUcmFuc2FjdGlvblxuICAgKi9cbiAgYXN5bmMgZXhwbGFpblRyYW5zYWN0aW9uKHVuc2lnbmVkVHJhbnNhY3Rpb246IFVuc2lnbmVkVHJhbnNhY3Rpb24pOiBQcm9taXNlPEV4cGxhbmF0aW9uUmVzdWx0PiB7XG4gICAgbGV0IG91dHB1dEFtb3VudCA9IDA7XG4gICAgdW5zaWduZWRUcmFuc2FjdGlvbi5wYXJzZWRUeC5vdXRwdXRzLmZvckVhY2goKG8pID0+IHtcbiAgICAgIG91dHB1dEFtb3VudCArPSBwYXJzZUludChvLnZhbHVlU3RyaW5nLCAxMCk7XG4gICAgfSk7XG4gICAgY29uc3QgZXhwbGFuYXRpb25SZXN1bHQ6IEV4cGxhbmF0aW9uUmVzdWx0ID0ge1xuICAgICAgZGlzcGxheU9yZGVyOiBbXG4gICAgICAgICdvdXRwdXRBbW91bnQnLFxuICAgICAgICAnY2hhbmdlQW1vdW50JyxcbiAgICAgICAgJ291dHB1dHMnLFxuICAgICAgICAnY2hhbmdlT3V0cHV0cycsXG4gICAgICAgICdmZWUnLFxuICAgICAgICAndHlwZScsXG4gICAgICAgICdzZXF1ZW5jZUlkJyxcbiAgICAgICAgJ2lkJyxcbiAgICAgICAgJ2Jsb2NrTnVtYmVyJyxcbiAgICAgIF0sXG4gICAgICBzZXF1ZW5jZUlkOiB1bnNpZ25lZFRyYW5zYWN0aW9uLnBhcnNlZFR4LnNlcXVlbmNlSWQsXG4gICAgICBmZWU6IHVuc2lnbmVkVHJhbnNhY3Rpb24uZmVlSW5mbz8uZmVlU3RyaW5nLFxuICAgICAgaWQ6IHVuc2lnbmVkVHJhbnNhY3Rpb24ucGFyc2VkVHguaWQsXG4gICAgICB0eXBlOiB1bnNpZ25lZFRyYW5zYWN0aW9uLnBhcnNlZFR4LnR5cGUsXG4gICAgICBvdXRwdXRzOiB1bnNpZ25lZFRyYW5zYWN0aW9uLnBhcnNlZFR4Lm91dHB1dHMsXG4gICAgICBibG9ja051bWJlcjogdW5zaWduZWRUcmFuc2FjdGlvbi5jb2luU3BlY2lmaWM/LmJsb2NrTnVtYmVyLFxuICAgICAgb3V0cHV0QW1vdW50OiBvdXRwdXRBbW91bnQsXG4gICAgICBjaGFuZ2VPdXRwdXRzOiBbXSxcbiAgICAgIGNoYW5nZUFtb3VudDogJzAnLFxuICAgIH07XG5cbiAgICByZXR1cm4gZXhwbGFuYXRpb25SZXN1bHQ7XG4gIH1cblxuICB2ZXJpZnlTaWduVHJhbnNhY3Rpb25QYXJhbXMocGFyYW1zOiBTaWduVHJhbnNhY3Rpb25PcHRpb25zKTogVmVyaWZpZWRUcmFuc2FjdGlvblBhcmFtZXRlcnMge1xuICAgIGNvbnN0IHBydiA9IHBhcmFtcy5wcnY7XG5cbiAgICBjb25zdCB0eEhleCA9IHBhcmFtcy50eFByZWJ1aWxkLnR4SGV4O1xuXG4gICAgaWYgKCF0eEhleCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIHR4UHJlYnVpbGQgcGFyYW1ldGVyJyk7XG4gICAgfVxuXG4gICAgaWYgKCFfLmlzU3RyaW5nKHR4SGV4KSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGB0eFByZWJ1aWxkIG11c3QgYmUgYW4gb2JqZWN0LCBnb3QgdHlwZSAke3R5cGVvZiB0eEhleH1gKTtcbiAgICB9XG5cbiAgICBpZiAoIXBydikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIHBydiBwYXJhbWV0ZXIgdG8gc2lnbiB0cmFuc2FjdGlvbicpO1xuICAgIH1cblxuICAgIGlmICghXy5pc1N0cmluZyhwcnYpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYHBydiBtdXN0IGJlIGEgc3RyaW5nLCBnb3QgdHlwZSAke3R5cGVvZiBwcnZ9YCk7XG4gICAgfVxuXG4gICAgaWYgKCFfLmhhcyhwYXJhbXMsICdwdWJzJykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyBwdWJsaWMga2V5IHBhcmFtZXRlciB0byBzaWduIHRyYW5zYWN0aW9uJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgdHhIZXgsIHBydiB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEFzc2VtYmxlIGtleWNoYWluIGFuZCBoYWxmLXNpZ24gcHJlYnVpbHQgdHJhbnNhY3Rpb25cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtc1xuICAgKiBAcGFyYW0gcGFyYW1zLnR4UHJlYnVpbGQge1RyYW5zYWN0aW9uUHJlYnVpbGR9IHByZWJ1aWxkIG9iamVjdCByZXR1cm5lZCBieSBwbGF0Zm9ybVxuICAgKiBAcGFyYW0gcGFyYW1zLnBydiB7U3RyaW5nfSB1c2VyIHBydlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxTaWduZWRUcmFuc2FjdGlvbj59XG4gICAqL1xuICBhc3luYyBzaWduVHJhbnNhY3Rpb24ocGFyYW1zOiBTaWduVHJhbnNhY3Rpb25PcHRpb25zKTogUHJvbWlzZTxTaWduZWRUcmFuc2FjdGlvbj4ge1xuICAgIGNvbnN0IHsgdHhIZXgsIHBydiB9ID0gdGhpcy52ZXJpZnlTaWduVHJhbnNhY3Rpb25QYXJhbXMocGFyYW1zKTtcbiAgICBjb25zdCBmYWN0b3J5ID0gdGhpcy5nZXRCdWlsZGVyKCk7XG4gICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeS5mcm9tKHR4SGV4KTtcbiAgICBjb25zdCBrZXlQYWlyID0gbmV3IERvdEtleVBhaXIoeyBwcnY6IHBydiB9KTtcbiAgICBjb25zdCB7IHJlZmVyZW5jZUJsb2NrLCBibG9ja051bWJlciwgdHJhbnNhY3Rpb25WZXJzaW9uLCBzZW5kZXIgfSA9IHBhcmFtcy50eFByZWJ1aWxkLnRyYW5zYWN0aW9uO1xuXG4gICAgdHhCdWlsZGVyXG4gICAgICAudmFsaWRpdHkoeyBmaXJzdFZhbGlkOiBibG9ja051bWJlciwgbWF4RHVyYXRpb246IHRoaXMuTUFYX1ZBTElESVRZX0RVUkFUSU9OIH0pXG4gICAgICAucmVmZXJlbmNlQmxvY2socmVmZXJlbmNlQmxvY2spXG4gICAgICAudmVyc2lvbih0cmFuc2FjdGlvblZlcnNpb24pXG4gICAgICAuc2VuZGVyKHsgYWRkcmVzczogc2VuZGVyIH0pXG4gICAgICAuc2lnbih7IGtleToga2V5UGFpci5nZXRLZXlzKCkucHJ2IH0pO1xuICAgIGNvbnN0IHRyYW5zYWN0aW9uID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgaWYgKCF0cmFuc2FjdGlvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHRyYW5zYWN0aW9uJyk7XG4gICAgfVxuICAgIGNvbnN0IHNpZ25lZFR4SGV4ID0gdHJhbnNhY3Rpb24udG9Ccm9hZGNhc3RGb3JtYXQoKTtcbiAgICByZXR1cm4geyB0eEhleDogc2lnbmVkVHhIZXggfTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBnZXRJbml0aWFsaXplZE5vZGVBUEkoKTogUHJvbWlzZTxBcGlQcm9taXNlPiB7XG4gICAgaWYgKCFEb3Qubm9kZUFwaUluaXRpYWxpemVkKSB7XG4gICAgICBjb25zdCB3c1Byb3ZpZGVyID0gbmV3IFdzUHJvdmlkZXIoRW52aXJvbm1lbnRzW3RoaXMuYml0Z28uZ2V0RW52KCldLmRvdE5vZGVVcmxzKTtcbiAgICAgIERvdC5BUEkgPSBhd2FpdCBBcGlQcm9taXNlLmNyZWF0ZSh7IHByb3ZpZGVyOiB3c1Byb3ZpZGVyIH0pO1xuICAgICAgRG90Lm5vZGVBcGlJbml0aWFsaXplZCA9IHRydWU7XG4gICAgfVxuICAgIHJldHVybiBEb3QuQVBJO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGdldEFjY291bnRJbmZvKHdhbGxldEFkZHI6IHN0cmluZyk6IFByb21pc2U8eyBub25jZTogbnVtYmVyOyBmcmVlQmFsYW5jZTogbnVtYmVyIH0+IHtcbiAgICBjb25zdCBhcGkgPSBhd2FpdCB0aGlzLmdldEluaXRpYWxpemVkTm9kZUFQSSgpO1xuICAgIGNvbnN0IHsgbm9uY2UsIGRhdGE6IGJhbGFuY2UgfSA9IGF3YWl0IGFwaS5xdWVyeS5zeXN0ZW0uYWNjb3VudCh3YWxsZXRBZGRyKTtcbiAgICByZXR1cm4geyBub25jZTogbm9uY2UudG9OdW1iZXIoKSwgZnJlZUJhbGFuY2U6IGJhbGFuY2UuZnJlZS50b051bWJlcigpIH07XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgZ2V0SGVhZGVySW5mbygpOiBQcm9taXNlPHsgaGVhZGVyTnVtYmVyOiBudW1iZXI7IGhlYWRlckhhc2g6IHN0cmluZyB9PiB7XG4gICAgY29uc3QgYXBpID0gYXdhaXQgdGhpcy5nZXRJbml0aWFsaXplZE5vZGVBUEkoKTtcbiAgICBjb25zdCBmaW5hbGl6ZWRIYXNoID0gYXdhaXQgYXBpLnJwYy5jaGFpbi5nZXRGaW5hbGl6ZWRIZWFkKCk7XG4gICAgY29uc3QgeyBudW1iZXIsIGhhc2ggfSA9IGF3YWl0IGFwaS5ycGMuY2hhaW4uZ2V0SGVhZGVyKGZpbmFsaXplZEhhc2gpO1xuICAgIHJldHVybiB7IGhlYWRlck51bWJlcjogbnVtYmVyLnRvTnVtYmVyKCksIGhlYWRlckhhc2g6IGhhc2gudG9TdHJpbmcoKSB9O1xuICB9XG5cbiAgLyoqXG4gICAqXG4gICAqIEVzdGltYXRlIHRoZSBmZWUgb2YgdGhlIHRyYW5zYWN0aW9uXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBkZXN0QWRkciBkZXN0aW5hdGlvbiB3YWxsZXQgYWRkcmVzc1xuICAgKiBAcGFyYW0ge3N0cmluZ30gc3JjQWRkciBzb3VyY2Ugd2FsbGV0IGFkZHJlc3NcbiAgICogQHBhcmFtIHtzdHJpbmd9IGFtb3VudCBhbW91bnQgdG8gdHJhbnNmZXJcbiAgICogQHJldHVybnMge251bWJlcn0gdGhlIGVzdGltYXRlZCBmZWUgdGhlIHRyYW5zYWN0aW9uIHdpbGwgY29zdFxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vcG9sa2Fkb3QuanMub3JnL2RvY3MvYXBpL2Nvb2tib29rL3R4I2hvdy1kby1pLWVzdGltYXRlLXRoZS10cmFuc2FjdGlvbi1mZWVzXG4gICAqL1xuICBwcm90ZWN0ZWQgYXN5bmMgZ2V0RmVlKGRlc3RBZGRyOiBzdHJpbmcsIHNyY0FkZHI6IHN0cmluZywgYW1vdW50OiBudW1iZXIpOiBQcm9taXNlPG51bWJlcj4ge1xuICAgIGNvbnN0IGFwaSA9IGF3YWl0IHRoaXMuZ2V0SW5pdGlhbGl6ZWROb2RlQVBJKCk7XG4gICAgY29uc3QgaW5mbyA9IGF3YWl0IGFwaS50eC5iYWxhbmNlcy50cmFuc2ZlckFsbG93RGVhdGgoZGVzdEFkZHIsIGFtb3VudCkucGF5bWVudEluZm8oc3JjQWRkcik7XG4gICAgcmV0dXJuIGluZm8ucGFydGlhbEZlZS50b051bWJlcigpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGdldE1hdGVyaWFsKCk6IFByb21pc2U8TWF0ZXJpYWw+IHtcbiAgICBjb25zdCBhcGkgPSBhd2FpdCB0aGlzLmdldEluaXRpYWxpemVkTm9kZUFQSSgpO1xuICAgIHJldHVybiB7XG4gICAgICBnZW5lc2lzSGFzaDogYXBpLmdlbmVzaXNIYXNoLnRvU3RyaW5nKCksXG4gICAgICBjaGFpbk5hbWU6IGFwaS5ydW50aW1lQ2hhaW4udG9TdHJpbmcoKSxcbiAgICAgIHNwZWNOYW1lOiBhcGkucnVudGltZVZlcnNpb24uc3BlY05hbWUudG9TdHJpbmcoKSBhcyBQb2xrYWRvdFNwZWNOYW1lVHlwZSxcbiAgICAgIHNwZWNWZXJzaW9uOiBhcGkucnVudGltZVZlcnNpb24uc3BlY1ZlcnNpb24udG9OdW1iZXIoKSxcbiAgICAgIHR4VmVyc2lvbjogYXBpLnJ1bnRpbWVWZXJzaW9uLnRyYW5zYWN0aW9uVmVyc2lvbi50b051bWJlcigpLFxuICAgICAgbWV0YWRhdGE6IGFwaS5ydW50aW1lTWV0YWRhdGEudG9IZXgoKSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkcyBhIGZ1bmRzIHJlY292ZXJ5IHRyYW5zYWN0aW9uIHdpdGhvdXQgQml0R29cbiAgICogQHBhcmFtIHtNUENSZWNvdmVyeU9wdGlvbnN9IHBhcmFtcyBwYXJhbWV0ZXJzIG5lZWRlZCB0byBjb25zdHJ1Y3QgYW5kXG4gICAqIChtYXliZSkgc2lnbiB0aGUgdHJhbnNhY3Rpb25cbiAgICogQHBhcmFtIHtFZGRzYVNpZ25pbmdNYXRlcmlhbH0gW3ByZWNvbXB1dGVkTWF0ZXJpYWxdIG9wdGlvbmFsIGRlY3J5cHRlZFxuICAgKiBtYXRlcmlhbCBmcm9tIHJlY292ZXJDb25zb2xpZGF0aW9uczsgbm9uLW1hdGNoaW5nIHZhbHVlcyBhcmUgaWdub3JlZFxuICAgKlxuICAgKiBAcmV0dXJucyB7TVBDVHh9IHRoZSBzZXJpYWxpemVkIHRyYW5zYWN0aW9uIGhleCBzdHJpbmcgYW5kIGluZGV4XG4gICAqIG9mIHRoZSBhZGRyZXNzIGJlaW5nIHN3ZXB0XG4gICAqL1xuICBhc3luYyByZWNvdmVyKHBhcmFtczogTVBDUmVjb3ZlcnlPcHRpb25zLCBwcmVjb21wdXRlZE1hdGVyaWFsPzogRWRkc2FTaWduaW5nTWF0ZXJpYWwpOiBQcm9taXNlPE1QQ1R4IHwgTVBDU3dlZXBUeHM+IHtcbiAgICBpZiAoIXBhcmFtcy5iaXRnb0tleSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIGJpdGdvS2V5Jyk7XG4gICAgfVxuICAgIGlmICghcGFyYW1zLnJlY292ZXJ5RGVzdGluYXRpb24gfHwgIXRoaXMuaXNWYWxpZEFkZHJlc3MocGFyYW1zLnJlY292ZXJ5RGVzdGluYXRpb24pKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgcmVjb3ZlcnlEZXN0aW5hdGlvbicpO1xuICAgIH1cblxuICAgIGNvbnN0IGJpdGdvS2V5ID0gcGFyYW1zLmJpdGdvS2V5LnJlcGxhY2UoL1xccy9nLCAnJyk7XG4gICAgY29uc3QgaXNVbnNpZ25lZFN3ZWVwID0gIXBhcmFtcy51c2VyS2V5ICYmICFwYXJhbXMuYmFja3VwS2V5ICYmICFwYXJhbXMud2FsbGV0UGFzc3BocmFzZTtcblxuICAgIGNvbnN0IE1QQyA9IGF3YWl0IEVERFNBTWV0aG9kcy5nZXRJbml0aWFsaXplZE1wY0luc3RhbmNlKCk7XG5cbiAgICBjb25zdCBpbmRleCA9IHBhcmFtcy5pbmRleCB8fCAwO1xuICAgIGNvbnN0IGN1cnJQYXRoID0gcGFyYW1zLnNlZWQgPyBnZXREZXJpdmF0aW9uUGF0aChwYXJhbXMuc2VlZCkgKyBgLyR7aW5kZXh9YCA6IGBtLyR7aW5kZXh9YDtcbiAgICBjb25zdCBhY2NvdW50SWQgPSBNUEMuZGVyaXZlVW5oYXJkZW5lZChiaXRnb0tleSwgY3VyclBhdGgpLnNsaWNlKDAsIDY0KTtcbiAgICBjb25zdCBzZW5kZXJBZGRyID0gdGhpcy5nZXRBZGRyZXNzRnJvbVB1YmxpY0tleShhY2NvdW50SWQpO1xuXG4gICAgbGV0IGFjY291bnRJbmZvO1xuICAgIGxldCBwYXJ0aWFsRmVlO1xuICAgIHRyeSB7XG4gICAgICBhY2NvdW50SW5mbyA9IGF3YWl0IHRoaXMuZ2V0QWNjb3VudEluZm8oc2VuZGVyQWRkcik7XG4gICAgICBwYXJ0aWFsRmVlID0gYXdhaXQgdGhpcy5nZXRGZWUocGFyYW1zLnJlY292ZXJ5RGVzdGluYXRpb24sIHNlbmRlckFkZHIsIGFjY291bnRJbmZvLmZyZWVCYWxhbmNlKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aHJvdyBuZXcgUmVjb3ZlcnlQcm92aWRlckVycm9yKGBGYWlsZWQgdG8gcXVlcnkgYWNjb3VudCBiYWxhbmNlIG9yIGZlZSBmb3IgJHtzZW5kZXJBZGRyfWAsIGUpO1xuICAgIH1cbiAgICBjb25zdCB7IG5vbmNlLCBmcmVlQmFsYW5jZSB9ID0gYWNjb3VudEluZm87XG5cbiAgICBjb25zdCB2YWx1ZSA9IG5ldyBCaWdOdW1iZXIoZnJlZUJhbGFuY2UpLm1pbnVzKG5ldyBCaWdOdW1iZXIocGFydGlhbEZlZSkpO1xuICAgIGlmICh2YWx1ZS5pc0xlc3NUaGFuT3JFcXVhbFRvKDApKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3JOb0lucHV0VG9SZWNvdmVyKCdEaWQgbm90IGZpbmQgYWRkcmVzcyB3aXRoIGZ1bmRzIHRvIHJlY292ZXInKTtcbiAgICB9XG5cbiAgICAvLyBmaXJzdCBidWlsZCB0aGUgdW5zaWduZWQgdHhuXG4gICAgbGV0IGhlYWRlckluZm87XG4gICAgbGV0IG1hdGVyaWFsO1xuICAgIHRyeSB7XG4gICAgICBoZWFkZXJJbmZvID0gYXdhaXQgdGhpcy5nZXRIZWFkZXJJbmZvKCk7XG4gICAgICBtYXRlcmlhbCA9IGF3YWl0IHRoaXMuZ2V0TWF0ZXJpYWwoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aHJvdyBuZXcgUmVjb3ZlcnlQcm92aWRlckVycm9yKCdGYWlsZWQgdG8gcXVlcnkgY2hhaW4gaGVhZGVyIG9yIG1hdGVyaWFsJywgZSk7XG4gICAgfVxuICAgIGNvbnN0IHsgaGVhZGVyTnVtYmVyLCBoZWFkZXJIYXNoIH0gPSBoZWFkZXJJbmZvO1xuICAgIGNvbnN0IHZhbGlkaXR5V2luZG93ID0geyBmaXJzdFZhbGlkOiBoZWFkZXJOdW1iZXIsIG1heER1cmF0aW9uOiB0aGlzLk1BWF9WQUxJRElUWV9EVVJBVElPTiB9O1xuXG4gICAgY29uc3QgdHhuQnVpbGRlciA9IHRoaXMuZ2V0QnVpbGRlcigpLmdldFRyYW5zZmVyQnVpbGRlcigpLm1hdGVyaWFsKG1hdGVyaWFsKTtcbiAgICB0eG5CdWlsZGVyXG4gICAgICAuc3dlZXAoZmFsc2UpXG4gICAgICAudG8oeyBhZGRyZXNzOiBwYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbiB9KVxuICAgICAgLnNlbmRlcih7IGFkZHJlc3M6IHNlbmRlckFkZHIgfSlcbiAgICAgIC52YWxpZGl0eSh2YWxpZGl0eVdpbmRvdylcbiAgICAgIC5yZWZlcmVuY2VCbG9jayhoZWFkZXJIYXNoKVxuICAgICAgLnNlcXVlbmNlSWQoeyBuYW1lOiAnTm9uY2UnLCBrZXl3b3JkOiAnbm9uY2UnLCB2YWx1ZTogbm9uY2UgfSlcbiAgICAgIC5mZWUoeyBhbW91bnQ6IDAsIHR5cGU6ICd0aXAnIH0pO1xuICAgIGNvbnN0IHVuc2lnbmVkVHJhbnNhY3Rpb24gPSAoYXdhaXQgdHhuQnVpbGRlci5idWlsZCgpKSBhcyBUcmFuc2FjdGlvbjtcblxuICAgIGxldCBzZXJpYWxpemVkVHggPSB1bnNpZ25lZFRyYW5zYWN0aW9uLnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG4gICAgaWYgKCFpc1Vuc2lnbmVkU3dlZXApIHtcbiAgICAgIGFzc2VydChwYXJhbXMudXNlcktleSwgJ21pc3NpbmcgdXNlcktleScpO1xuICAgICAgYXNzZXJ0KHBhcmFtcy5iYWNrdXBLZXksICdtaXNzaW5nIGJhY2t1cEtleScpO1xuICAgICAgYXNzZXJ0KHBhcmFtcy53YWxsZXRQYXNzcGhyYXNlLCAnbWlzc2luZyB3YWxsZXQgcGFzc3BocmFzZScpO1xuXG4gICAgICBjb25zdCBzaWduaW5nTWF0ZXJpYWwgPSBpc0VkZHNhU2lnbmluZ01hdGVyaWFsKHByZWNvbXB1dGVkTWF0ZXJpYWwpXG4gICAgICAgID8gcHJlY29tcHV0ZWRNYXRlcmlhbFxuICAgICAgICA6IGF3YWl0IHRoaXMuZ2V0RWRkc2FTaWduaW5nTWF0ZXJpYWwocGFyYW1zLnVzZXJLZXksIHBhcmFtcy53YWxsZXRQYXNzcGhyYXNlKTtcbiAgICAgIGF3YWl0IHRoaXMuYWRkUmVjb3ZlcnlTaWduYXR1cmUoXG4gICAgICAgIHNpZ25pbmdNYXRlcmlhbCxcbiAgICAgICAgcGFyYW1zLmJhY2t1cEtleS5yZXBsYWNlKC9cXHMvZywgJycpLFxuICAgICAgICBwYXJhbXMud2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgdHhuQnVpbGRlcixcbiAgICAgICAgYWNjb3VudElkLFxuICAgICAgICB1bnNpZ25lZFRyYW5zYWN0aW9uLFxuICAgICAgICBjdXJyUGF0aCxcbiAgICAgICAgYml0Z29LZXlcbiAgICAgICk7XG4gICAgICBjb25zdCBzaWduZWRUcmFuc2FjdGlvbiA9IGF3YWl0IHR4bkJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIHNlcmlhbGl6ZWRUeCA9IHNpZ25lZFRyYW5zYWN0aW9uLnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHZhbHVlID0gbmV3IEJpZ051bWJlcihmcmVlQmFsYW5jZSk7XG4gICAgICBjb25zdCB3YWxsZXRDb2luID0gdGhpcy5nZXRDaGFpbigpO1xuICAgICAgY29uc3QgaW5wdXRzID0gW1xuICAgICAgICB7XG4gICAgICAgICAgYWRkcmVzczogdW5zaWduZWRUcmFuc2FjdGlvbi5pbnB1dHNbMF0uYWRkcmVzcyxcbiAgICAgICAgICB2YWx1ZVN0cmluZzogdmFsdWUudG9TdHJpbmcoKSxcbiAgICAgICAgICB2YWx1ZTogdmFsdWUudG9OdW1iZXIoKSxcbiAgICAgICAgfSxcbiAgICAgIF07XG4gICAgICBjb25zdCBvdXRwdXRzID0gW1xuICAgICAgICB7XG4gICAgICAgICAgYWRkcmVzczogdW5zaWduZWRUcmFuc2FjdGlvbi5vdXRwdXRzWzBdLmFkZHJlc3MsXG4gICAgICAgICAgdmFsdWVTdHJpbmc6IHZhbHVlLnRvU3RyaW5nKCksXG4gICAgICAgICAgY29pbk5hbWU6IHdhbGxldENvaW4sXG4gICAgICAgIH0sXG4gICAgICBdO1xuICAgICAgY29uc3Qgc3BlbmRBbW91bnQgPSB2YWx1ZS50b1N0cmluZygpO1xuICAgICAgY29uc3QgcGFyc2VkVHggPSB7IGlucHV0czogaW5wdXRzLCBvdXRwdXRzOiBvdXRwdXRzLCBzcGVuZEFtb3VudDogc3BlbmRBbW91bnQsIHR5cGU6ICcnIH07XG4gICAgICBjb25zdCBmZWVJbmZvID0geyBmZWU6IDAsIGZlZVN0cmluZzogJzAnIH07XG4gICAgICBjb25zdCB0cmFuc2FjdGlvbjogTVBDVHggPSB7XG4gICAgICAgIHNlcmlhbGl6ZWRUeDogc2VyaWFsaXplZFR4LFxuICAgICAgICBzY2FuSW5kZXg6IGluZGV4LFxuICAgICAgICBjb2luOiB3YWxsZXRDb2luLFxuICAgICAgICBzaWduYWJsZUhleDogdW5zaWduZWRUcmFuc2FjdGlvbi5zaWduYWJsZVBheWxvYWQudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgICBkZXJpdmF0aW9uUGF0aDogY3VyclBhdGgsXG4gICAgICAgIHBhcnNlZFR4OiBwYXJzZWRUeCxcbiAgICAgICAgZmVlSW5mbzogZmVlSW5mbyxcbiAgICAgICAgY29pblNwZWNpZmljOiB7IC4uLnZhbGlkaXR5V2luZG93LCBjb21tb25LZXljaGFpbjogYml0Z29LZXkgfSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHVuc2lnbmVkVHg6IE1QQ1Vuc2lnbmVkVHggPSB7IHVuc2lnbmVkVHg6IHRyYW5zYWN0aW9uLCBzaWduYXR1cmVTaGFyZXM6IFtdIH07XG4gICAgICBjb25zdCB0cmFuc2FjdGlvbnM6IE1QQ1Vuc2lnbmVkVHhbXSA9IFt1bnNpZ25lZFR4XTtcbiAgICAgIGNvbnN0IHR4UmVxdWVzdDogUmVjb3ZlcnlUeFJlcXVlc3QgPSB7XG4gICAgICAgIHRyYW5zYWN0aW9uczogdHJhbnNhY3Rpb25zLFxuICAgICAgICB3YWxsZXRDb2luOiB3YWxsZXRDb2luLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHR4UmVxdWVzdHM6IE1QQ1N3ZWVwVHhzID0geyB0eFJlcXVlc3RzOiBbdHhSZXF1ZXN0XSB9O1xuICAgICAgcmV0dXJuIHR4UmVxdWVzdHM7XG4gICAgfVxuICAgIGNvbnN0IHRyYW5zYWN0aW9uOiBNUENUeCA9IHsgc2VyaWFsaXplZFR4OiBzZXJpYWxpemVkVHgsIHNjYW5JbmRleDogaW5kZXggfTtcbiAgICByZXR1cm4gdHJhbnNhY3Rpb247XG4gIH1cblxuICAvKipcbiAgICogQnVpbGRzIG5hdGl2ZSBET1QgcmVjb3ZlcmllcyBvZiByZWNlaXZlIGFkZHJlc3NlcyBpbiBiYXRjaCB3aXRob3V0IEJpdEdvLlxuICAgKiBGdW5kcyB3aWxsIGJlIHJlY292ZXJlZCB0byBiYXNlIGFkZHJlc3MgZmlyc3QuIFlvdSBuZWVkIHRvIGluaXRpYXRlIGFub3RoZXIgc3dlZXAgdHhuIGFmdGVyIHRoYXQuXG4gICAqXG4gICAqIEBwYXJhbSB7TVBDQ29uc29saWRhdGlvblJlY292ZXJ5T3B0aW9uc30gcGFyYW1zIC0gb3B0aW9ucyBmb3IgY29uc29saWRhdGlvbiByZWNvdmVyeS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IFtwYXJhbXMuc3RhcnRpbmdTY2FuSW5kZXhdIC0gcmVjZWl2ZSBhZGRyZXNzIGluZGV4IHRvIHN0YXJ0IHNjYW5uaW5nIGZyb20uIGRlZmF1bHQgdG8gMSAoaW5jbHVzaXZlKS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IFtwYXJhbXMuZW5kaW5nU2NhbkluZGV4XSAtIHJlY2VpdmUgYWRkcmVzcyBpbmRleCB0byBlbmQgc2Nhbm5pbmcgYXQuIGRlZmF1bHQgdG8gc3RhcnRpbmdTY2FuSW5kZXggKyAyMCAoZXhjbHVzaXZlKS5cbiAgICovXG4gIGFzeW5jIHJlY292ZXJDb25zb2xpZGF0aW9ucyhwYXJhbXM6IE1QQ0NvbnNvbGlkYXRpb25SZWNvdmVyeU9wdGlvbnMpOiBQcm9taXNlPE1QQ1R4cyB8IE1QQ1N3ZWVwVHhzPiB7XG4gICAgY29uc3QgaXNVbnNpZ25lZFN3ZWVwID0gIXBhcmFtcy51c2VyS2V5ICYmICFwYXJhbXMuYmFja3VwS2V5ICYmICFwYXJhbXMud2FsbGV0UGFzc3BocmFzZTtcbiAgICBjb25zdCBzdGFydElkeCA9IHBhcmFtcy5zdGFydGluZ1NjYW5JbmRleCB8fCAxO1xuICAgIGNvbnN0IGVuZElkeCA9IHBhcmFtcy5lbmRpbmdTY2FuSW5kZXggfHwgc3RhcnRJZHggKyBERUZBVUxUX1NDQU5fRkFDVE9SO1xuXG4gICAgaWYgKHN0YXJ0SWR4IDwgMSB8fCBlbmRJZHggPD0gc3RhcnRJZHggfHwgZW5kSWR4IC0gc3RhcnRJZHggPiAxMCAqIERFRkFVTFRfU0NBTl9GQUNUT1IpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYEludmFsaWQgc3RhcnRpbmcgb3IgZW5kaW5nIGluZGV4IHRvIHNjYW4gZm9yIGFkZHJlc3Nlcy4gc3RhcnRpbmdTY2FuSW5kZXg6ICR7c3RhcnRJZHh9LCBlbmRpbmdTY2FuSW5kZXg6ICR7ZW5kSWR4fS5gXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IGJpdGdvS2V5ID0gcGFyYW1zLmJpdGdvS2V5LnJlcGxhY2UoL1xccy9nLCAnJyk7XG4gICAgY29uc3QgTVBDID0gYXdhaXQgRUREU0FNZXRob2RzLmdldEluaXRpYWxpemVkTXBjSW5zdGFuY2UoKTtcbiAgICBjb25zdCBiYXNlSW5kZXggPSAwO1xuICAgIGNvbnN0IGJhc2VQYXRoID0gcGFyYW1zLnNlZWQgPyBnZXREZXJpdmF0aW9uUGF0aChwYXJhbXMuc2VlZCkgKyBgLyR7YmFzZUluZGV4fWAgOiBgbS8ke2Jhc2VJbmRleH1gO1xuICAgIGNvbnN0IGFjY291bnRJZCA9IE1QQy5kZXJpdmVVbmhhcmRlbmVkKGJpdGdvS2V5LCBiYXNlUGF0aCkuc2xpY2UoMCwgNjQpO1xuICAgIGNvbnN0IGJhc2VBZGRyZXNzID0gdGhpcy5nZXRBZGRyZXNzRnJvbVB1YmxpY0tleShhY2NvdW50SWQpO1xuXG4gICAgLy8gRGV0ZWN0IHNpZ25pbmcgbWF0ZXJpYWwgb25jZSB0byBhdm9pZCByZS1kZWNyeXB0aW5nIHRoZSBrZXljYXJkIG9uIGV2ZXJ5IGxvb3AgaXRlcmF0aW9uLlxuICAgIGNvbnN0IHNpZ25pbmdNYXRlcmlhbCA9XG4gICAgICBwYXJhbXMud2FsbGV0UGFzc3BocmFzZSAmJiBwYXJhbXMudXNlcktleVxuICAgICAgICA/IGF3YWl0IHRoaXMuZ2V0RWRkc2FTaWduaW5nTWF0ZXJpYWwocGFyYW1zLnVzZXJLZXkucmVwbGFjZSgvXFxzL2csICcnKSwgcGFyYW1zLndhbGxldFBhc3NwaHJhc2UpXG4gICAgICAgIDogdW5kZWZpbmVkO1xuXG4gICAgY29uc3QgY29uc29saWRhdGlvblRyYW5zYWN0aW9uczogYW55W10gPSBbXTtcbiAgICBsZXQgbGFzdFNjYW5JbmRleCA9IHN0YXJ0SWR4O1xuICAgIGZvciAobGV0IGkgPSBzdGFydElkeDsgaSA8IGVuZElkeDsgaSsrKSB7XG4gICAgICBjb25zdCByZWNvdmVyUGFyYW1zOiBNUENSZWNvdmVyeU9wdGlvbnMgPSB7XG4gICAgICAgIHVzZXJLZXk6IHBhcmFtcy51c2VyS2V5LFxuICAgICAgICBiYWNrdXBLZXk6IHBhcmFtcy5iYWNrdXBLZXksXG4gICAgICAgIGJpdGdvS2V5OiBwYXJhbXMuYml0Z29LZXksXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IHBhcmFtcy53YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiBiYXNlQWRkcmVzcyxcbiAgICAgICAgc2VlZDogcGFyYW1zLnNlZWQsXG4gICAgICAgIGluZGV4OiBpLFxuICAgICAgfTtcblxuICAgICAgbGV0IHJlY292ZXJ5VHJhbnNhY3Rpb247XG4gICAgICB0cnkge1xuICAgICAgICByZWNvdmVyeVRyYW5zYWN0aW9uID0gYXdhaXQgdGhpcy5yZWNvdmVyKHJlY292ZXJQYXJhbXMsIHNpZ25pbmdNYXRlcmlhbCk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGlmIChlIGluc3RhbmNlb2YgRXJyb3JOb0lucHV0VG9SZWNvdmVyKSB7XG4gICAgICAgICAgbGFzdFNjYW5JbmRleCA9IGk7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGlzVW5zaWduZWRTd2VlcCkge1xuICAgICAgICBjb25zb2xpZGF0aW9uVHJhbnNhY3Rpb25zLnB1c2goKHJlY292ZXJ5VHJhbnNhY3Rpb24gYXMgTVBDU3dlZXBUeHMpLnR4UmVxdWVzdHNbMF0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc29saWRhdGlvblRyYW5zYWN0aW9ucy5wdXNoKHJlY292ZXJ5VHJhbnNhY3Rpb24pO1xuICAgICAgfVxuICAgICAgbGFzdFNjYW5JbmRleCA9IGk7XG4gICAgfVxuXG4gICAgaWYgKGNvbnNvbGlkYXRpb25UcmFuc2FjdGlvbnMubGVuZ3RoID09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvck5vSW5wdXRUb1JlY292ZXIoJ0RpZCBub3QgZmluZCBhbiBhZGRyZXNzIHdpdGggZnVuZHMgdG8gcmVjb3ZlcicpO1xuICAgIH1cblxuICAgIGlmIChpc1Vuc2lnbmVkU3dlZXApIHtcbiAgICAgIC8vIGxhc3RTY2FuSW5kZXggd2lsbCBiZSB1c2VkIHRvIGluZm9ybSB1c2VyIHRoZSBsYXN0IGFkZHJlc3MgaW5kZXggc2Nhbm5lZCBmb3IgYXZhaWxhYmxlIGZ1bmRzIChzbyB0aGV5IGNhblxuICAgICAgLy8gYXBwcm9wcmlhdGVseSBhZGp1c3QgdGhlIHNjYW4gcmFuZ2Ugb24gdGhlIG5leHQgaXRlcmF0aW9uIG9mIGNvbnNvbGlkYXRpb24gcmVjb3ZlcmllcykuIEluIHRoZSBjYXNlIG9mIHVuc2lnbmVkXG4gICAgICAvLyBzd2VlcCBjb25zb2xpZGF0aW9ucywgdGhpcyBsYXN0U2NhbkluZGV4IHdpbGwgYmUgcHJvdmlkZWQgaW4gdGhlIGNvaW5TcGVjaWZpYyBvZiB0aGUgbGFzdCB0eG4gbWFkZS5cbiAgICAgIGNvbnN0IGxhc3RUcmFuc2FjdGlvbkNvaW5TcGVjaWZpYyA9IHtcbiAgICAgICAgZmlyc3RWYWxpZDpcbiAgICAgICAgICBjb25zb2xpZGF0aW9uVHJhbnNhY3Rpb25zW2NvbnNvbGlkYXRpb25UcmFuc2FjdGlvbnMubGVuZ3RoIC0gMV0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguY29pblNwZWNpZmljXG4gICAgICAgICAgICAuZmlyc3RWYWxpZCxcbiAgICAgICAgbWF4RHVyYXRpb246XG4gICAgICAgICAgY29uc29saWRhdGlvblRyYW5zYWN0aW9uc1tjb25zb2xpZGF0aW9uVHJhbnNhY3Rpb25zLmxlbmd0aCAtIDFdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LmNvaW5TcGVjaWZpY1xuICAgICAgICAgICAgLm1heER1cmF0aW9uLFxuICAgICAgICBjb21tb25LZXljaGFpbjpcbiAgICAgICAgICBjb25zb2xpZGF0aW9uVHJhbnNhY3Rpb25zW2NvbnNvbGlkYXRpb25UcmFuc2FjdGlvbnMubGVuZ3RoIC0gMV0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguY29pblNwZWNpZmljXG4gICAgICAgICAgICAuY29tbW9uS2V5Y2hhaW4sXG4gICAgICAgIGxhc3RTY2FuSW5kZXg6IGxhc3RTY2FuSW5kZXgsXG4gICAgICB9O1xuICAgICAgY29uc29saWRhdGlvblRyYW5zYWN0aW9uc1tjb25zb2xpZGF0aW9uVHJhbnNhY3Rpb25zLmxlbmd0aCAtIDFdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LmNvaW5TcGVjaWZpYyA9XG4gICAgICAgIGxhc3RUcmFuc2FjdGlvbkNvaW5TcGVjaWZpYztcbiAgICAgIGNvbnN0IGNvbnNvbGlkYXRpb25Td2VlcFRyYW5zYWN0aW9uczogTVBDU3dlZXBUeHMgPSB7IHR4UmVxdWVzdHM6IGNvbnNvbGlkYXRpb25UcmFuc2FjdGlvbnMgfTtcbiAgICAgIHJldHVybiBjb25zb2xpZGF0aW9uU3dlZXBUcmFuc2FjdGlvbnM7XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgdHJhbnNhY3Rpb25zOiBjb25zb2xpZGF0aW9uVHJhbnNhY3Rpb25zLCBsYXN0U2NhbkluZGV4IH07XG4gIH1cblxuICAvKiogaW5oZXJpdGVkIGRvYyAqL1xuICBhc3luYyBjcmVhdGVCcm9hZGNhc3RhYmxlU3dlZXBUcmFuc2FjdGlvbihwYXJhbXM6IE1QQ1N3ZWVwUmVjb3ZlcnlPcHRpb25zKTogUHJvbWlzZTxNUENUeHM+IHtcbiAgICBjb25zdCByZXEgPSBwYXJhbXMuc2lnbmF0dXJlU2hhcmVzO1xuICAgIGNvbnN0IGJyb2FkY2FzdGFibGVUcmFuc2FjdGlvbnM6IE1QQ1R4W10gPSBbXTtcbiAgICBsZXQgbGFzdFNjYW5JbmRleCA9IDA7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJlcS5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgTVBDID0gYXdhaXQgRUREU0FNZXRob2RzLmdldEluaXRpYWxpemVkTXBjSW5zdGFuY2UoKTtcbiAgICAgIGNvbnN0IHRyYW5zYWN0aW9uID0gcmVxW2ldLnR4UmVxdWVzdC50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeDtcbiAgICAgIGNvbnN0IG92YyA9IHJlcVtpXS5vdmM/LlswXTtcbiAgICAgIGNvbnN0IG1wY3YyU2lnbmF0dXJlSGV4ID0gb3ZjPy5lZGRzYU1wY3YyU2lnbmF0dXJlO1xuICAgICAgaWYgKCFvdmMgfHwgKCFtcGN2MlNpZ25hdHVyZUhleCAmJiAhb3ZjLmVkZHNhU2lnbmF0dXJlKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3Npbmcgc2lnbmF0dXJlKHMpJyk7XG4gICAgICB9XG4gICAgICBpZiAoIXRyYW5zYWN0aW9uLnNpZ25hYmxlSGV4KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyBzaWduYWJsZSBoZXgnKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IG1lc3NhZ2VCdWZmZXIgPSBCdWZmZXIuZnJvbSh0cmFuc2FjdGlvbi5zaWduYWJsZUhleCEsICdoZXgnKTtcbiAgICAgIGlmIChcbiAgICAgICAgIXRyYW5zYWN0aW9uLmNvaW5TcGVjaWZpYyB8fFxuICAgICAgICAhdHJhbnNhY3Rpb24uY29pblNwZWNpZmljPy5maXJzdFZhbGlkIHx8XG4gICAgICAgICF0cmFuc2FjdGlvbi5jb2luU3BlY2lmaWM/Lm1heER1cmF0aW9uXG4gICAgICApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIHZhbGlkaXR5IHdpbmRvdycpO1xuICAgICAgfVxuICAgICAgY29uc3QgdmFsaWRpdHlXaW5kb3cgPSB7XG4gICAgICAgIGZpcnN0VmFsaWQ6IHRyYW5zYWN0aW9uLmNvaW5TcGVjaWZpYz8uZmlyc3RWYWxpZCxcbiAgICAgICAgbWF4RHVyYXRpb246IHRyYW5zYWN0aW9uLmNvaW5TcGVjaWZpYz8ubWF4RHVyYXRpb24sXG4gICAgICB9O1xuICAgICAgY29uc3QgbWF0ZXJpYWwgPSBhd2FpdCB0aGlzLmdldE1hdGVyaWFsKCk7XG4gICAgICBpZiAoIXRyYW5zYWN0aW9uLmNvaW5TcGVjaWZpYz8uY29tbW9uS2V5Y2hhaW4pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIGNvbW1vbiBrZXljaGFpbicpO1xuICAgICAgfVxuICAgICAgY29uc3QgY29tbW9uS2V5Y2hhaW4gPSB0cmFuc2FjdGlvbi5jb2luU3BlY2lmaWMhLmNvbW1vbktleWNoYWluISBhcyBzdHJpbmc7XG4gICAgICBpZiAoIXRyYW5zYWN0aW9uLmRlcml2YXRpb25QYXRoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyBkZXJpdmF0aW9uIHBhdGgnKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGRlcml2YXRpb25QYXRoID0gdHJhbnNhY3Rpb24uZGVyaXZhdGlvblBhdGggYXMgc3RyaW5nO1xuICAgICAgY29uc3QgYWNjb3VudElkID0gTVBDLmRlcml2ZVVuaGFyZGVuZWQoY29tbW9uS2V5Y2hhaW4sIGRlcml2YXRpb25QYXRoKS5zbGljZSgwLCA2NCk7XG4gICAgICBjb25zdCBzZW5kZXJBZGRyID0gdGhpcy5nZXRBZGRyZXNzRnJvbVB1YmxpY0tleShhY2NvdW50SWQpO1xuICAgICAgbGV0IHNpZ25hdHVyZUhleDogQnVmZmVyO1xuICAgICAgaWYgKG1wY3YyU2lnbmF0dXJlSGV4KSB7XG4gICAgICAgIC8vIE1QQ3YyIChPVkMgNS1wYXNzKTogcmF3IDY0LWJ5dGUgRWQyNTUxOSBzaWduYXR1cmUuIFZlcmlmeSBhZ2FpbnN0IHRoZVxuICAgICAgICAvLyBzYW1lIGRlcml2ZWQgcHVibGljIGtleSB0aGUgdHJhbnNhY3Rpb24gaXMgc2lnbmVkIHVuZGVyLCB0aGVuIGVtYmVkIGFzLWlzLlxuICAgICAgICBjb25zdCBzaWduYXR1cmUgPSBCdWZmZXIuZnJvbShtcGN2MlNpZ25hdHVyZUhleCwgJ2hleCcpO1xuICAgICAgICBjb25zdCBpc1ZhbGlkID0gbmFjbC5zaWduLmRldGFjaGVkLnZlcmlmeShtZXNzYWdlQnVmZmVyLCBzaWduYXR1cmUsIEJ1ZmZlci5mcm9tKGFjY291bnRJZCwgJ2hleCcpKTtcbiAgICAgICAgaWYgKCFpc1ZhbGlkKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHNpZ25hdHVyZScpO1xuICAgICAgICB9XG4gICAgICAgIHNpZ25hdHVyZUhleCA9IHNpZ25hdHVyZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IE1QQy52ZXJpZnkobWVzc2FnZUJ1ZmZlciwgb3ZjLmVkZHNhU2lnbmF0dXJlKTtcbiAgICAgICAgaWYgKCFyZXN1bHQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgc2lnbmF0dXJlJyk7XG4gICAgICAgIH1cbiAgICAgICAgc2lnbmF0dXJlSGV4ID0gQnVmZmVyLmNvbmNhdChbXG4gICAgICAgICAgQnVmZmVyLmZyb20ob3ZjLmVkZHNhU2lnbmF0dXJlLlIsICdoZXgnKSxcbiAgICAgICAgICBCdWZmZXIuZnJvbShvdmMuZWRkc2FTaWduYXR1cmUuc2lnbWEsICdoZXgnKSxcbiAgICAgICAgXSk7XG4gICAgICB9XG4gICAgICBjb25zdCB0eG5CdWlsZGVyID0gdGhpcy5nZXRCdWlsZGVyKClcbiAgICAgICAgLm1hdGVyaWFsKG1hdGVyaWFsKVxuICAgICAgICAuZnJvbSh0cmFuc2FjdGlvbi5zZXJpYWxpemVkVHggYXMgc3RyaW5nKVxuICAgICAgICAuc2VuZGVyKHsgYWRkcmVzczogc2VuZGVyQWRkciB9KVxuICAgICAgICAudmFsaWRpdHkodmFsaWRpdHlXaW5kb3cpO1xuICAgICAgY29uc3QgZG90S2V5UGFpciA9IG5ldyBEb3RLZXlQYWlyKHsgcHViOiBhY2NvdW50SWQgfSk7XG4gICAgICB0eG5CdWlsZGVyLmFkZFNpZ25hdHVyZSh7IHB1YjogZG90S2V5UGFpci5nZXRLZXlzKCkucHViIH0sIHNpZ25hdHVyZUhleCk7XG4gICAgICBjb25zdCBzaWduZWRUcmFuc2FjdGlvbiA9IGF3YWl0IHR4bkJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIGNvbnN0IHNlcmlhbGl6ZWRUeCA9IHNpZ25lZFRyYW5zYWN0aW9uLnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG5cbiAgICAgIGJyb2FkY2FzdGFibGVUcmFuc2FjdGlvbnMucHVzaCh7XG4gICAgICAgIHNlcmlhbGl6ZWRUeDogc2VyaWFsaXplZFR4LFxuICAgICAgICBzY2FuSW5kZXg6IHRyYW5zYWN0aW9uLnNjYW5JbmRleCxcbiAgICAgIH0pO1xuXG4gICAgICBpZiAoaSA9PT0gcmVxLmxlbmd0aCAtIDEgJiYgdHJhbnNhY3Rpb24uY29pblNwZWNpZmljIS5sYXN0U2NhbkluZGV4KSB7XG4gICAgICAgIGxhc3RTY2FuSW5kZXggPSB0cmFuc2FjdGlvbi5jb2luU3BlY2lmaWMhLmxhc3RTY2FuSW5kZXggYXMgbnVtYmVyO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4geyB0cmFuc2FjdGlvbnM6IGJyb2FkY2FzdGFibGVUcmFuc2FjdGlvbnMsIGxhc3RTY2FuSW5kZXggfTtcbiAgfVxuXG4gIGFzeW5jIHBhcnNlVHJhbnNhY3Rpb24ocGFyYW1zOiBQYXJzZVRyYW5zYWN0aW9uT3B0aW9ucyk6IFByb21pc2U8UGFyc2VkVHJhbnNhY3Rpb24+IHtcbiAgICByZXR1cm4ge307XG4gIH1cblxuICBhc3luYyBpc1dhbGxldEFkZHJlc3MocGFyYW1zOiBUc3NWZXJpZnlBZGRyZXNzT3B0aW9ucyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIHJldHVybiB2ZXJpZnlFZGRzYVRzc1dhbGxldEFkZHJlc3MoXG4gICAgICBwYXJhbXMsXG4gICAgICAoYWRkcmVzcykgPT4gdGhpcy5pc1ZhbGlkQWRkcmVzcyhhZGRyZXNzKSxcbiAgICAgIChwdWJsaWNLZXkpID0+IHRoaXMuZ2V0QWRkcmVzc0Zyb21QdWJsaWNLZXkocHVibGljS2V5KVxuICAgICk7XG4gIH1cblxuICBhc3luYyB2ZXJpZnlUcmFuc2FjdGlvbihwYXJhbXM6IFZlcmlmeVRyYW5zYWN0aW9uT3B0aW9ucyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGNvbnN0IHsgdHhQcmVidWlsZCwgdHhQYXJhbXMsIHZlcmlmaWNhdGlvbiwgd2FsbGV0LCByZXFJZCB9ID0gcGFyYW1zO1xuICAgIGlmICghdHhQYXJhbXMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyB0eFBhcmFtcycpO1xuICAgIH1cblxuICAgIGlmICghdHhQcmVidWlsZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIHR4UHJlYnVpbGQnKTtcbiAgICB9XG5cbiAgICBpZiAoIXR4UHJlYnVpbGQudHhIZXgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyB0eEhleCBpbiB0eFByZWJ1aWxkJyk7XG4gICAgfVxuXG4gICAgY29uc3QgY2hhaW4gPSB0aGlzLmdldENoYWluKCk7XG4gICAgbGV0IHR4VG86IHN0cmluZztcbiAgICBsZXQgdHhBbW91bnQ6IHN0cmluZztcbiAgICBsZXQgaXNTd2VlcDogYm9vbGVhbjtcblxuICAgIGlmIChjaGFpbiA9PT0gJ3Rkb3QnKSB7XG4gICAgICBjb25zdCBtYXRlcmlhbCA9IFV0aWxzLmRlZmF1bHQuZ2V0TWF0ZXJpYWwoY29pbnMuZ2V0KGNoYWluKSk7XG4gICAgICBjb25zdCBleHBsYWluZWQgPSBleHBsYWluRG90VHJhbnNhY3Rpb24oeyB0eEhleDogdHhQcmVidWlsZC50eEhleCwgbWF0ZXJpYWwgfSk7XG4gICAgICB0eFRvID0gZXhwbGFpbmVkLm91dHB1dHNbMF0/LmFkZHJlc3MgPz8gJyc7XG4gICAgICB0eEFtb3VudCA9IFN0cmluZyhleHBsYWluZWQub3V0cHV0c1swXT8uYW1vdW50ID8/ICcwJyk7XG4gICAgICBpc1N3ZWVwID0gZXhwbGFpbmVkLm1ldGhvZE5hbWUgPT09ICdiYWxhbmNlcy50cmFuc2ZlckFsbCc7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGZhY3RvcnkgPSB0aGlzLmdldEJ1aWxkZXIoKTtcbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGZhY3RvcnkuZnJvbSh0eFByZWJ1aWxkLnR4SGV4KSBhcyB1bmtub3duIGFzIE5hdGl2ZVRyYW5zZmVyQnVpbGRlcjtcbiAgICAgIHR4VG8gPSB0eEJ1aWxkZXJbJ190byddO1xuICAgICAgdHhBbW91bnQgPSB0eEJ1aWxkZXJbJ19hbW91bnQnXTtcbiAgICAgIGlzU3dlZXAgPSB0eEJ1aWxkZXJbJ19zd2VlcEZyZWVCYWxhbmNlJ10gPT09IHRydWU7XG4gICAgfVxuXG4gICAgaWYgKHZlcmlmaWNhdGlvbj8uY29uc29saWRhdGlvblRvQmFzZUFkZHJlc3MpIHtcbiAgICAgIGNvbnN0IGJhc2VBZGRyZXNzID0gd2FsbGV0Py5jb2luU3BlY2lmaWMoKT8ucm9vdEFkZHJlc3MgfHwgd2FsbGV0Py5jb2luU3BlY2lmaWMoKT8uYmFzZUFkZHJlc3M7XG4gICAgICBpZiAoIWJhc2VBZGRyZXNzKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignVW5hYmxlIHRvIGRldGVybWluZSBiYXNlIGFkZHJlc3MgZm9yIGNvbnNvbGlkYXRpb24nKTtcbiAgICAgIH1cbiAgICAgIGlmICh0eFRvICE9PSBiYXNlQWRkcmVzcykge1xuICAgICAgICB0aHJvdyBuZXcgVHhJbnRlbnRNaXNtYXRjaFJlY2lwaWVudEVycm9yKFxuICAgICAgICAgIGBUcmFuc2FjdGlvbiBkZXN0aW5hdGlvbiBhZGRyZXNzICR7dHhUb30gZG9lcyBub3QgbWF0Y2ggd2FsbGV0IGJhc2UgYWRkcmVzcyAke2Jhc2VBZGRyZXNzfWAsXG4gICAgICAgICAgcmVxSWQsXG4gICAgICAgICAgW3R4UGFyYW1zXSxcbiAgICAgICAgICB0eFByZWJ1aWxkLnR4SGV4LFxuICAgICAgICAgIFt7IGFkZHJlc3M6IHR4VG8sIGFtb3VudDogdHhBbW91bnQgfV1cbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodHhQYXJhbXMucmVjaXBpZW50cyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAodHhQYXJhbXMucmVjaXBpZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIHJlY2lwaWVudHMgaW4gdHhQYXJhbXMnKTtcbiAgICAgIH1cblxuICAgICAgaWYgKEFycmF5LmlzQXJyYXkodHhQYXJhbXMucmVjaXBpZW50cykgJiYgdHhQYXJhbXMucmVjaXBpZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgJHt0aGlzLmdldENoYWluKCl9IGRvZXNuJ3Qgc3VwcG9ydCBzZW5kaW5nIHRvIG1vcmUgdGhhbiAxIGRlc3RpbmF0aW9uIGFkZHJlc3Mgd2l0aGluIGEgc2luZ2xlIHRyYW5zYWN0aW9uLiBUcnkgYWdhaW4sIHVzaW5nIG9ubHkgYSBzaW5nbGUgcmVjaXBpZW50LmBcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHR4UGFyYW1zLnJlY2lwaWVudHNbMF0uYWRkcmVzcyAhPT0gdHhUbykge1xuICAgICAgICB0aHJvdyBuZXcgVHhJbnRlbnRNaXNtYXRjaFJlY2lwaWVudEVycm9yKFxuICAgICAgICAgIGBSZWNpcGllbnQgYWRkcmVzcyAke3R4UGFyYW1zLnJlY2lwaWVudHNbMF0uYWRkcmVzc30gZG9lcyBub3QgbWF0Y2ggdHJhbnNhY3Rpb24gZGVzdGluYXRpb24gYWRkcmVzcyAke3R4VG99YCxcbiAgICAgICAgICByZXFJZCxcbiAgICAgICAgICBbdHhQYXJhbXNdLFxuICAgICAgICAgIHR4UHJlYnVpbGQudHhIZXgsXG4gICAgICAgICAgW3sgYWRkcmVzczogdHhUbywgYW1vdW50OiB0eEFtb3VudCB9XVxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWlzU3dlZXAgJiYgdHhQYXJhbXMucmVjaXBpZW50c1swXS5hbW91bnQgIT09IHR4QW1vdW50KSB7XG4gICAgICAgIHRocm93IG5ldyBUeEludGVudE1pc21hdGNoUmVjaXBpZW50RXJyb3IoXG4gICAgICAgICAgYFJlY2lwaWVudCBhbW91bnQgJHt0eFBhcmFtcy5yZWNpcGllbnRzWzBdLmFtb3VudH0gZG9lcyBub3QgbWF0Y2ggdHJhbnNhY3Rpb24gYW1vdW50ICR7dHhBbW91bnR9YCxcbiAgICAgICAgICByZXFJZCxcbiAgICAgICAgICBbdHhQYXJhbXNdLFxuICAgICAgICAgIHR4UHJlYnVpbGQudHhIZXgsXG4gICAgICAgICAgW3sgYWRkcmVzczogdHhUbywgYW1vdW50OiB0eEFtb3VudCB9XVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGdldEFkZHJlc3NGcm9tUHVibGljS2V5KFB1YmtleTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gbmV3IERvdEtleVBhaXIoeyBwdWI6IFB1YmtleSB9KS5nZXRBZGRyZXNzKFV0aWxzLmRlZmF1bHQuZ2V0QWRkcmVzc0Zvcm1hdCh0aGlzLmdldENoYWluKCkgYXMgRG90QXNzZXRUeXBlcykpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRCdWlsZGVyKCk6IFRyYW5zYWN0aW9uQnVpbGRlckZhY3Rvcnkge1xuICAgIHJldHVybiBuZXcgVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeShjb2lucy5nZXQodGhpcy5nZXRDaGFpbigpKSk7XG4gIH1cblxuICAvKipcbiAgICogRGV0ZWN0cyB3aGV0aGVyIGEga2V5Y2FyZCdzIGRlY3J5cHRlZCBwbGFpbnRleHQgaXMgTVBDdjEgSlNPTiBvciBNUEN2MiBDQk9SLlxuICAgKiBVbnNpZ25lZCBzd2VlcHMgKG5vIHdhbGxldFBhc3NwaHJhc2UpIGhhdmUgbm8ga2V5Y2FyZCB0byBpbnNwZWN0IGFuZCBkZWZhdWx0IHRvIE1QQ3YxLlxuICAgKi9cbiAgcHJvdGVjdGVkIGFzeW5jIGdldEVkZHNhU2lnbmluZ01hdGVyaWFsKHVzZXJLZXk6IHN0cmluZywgd2FsbGV0UGFzc3BocmFzZTogc3RyaW5nKTogUHJvbWlzZTxFZGRzYVNpZ25pbmdNYXRlcmlhbD4ge1xuICAgIHJldHVybiBzaGFyZWRHZXRFZGRzYVNpZ25pbmdNYXRlcmlhbCh1c2VyS2V5LnJlcGxhY2UoL1xccy9nLCAnJyksIHdhbGxldFBhc3NwaHJhc2UsIHRoaXMuYml0Z28pO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIHNpZ25Eb3RNcGNWMlJlY292ZXJ5KHBhcmFtczogUGFyYW1ldGVyczx0eXBlb2Ygc2lnbkVkZHNhTXBjVjJSZWNvdmVyeVR4PlswXSk6IFByb21pc2U8QnVmZmVyPiB7XG4gICAgcmV0dXJuIHNpZ25FZGRzYU1wY1YyUmVjb3ZlcnlUeChwYXJhbXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYW4gTVBDdjEgb3IgTVBDdjIgc2lnbmF0dXJlIHRvIGEgRE9UIHRyYW5zYWN0aW9uIGJ1aWxkZXIuXG4gICAqXG4gICAqIFRyYW5zYWN0aW9uI2NvbnN0cnVjdFNpZ25lZFBheWxvYWQgYWxyZWFkeSBwcmVwZW5kcyB0aGUgMHgwMCB0eXBlLXRhZyAodGhlIFN1YnN0cmF0ZVxuICAgKiBNdWx0aVNpZ25hdHVyZSBlbnVtIGRpc2NyaW1pbmFudCBmb3IgRWQyNTUxOSkgdG8gd2hhdGV2ZXIgc2lnbmF0dXJlIGJ1ZmZlciBpcyBwYXNzZWQgdG9cbiAgICogYWRkU2lnbmF0dXJlLCBzbyBib3RoIHBhdGhzIGhlcmUgaGFuZCBvZmYgdGhlIHJhdyA2NC1ieXRlIHNpZ25hdHVyZSB1bnRvdWNoZWQuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGFkZFJlY292ZXJ5U2lnbmF0dXJlKFxuICAgIHNpZ25pbmdNYXRlcmlhbDogRWRkc2FTaWduaW5nTWF0ZXJpYWwsXG4gICAgYmFja3VwS2V5OiBzdHJpbmcsXG4gICAgd2FsbGV0UGFzc3BocmFzZTogc3RyaW5nLFxuICAgIHR4bkJ1aWxkZXI6IE5hdGl2ZVRyYW5zZmVyQnVpbGRlcixcbiAgICBhY2NvdW50SWQ6IHN0cmluZyxcbiAgICB1bnNpZ25lZFRyYW5zYWN0aW9uOiBUcmFuc2FjdGlvbixcbiAgICBjdXJyUGF0aDogc3RyaW5nLFxuICAgIGJpdGdvS2V5OiBzdHJpbmdcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgZG90S2V5UGFpciA9IG5ldyBEb3RLZXlQYWlyKHsgcHViOiBhY2NvdW50SWQgfSk7XG5cbiAgICBpZiAoc2lnbmluZ01hdGVyaWFsLnZlcnNpb24gPT09ICd2MicpIHtcbiAgICAgIGNvbnN0IHJhd1NpZyA9IGF3YWl0IHRoaXMuc2lnbkRvdE1wY1YyUmVjb3Zlcnkoe1xuICAgICAgICBtZXNzYWdlOiB1bnNpZ25lZFRyYW5zYWN0aW9uLnNpZ25hYmxlUGF5bG9hZCxcbiAgICAgICAgdXNlcktleTogc2lnbmluZ01hdGVyaWFsLmVuY3J5cHRlZFVzZXJLZXksXG4gICAgICAgIGJhY2t1cEtleSxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgYml0Z29LZXksXG4gICAgICAgIGRlcml2YXRpb25QYXRoOiBjdXJyUGF0aCxcbiAgICAgICAgYml0Z286IHRoaXMuYml0Z28sXG4gICAgICB9KTtcbiAgICAgIHR4bkJ1aWxkZXIuYWRkU2lnbmF0dXJlKHsgcHViOiBkb3RLZXlQYWlyLmdldEtleXMoKS5wdWIgfSwgcmF3U2lnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLyoqIFRPRE8gQkctNTI0MTkgSW1wbGVtZW50IENvZGVjIGZvciBwYXJzaW5nICovXG4gICAgICBjb25zdCB1c2VyU2lnbmluZ01hdGVyaWFsID0gSlNPTi5wYXJzZShzaWduaW5nTWF0ZXJpYWwudXNlclBydikgYXMgRUREU0FNZXRob2RUeXBlcy5Vc2VyU2lnbmluZ01hdGVyaWFsO1xuICAgICAgY29uc3QgYmFja3VwUHJ2ID0gYXdhaXQgZGVjcnlwdEtleWNoYWluUHJpdmF0ZUtleSh0aGlzLmJpdGdvLCB7IGVuY3J5cHRlZFBydjogYmFja3VwS2V5IH0sIHdhbGxldFBhc3NwaHJhc2UpO1xuICAgICAgaWYgKCFiYWNrdXBQcnYpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdFcnJvciBkZWNyeXB0aW5nIGJhY2t1cCBrZXljaGFpbjogaW52YWxpZCBwYXNzd29yZCBvciBjb3JydXB0ZWQga2V5Jyk7XG4gICAgICB9XG4gICAgICBjb25zdCBiYWNrdXBTaWduaW5nTWF0ZXJpYWwgPSBKU09OLnBhcnNlKGJhY2t1cFBydikgYXMgRUREU0FNZXRob2RUeXBlcy5CYWNrdXBTaWduaW5nTWF0ZXJpYWw7XG5cbiAgICAgIGNvbnN0IHNpZ25hdHVyZUhleCA9IGF3YWl0IEVERFNBTWV0aG9kcy5nZXRUU1NTaWduYXR1cmUoXG4gICAgICAgIHVzZXJTaWduaW5nTWF0ZXJpYWwsXG4gICAgICAgIGJhY2t1cFNpZ25pbmdNYXRlcmlhbCxcbiAgICAgICAgY3VyclBhdGgsXG4gICAgICAgIHVuc2lnbmVkVHJhbnNhY3Rpb25cbiAgICAgICk7XG4gICAgICB0eG5CdWlsZGVyLmFkZFNpZ25hdHVyZSh7IHB1YjogZG90S2V5UGFpci5nZXRLZXlzKCkucHViIH0sIHNpZ25hdHVyZUhleCk7XG4gICAgfVxuICB9XG5cbiAgLyoqIEBpbmhlcml0RG9jICovXG4gIGF1ZGl0RGVjcnlwdGVkS2V5KHsgcHVibGljS2V5LCBwcnYsIG11bHRpU2lnVHlwZSB9OiBBdWRpdERlY3J5cHRlZEtleVBhcmFtcykge1xuICAgIGlmIChtdWx0aVNpZ1R5cGUgIT09ICd0c3MnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIG11bHRpU2lnVHlwZScpO1xuICAgIH1cbiAgICBhdWRpdEVkZHNhUHJpdmF0ZUtleShwcnYsIHB1YmxpY0tleSA/PyAnJyk7XG4gIH1cbn1cbiJdfQ==
|