@bitgo-beta/sdk-lib-safes 1.0.0-beta.63 → 1.0.0-beta.65

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.
@@ -33,20 +33,27 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.DerivedFromParentWithHardenedPath = exports.DERIVED_FROM_PARENT_WITH_HARDENED_PATH = void 0;
37
- exports.parseSafeDerivationIndex = parseSafeDerivationIndex;
38
- exports.getSafeHardenedDerivationPath = getSafeHardenedDerivationPath;
39
- exports.parseDerivedFromParentWithHardenedPath = parseDerivedFromParentWithHardenedPath;
36
+ exports.DerivedFromParentWithSoftPath = exports.DerivedFromParentWithHardenedPath = void 0;
37
+ exports.assertBip32Path = assertBip32Path;
38
+ exports.isDerivedFromParentWithHardenedPath = isDerivedFromParentWithHardenedPath;
39
+ exports.isDerivedFromParentWithSoftPath = isDerivedFromParentWithSoftPath;
40
+ exports.parseSafeBip44Path = parseSafeBip44Path;
41
+ exports.getSafeBip44CoinType = getSafeBip44CoinType;
42
+ exports.buildSafeBip44Path = buildSafeBip44Path;
43
+ exports.toSoftTwinPath = toSoftTwinPath;
40
44
  exports.deriveSafeChildHardenedFromXprv = deriveSafeChildHardenedFromXprv;
41
45
  exports.deriveAndSelfCheckSafeChildHardened = deriveAndSelfCheckSafeChildHardened;
42
46
  exports.deriveSafeChildEd25519Hardened = deriveSafeChildEd25519Hardened;
47
+ exports.deriveSafeChildTriplet = deriveSafeChildTriplet;
43
48
  /**
44
49
  * @prettier
45
50
  *
46
51
  * @experimental Shared safe child derivation for mint, sign, and recovery.
47
52
  *
48
- * User child: hardened `m/<index>'` from the sequential `safe.derivationIndex[slot]`.
49
- * Backup / BitGo children are soft-derived at `m/<index>` client-side for recovery.
53
+ * User child (every slot): hardened `m/44'/<coinType>'/<slot>'/<account>'`.
54
+ * Multisig co-signers (backup / BitGo): the soft twin `m/44/<coinType>/<slot>/<account>`.
55
+ * `<coinType>` is statics `bip44CoinType`, `<slot>` is statics `SAFE_ROOT_SLOT_ORDINALS[slot]`,
56
+ * and `<account>` is the safe's per-(slot, coinType) counter.
50
57
  *
51
58
  * Do not use `derivedFromParentWithSeed` / `deriveKeyWithSeed` (`m/999999/a/b`) —
52
59
  * that is the custody hashed path and cannot reproduce a safe child.
@@ -56,48 +63,106 @@ const nacl = __importStar(require("tweetnacl"));
56
63
  const utxo_lib_1 = require("@bitgo-beta/utxo-lib");
57
64
  const statics_1 = require("@bitgo-beta/statics");
58
65
  const ed25519KeyDeriver_1 = require("./ed25519KeyDeriver");
59
- const codecs_1 = require("./codecs");
60
66
  const ed25519Pub_1 = require("./ed25519Pub");
61
- exports.DERIVED_FROM_PARENT_WITH_HARDENED_PATH = /^m\/(\d+)'$/;
62
- function parseSafeDerivationIndex(index) {
63
- let idx;
64
- if (typeof index === 'number') {
65
- idx = index;
66
- }
67
- else if (/^\d+$/.test(index)) {
68
- idx = Number(index);
69
- }
70
- else {
71
- throw new Error(`Invalid safe derivation index '${index}': expected a non-negative integer`);
67
+ const HARDENED_BIP44_PATH = /^m\/44'\/(\d+)'\/(\d+)'\/(\d+)'$/;
68
+ const SOFT_BIP44_PATH = /^m\/44\/(\d+)\/(\d+)\/(\d+)$/;
69
+ const SAFE_SLOT_ORDINALS = Object.values(statics_1.SAFE_ROOT_SLOT_ORDINALS);
70
+ /**
71
+ * Assert `path` is a valid BIP32 path for the given derivation kind. Hardened paths require every
72
+ * segment to carry the `'` marker; soft paths reject it. Every segment must be a non-negative
73
+ * integer at or below {@link MAX_BIP32_INDEX}.
74
+ */
75
+ function assertBip32Path(path, opts) {
76
+ const re = opts.hardened ? /^m(\/\d+')+$/ : /^m(\/\d+)+$/;
77
+ if (!re.test(path)) {
78
+ throw new Error(`Invalid ${opts.hardened ? 'hardened' : 'soft'} derivation path '${path}'`);
72
79
  }
73
- if (!Number.isInteger(idx) || idx < 0 || idx > statics_1.MAX_BIP32_INDEX) {
74
- throw new Error(`Invalid safe derivation index '${index}': expected a non-negative integer`);
80
+ const outOfRange = path
81
+ .split('/')
82
+ .slice(1)
83
+ .map((segment) => Number(opts.hardened ? segment.slice(0, -1) : segment))
84
+ .some((index) => !Number.isInteger(index) || index < 0 || index > statics_1.MAX_BIP32_INDEX);
85
+ if (outOfRange) {
86
+ throw new Error(`Invalid ${opts.hardened ? 'hardened' : 'soft'} derivation path '${path}': index out of range`);
75
87
  }
76
- return idx;
77
88
  }
78
- function getSafeHardenedDerivationPath(index) {
79
- return `m/${parseSafeDerivationIndex(index)}'`;
89
+ /**
90
+ * Canonical decimal only: `044` and `44` name one key under two strings, so string-equality
91
+ * path checks (the server's unique index) would treat one child as two.
92
+ */
93
+ function parseBip32Index(segment) {
94
+ const index = Number(segment);
95
+ return Number.isInteger(index) && index <= statics_1.MAX_BIP32_INDEX && String(index) === segment ? index : undefined;
80
96
  }
81
- exports.DerivedFromParentWithHardenedPath = t.brand(t.string, (s) => parseDerivedFromParentWithHardenedPathIndex(s) !== undefined, 'DerivedFromParentWithHardenedPath');
82
- function parseDerivedFromParentWithHardenedPathIndex(path) {
83
- const match = exports.DERIVED_FROM_PARENT_WITH_HARDENED_PATH.exec(path);
97
+ function parseBip44Segments(match) {
84
98
  if (!match) {
85
99
  return undefined;
86
100
  }
87
- try {
88
- return parseSafeDerivationIndex(match[1]);
101
+ const coinType = parseBip32Index(match[1]);
102
+ const slotOrdinal = parseBip32Index(match[2]);
103
+ const account = parseBip32Index(match[3]);
104
+ if (coinType === undefined || slotOrdinal === undefined || account === undefined) {
105
+ return undefined;
89
106
  }
90
- catch {
107
+ if (!SAFE_SLOT_ORDINALS.includes(slotOrdinal)) {
91
108
  return undefined;
92
109
  }
110
+ return { coinType, slotOrdinal, account };
111
+ }
112
+ function isDerivedFromParentWithHardenedPath(s) {
113
+ return parseBip44Segments(HARDENED_BIP44_PATH.exec(s)) !== undefined;
114
+ }
115
+ function isDerivedFromParentWithSoftPath(s) {
116
+ return parseBip44Segments(SOFT_BIP44_PATH.exec(s)) !== undefined;
117
+ }
118
+ exports.DerivedFromParentWithHardenedPath = t.brand(t.string, (s) => isDerivedFromParentWithHardenedPath(s), 'DerivedFromParentWithHardenedPath');
119
+ exports.DerivedFromParentWithSoftPath = t.brand(t.string, (s) => isDerivedFromParentWithSoftPath(s), 'DerivedFromParentWithSoftPath');
120
+ /**
121
+ * Reads the numeric segments out of a user/MPC child path. Rejects anything else, including a
122
+ * cast soft path: a hardened derive ceremony must never run at, or register, a soft path.
123
+ */
124
+ function parseSafeBip44Path(path) {
125
+ const segments = parseBip44Segments(HARDENED_BIP44_PATH.exec(path));
126
+ if (segments === undefined) {
127
+ throw new Error(`Invalid safe BIP44 path '${path}'`);
128
+ }
129
+ return segments;
93
130
  }
94
- function parseDerivedFromParentWithHardenedPath(path) {
95
- const validated = (0, codecs_1.decodeWithCodec)(exports.DerivedFromParentWithHardenedPath, path, 'derivedFromParentWithHardenedPath');
96
- const index = parseDerivedFromParentWithHardenedPathIndex(validated);
97
- if (index === undefined) {
98
- throw new Error(`Invalid derivedFromParentWithHardenedPath '${path}': expected m/<n>'`);
131
+ /** The `<coinType>` segment for a coin. OFC and fiat coins have none and cannot mint a safe child. */
132
+ function getSafeBip44CoinType(coin) {
133
+ const coinType = statics_1.coins.get(coin).bip44CoinType;
134
+ if (coinType === undefined) {
135
+ throw new Error(`Coin '${coin}' has no BIP44 coin type and cannot derive a safe child`);
136
+ }
137
+ return coinType;
138
+ }
139
+ /**
140
+ * Builds the user-child path `m/44'/<coinType>'/<slot>'/<account>'`. `coinType` comes from statics
141
+ * (or the derivation-index response) and `account` from the safe's per-(slot, coinType) counter.
142
+ */
143
+ function buildSafeBip44Path(coinType, slot, account) {
144
+ const path = `m/44'/${coinType}'/${statics_1.SAFE_ROOT_SLOT_ORDINALS[slot]}'/${account}'`;
145
+ if (!isDerivedFromParentWithHardenedPath(path)) {
146
+ throw new Error(`Invalid safe BIP44 path segments: coinType=${coinType}, slot=${slot}, account=${account}`);
147
+ }
148
+ return path;
149
+ }
150
+ /** Strips hardening from every level: the co-signer path paired with a user-child path. */
151
+ function toSoftTwinPath(path) {
152
+ const softPath = path.replace(/'/g, '');
153
+ if (!isDerivedFromParentWithSoftPath(softPath)) {
154
+ throw new Error(`Invalid safe BIP44 path '${path}': no soft twin`);
155
+ }
156
+ return softPath;
157
+ }
158
+ /**
159
+ * The type alone is not enough: a cast path with a soft level on a user child would let the
160
+ * parent xpub plus the child prv recover the root.
161
+ */
162
+ function assertHardenedPath(path) {
163
+ if (!isDerivedFromParentWithHardenedPath(path)) {
164
+ throw new Error(`Invalid safe child path '${path}': expected m/44'/<coinType>'/<slot>'/<account>'`);
99
165
  }
100
- return index;
101
166
  }
102
167
  function childFromNode(child, derivationPath) {
103
168
  if (!child.privateKey) {
@@ -109,15 +174,14 @@ function childFromNode(child, derivationPath) {
109
174
  derivationPath,
110
175
  };
111
176
  }
112
- function deriveSafeChildHardenedFromXprv(rootXprv, index) {
113
- const idx = parseSafeDerivationIndex(index);
114
- const derivationPath = getSafeHardenedDerivationPath(idx);
115
- return childFromNode(utxo_lib_1.bip32.fromBase58(rootXprv).deriveHardened(idx), derivationPath);
177
+ function deriveSafeChildHardenedFromXprv(rootXprv, path) {
178
+ assertHardenedPath(path);
179
+ return childFromNode(utxo_lib_1.bip32.fromBase58(rootXprv).derivePath(path), path);
116
180
  }
117
181
  /** Re-derive and assert both results match before the child is registered. */
118
- function deriveAndSelfCheckSafeChildHardened(rootXprv, index) {
119
- const first = deriveSafeChildHardenedFromXprv(rootXprv, index);
120
- const second = deriveSafeChildHardenedFromXprv(rootXprv, index);
182
+ function deriveAndSelfCheckSafeChildHardened(rootXprv, path) {
183
+ const first = deriveSafeChildHardenedFromXprv(rootXprv, path);
184
+ const second = deriveSafeChildHardenedFromXprv(rootXprv, path);
121
185
  if (first.pub !== second.pub || first.prv !== second.prv) {
122
186
  throw new Error(`Safe child self-check failed at ${first.derivationPath}: derivation was not deterministic`);
123
187
  }
@@ -126,7 +190,7 @@ function deriveAndSelfCheckSafeChildHardened(rootXprv, index) {
126
190
  /**
127
191
  * SLIP-0010 hardened derivation of a safe user child from an ed25519 root secret seed.
128
192
  *
129
- * `rootPrv` is a Stellar StrKey `S…` secret seed (what slot-④ `ed25519Multisig` user roots store).
193
+ * `rootPrv` is a Stellar StrKey `S…` secret seed (what slot-② `ed25519Multisig` user roots store).
130
194
  * The derivation reuses the existing SLIP-0010 implementation {@link Ed25519KeyDeriver.derivePath}
131
195
  * (hardened-only CKDPriv over the `ed25519 seed` HMAC master), then expands the resulting 32-byte
132
196
  * child seed into a keypair with `nacl`. The child `pub` is a bare StrKey `G…`; the `prv` is the
@@ -135,17 +199,40 @@ function deriveAndSelfCheckSafeChildHardened(rootXprv, index) {
135
199
  * Unlike the secp256k1 path, ed25519 hardened derivation needs no chain code — the composite
136
200
  * `pub‖chainCode` form is only for SOFT co-signer derivation and is not used here.
137
201
  */
138
- function deriveSafeChildEd25519Hardened(rootPrv, index) {
139
- const idx = parseSafeDerivationIndex(index);
140
- const derivationPath = getSafeHardenedDerivationPath(idx);
202
+ function deriveSafeChildEd25519Hardened(rootPrv, path) {
203
+ assertHardenedPath(path);
141
204
  const rawSeedHex = (0, ed25519Pub_1.decodeEd25519StrKeySecretSeed)(rootPrv).toString('hex');
142
- const childSeed = ed25519KeyDeriver_1.Ed25519KeyDeriver.derivePath(derivationPath, rawSeedHex).key;
205
+ const childSeed = ed25519KeyDeriver_1.Ed25519KeyDeriver.derivePath(path, rawSeedHex).key;
143
206
  const keyPair = nacl.sign.keyPair.fromSeed(Uint8Array.from(childSeed));
144
207
  const pub = (0, ed25519Pub_1.encodeEd25519StrKeyPublicKey)(Buffer.from(keyPair.publicKey));
145
208
  return {
146
209
  prv: Buffer.from(childSeed).toString('hex'),
147
210
  pub,
148
- derivationPath,
211
+ derivationPath: path,
212
+ };
213
+ }
214
+ /**
215
+ * Derives the slot-① (secp256k1Multisig) child triplet from the keycard roots: the user child at
216
+ * the hardened `path`, the backup and BitGo children at its soft twin.
217
+ */
218
+ function deriveSafeChildTriplet(roots, path) {
219
+ assertHardenedPath(path);
220
+ const userRoot = utxo_lib_1.bip32.fromBase58(roots.user);
221
+ const backupRoot = utxo_lib_1.bip32.fromBase58(roots.backup);
222
+ const bitgoRoot = utxo_lib_1.bip32.fromBase58(roots.bitgo);
223
+ if (userRoot.isNeutered() || backupRoot.isNeutered()) {
224
+ throw new Error('deriveSafeChildTriplet: user and backup roots must be private (xprv)');
225
+ }
226
+ if (!bitgoRoot.isNeutered()) {
227
+ throw new Error('deriveSafeChildTriplet: bitgo root must be public (xpub)');
228
+ }
229
+ const softPath = toSoftTwinPath(path);
230
+ const user = userRoot.derivePath(path);
231
+ const backup = backupRoot.derivePath(softPath);
232
+ return {
233
+ user: { prv: user.toBase58(), pub: user.neutered().toBase58() },
234
+ backup: { prv: backup.toBase58(), pub: backup.neutered().toBase58() },
235
+ bitgo: { pub: bitgoRoot.derivePath(softPath).toBase58() },
149
236
  };
150
237
  }
151
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2FmZURlcml2YXRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2FmZURlcml2YXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBcUJBLDREQWFDO0FBRUQsc0VBRUM7QUEwQkQsd0ZBT0M7QUFtQkQsMEVBSUM7QUFHRCxrRkFPQztBQWNELHdFQVlDO0FBbElEOzs7Ozs7Ozs7O0dBVUc7QUFDSCx5Q0FBMkI7QUFDM0IsZ0RBQWtDO0FBQ2xDLG1EQUE2RDtBQUM3RCxpREFBc0Q7QUFDdEQsMkRBQXdEO0FBQ3hELHFDQUEyQztBQUMzQyw2Q0FBMkY7QUFFOUUsUUFBQSxzQ0FBc0MsR0FBRyxhQUFhLENBQUM7QUFFcEUsU0FBZ0Isd0JBQXdCLENBQUMsS0FBc0I7SUFDN0QsSUFBSSxHQUFXLENBQUM7SUFDaEIsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLEVBQUUsQ0FBQztRQUM5QixHQUFHLEdBQUcsS0FBSyxDQUFDO0lBQ2QsQ0FBQztTQUFNLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQy9CLEdBQUcsR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDdEIsQ0FBQztTQUFNLENBQUM7UUFDTixNQUFNLElBQUksS0FBSyxDQUFDLGtDQUFrQyxLQUFLLG9DQUFvQyxDQUFDLENBQUM7SUFDL0YsQ0FBQztJQUNELElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEdBQUcsR0FBRyxDQUFDLElBQUksR0FBRyxHQUFHLHlCQUFlLEVBQUUsQ0FBQztRQUMvRCxNQUFNLElBQUksS0FBSyxDQUFDLGtDQUFrQyxLQUFLLG9DQUFvQyxDQUFDLENBQUM7SUFDL0YsQ0FBQztJQUNELE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUVELFNBQWdCLDZCQUE2QixDQUFDLEtBQXNCO0lBQ2xF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QUM7SUFDMUQsTUFBTSxVQUFVLEdBQUcsSUFBQSwwQ0FBNkIsRUFBQyxPQUFPLENBQUMsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDMUUsTUFBTSxTQUFTLEdBQUcscUNBQWlCLENBQUMsVUFBVSxDQUFDLGNBQWMsRUFBRSxVQUFVLENBQUMsQ0FBQyxHQUFHLENBQUM7SUFDL0UsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztJQUN2RSxNQUFNLEdBQUcsR0FBRyxJQUFBLHlDQUE0QixFQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7SUFDekUsT0FBTztRQUNMLEdBQUcsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUM7UUFDM0MsR0FBRztRQUNILGNBQWM7S0FDZixDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQHByZXR0aWVyXG4gKlxuICogQGV4cGVyaW1lbnRhbCBTaGFyZWQgc2FmZSBjaGlsZCBkZXJpdmF0aW9uIGZvciBtaW50LCBzaWduLCBhbmQgcmVjb3ZlcnkuXG4gKlxuICogVXNlciBjaGlsZDogaGFyZGVuZWQgYG0vPGluZGV4PidgIGZyb20gdGhlIHNlcXVlbnRpYWwgYHNhZmUuZGVyaXZhdGlvbkluZGV4W3Nsb3RdYC5cbiAqIEJhY2t1cCAvIEJpdEdvIGNoaWxkcmVuIGFyZSBzb2Z0LWRlcml2ZWQgYXQgYG0vPGluZGV4PmAgY2xpZW50LXNpZGUgZm9yIHJlY292ZXJ5LlxuICpcbiAqIERvIG5vdCB1c2UgYGRlcml2ZWRGcm9tUGFyZW50V2l0aFNlZWRgIC8gYGRlcml2ZUtleVdpdGhTZWVkYCAoYG0vOTk5OTk5L2EvYmApIOKAlFxuICogdGhhdCBpcyB0aGUgY3VzdG9keSBoYXNoZWQgcGF0aCBhbmQgY2Fubm90IHJlcHJvZHVjZSBhIHNhZmUgY2hpbGQuXG4gKi9cbmltcG9ydCAqIGFzIHQgZnJvbSAnaW8tdHMnO1xuaW1wb3J0ICogYXMgbmFjbCBmcm9tICd0d2VldG5hY2wnO1xuaW1wb3J0IHsgYmlwMzIsIEJJUDMySW50ZXJmYWNlIH0gZnJvbSAnQGJpdGdvLWJldGEvdXR4by1saWInO1xuaW1wb3J0IHsgTUFYX0JJUDMyX0lOREVYIH0gZnJvbSAnQGJpdGdvLWJldGEvc3RhdGljcyc7XG5pbXBvcnQgeyBFZDI1NTE5S2V5RGVyaXZlciB9IGZyb20gJy4vZWQyNTUxOUtleURlcml2ZXInO1xuaW1wb3J0IHsgZGVjb2RlV2l0aENvZGVjIH0gZnJvbSAnLi9jb2RlY3MnO1xuaW1wb3J0IHsgZGVjb2RlRWQyNTUxOVN0cktleVNlY3JldFNlZWQsIGVuY29kZUVkMjU1MTlTdHJLZXlQdWJsaWNLZXkgfSBmcm9tICcuL2VkMjU1MTlQdWInO1xuXG5leHBvcnQgY29uc3QgREVSSVZFRF9GUk9NX1BBUkVOVF9XSVRIX0hBUkRFTkVEX1BBVEggPSAvXm1cXC8oXFxkKyknJC87XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZVNhZmVEZXJpdmF0aW9uSW5kZXgoaW5kZXg6IHN0cmluZyB8IG51bWJlcik6IG51bWJlciB7XG4gIGxldCBpZHg6IG51bWJlcjtcbiAgaWYgKHR5cGVvZiBpbmRleCA9PT0gJ251bWJlcicpIHtcbiAgICBpZHggPSBpbmRleDtcbiAgfSBlbHNlIGlmICgvXlxcZCskLy50ZXN0KGluZGV4KSkge1xuICAgIGlkeCA9IE51bWJlcihpbmRleCk7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIHNhZmUgZGVyaXZhdGlvbiBpbmRleCAnJHtpbmRleH0nOiBleHBlY3RlZCBhIG5vbi1uZWdhdGl2ZSBpbnRlZ2VyYCk7XG4gIH1cbiAgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKGlkeCkgfHwgaWR4IDwgMCB8fCBpZHggPiBNQVhfQklQMzJfSU5ERVgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgc2FmZSBkZXJpdmF0aW9uIGluZGV4ICcke2luZGV4fSc6IGV4cGVjdGVkIGEgbm9uLW5lZ2F0aXZlIGludGVnZXJgKTtcbiAgfVxuICByZXR1cm4gaWR4O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0U2FmZUhhcmRlbmVkRGVyaXZhdGlvblBhdGgoaW5kZXg6IHN0cmluZyB8IG51bWJlcik6IHN0cmluZyB7XG4gIHJldHVybiBgbS8ke3BhcnNlU2FmZURlcml2YXRpb25JbmRleChpbmRleCl9J2A7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRGVyaXZlZEZyb21QYXJlbnRXaXRoSGFyZGVuZWRQYXRoQnJhbmQge1xuICByZWFkb25seSBEZXJpdmVkRnJvbVBhcmVudFdpdGhIYXJkZW5lZFBhdGg6IHVuaXF1ZSBzeW1ib2w7XG59XG5cbmV4cG9ydCB0eXBlIERlcml2ZWRGcm9tUGFyZW50V2l0aEhhcmRlbmVkUGF0aCA9IHQuQnJhbmRlZDxzdHJpbmcsIERlcml2ZWRGcm9tUGFyZW50V2l0aEhhcmRlbmVkUGF0aEJyYW5kPjtcblxuZXhwb3J0IGNvbnN0IERlcml2ZWRGcm9tUGFyZW50V2l0aEhhcmRlbmVkUGF0aCA9IHQuYnJhbmQoXG4gIHQuc3RyaW5nLFxuICAocyk6IHMgaXMgRGVyaXZlZEZyb21QYXJlbnRXaXRoSGFyZGVuZWRQYXRoID0+IHBhcnNlRGVyaXZlZEZyb21QYXJlbnRXaXRoSGFyZGVuZWRQYXRoSW5kZXgocykgIT09IHVuZGVmaW5lZCxcbiAgJ0Rlcml2ZWRGcm9tUGFyZW50V2l0aEhhcmRlbmVkUGF0aCdcbik7XG5cbmZ1bmN0aW9uIHBhcnNlRGVyaXZlZEZyb21QYXJlbnRXaXRoSGFyZGVuZWRQYXRoSW5kZXgocGF0aDogc3RyaW5nKTogbnVtYmVyIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgbWF0Y2ggPSBERVJJVkVEX0ZST01fUEFSRU5UX1dJVEhfSEFSREVORURfUEFUSC5leGVjKHBhdGgpO1xuICBpZiAoIW1hdGNoKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICB0cnkge1xuICAgIHJldHVybiBwYXJzZVNhZmVEZXJpdmF0aW9uSW5kZXgobWF0Y2hbMV0pO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZURlcml2ZWRGcm9tUGFyZW50V2l0aEhhcmRlbmVkUGF0aChwYXRoOiBzdHJpbmcpOiBudW1iZXIge1xuICBjb25zdCB2YWxpZGF0ZWQgPSBkZWNvZGVXaXRoQ29kZWMoRGVyaXZlZEZyb21QYXJlbnRXaXRoSGFyZGVuZWRQYXRoLCBwYXRoLCAnZGVyaXZlZEZyb21QYXJlbnRXaXRoSGFyZGVuZWRQYXRoJyk7XG4gIGNvbnN0IGluZGV4ID0gcGFyc2VEZXJpdmVkRnJvbVBhcmVudFdpdGhIYXJkZW5lZFBhdGhJbmRleCh2YWxpZGF0ZWQpO1xuICBpZiAoaW5kZXggPT09IHVuZGVmaW5lZCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBkZXJpdmVkRnJvbVBhcmVudFdpdGhIYXJkZW5lZFBhdGggJyR7cGF0aH0nOiBleHBlY3RlZCBtLzxuPidgKTtcbiAgfVxuICByZXR1cm4gaW5kZXg7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2FmZUhhcmRlbmVkQ2hpbGRLZXkge1xuICBwcnY6IHN0cmluZztcbiAgcHViOiBzdHJpbmc7XG4gIGRlcml2YXRpb25QYXRoOiBzdHJpbmc7XG59XG5cbmZ1bmN0aW9uIGNoaWxkRnJvbU5vZGUoY2hpbGQ6IEJJUDMySW50ZXJmYWNlLCBkZXJpdmF0aW9uUGF0aDogc3RyaW5nKTogU2FmZUhhcmRlbmVkQ2hpbGRLZXkge1xuICBpZiAoIWNoaWxkLnByaXZhdGVLZXkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEZhaWxlZCB0byBkZXJpdmUgaGFyZGVuZWQgc2FmZSBjaGlsZCBhdCAke2Rlcml2YXRpb25QYXRofWApO1xuICB9XG4gIHJldHVybiB7XG4gICAgcHJ2OiBjaGlsZC50b0Jhc2U1OCgpLFxuICAgIHB1YjogY2hpbGQubmV1dGVyZWQoKS50b0Jhc2U1OCgpLFxuICAgIGRlcml2YXRpb25QYXRoLFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZGVyaXZlU2FmZUNoaWxkSGFyZGVuZWRGcm9tWHBydihyb290WHBydjogc3RyaW5nLCBpbmRleDogc3RyaW5nIHwgbnVtYmVyKTogU2FmZUhhcmRlbmVkQ2hpbGRLZXkge1xuICBjb25zdCBpZHggPSBwYXJzZVNhZmVEZXJpdmF0aW9uSW5kZXgoaW5kZXgpO1xuICBjb25zdCBkZXJpdmF0aW9uUGF0aCA9IGdldFNhZmVIYXJkZW5lZERlcml2YXRpb25QYXRoKGlkeCk7XG4gIHJldHVybiBjaGlsZEZyb21Ob2RlKGJpcDMyLmZyb21CYXNlNTgocm9vdFhwcnYpLmRlcml2ZUhhcmRlbmVkKGlkeCksIGRlcml2YXRpb25QYXRoKTtcbn1cblxuLyoqIFJlLWRlcml2ZSBhbmQgYXNzZXJ0IGJvdGggcmVzdWx0cyBtYXRjaCBiZWZvcmUgdGhlIGNoaWxkIGlzIHJlZ2lzdGVyZWQuICovXG5leHBvcnQgZnVuY3Rpb24gZGVyaXZlQW5kU2VsZkNoZWNrU2FmZUNoaWxkSGFyZGVuZWQocm9vdFhwcnY6IHN0cmluZywgaW5kZXg6IHN0cmluZyB8IG51bWJlcik6IFNhZmVIYXJkZW5lZENoaWxkS2V5IHtcbiAgY29uc3QgZmlyc3QgPSBkZXJpdmVTYWZlQ2hpbGRIYXJkZW5lZEZyb21YcHJ2KHJvb3RYcHJ2LCBpbmRleCk7XG4gIGNvbnN0IHNlY29uZCA9IGRlcml2ZVNhZmVDaGlsZEhhcmRlbmVkRnJvbVhwcnYocm9vdFhwcnYsIGluZGV4KTtcbiAgaWYgKGZpcnN0LnB1YiAhPT0gc2Vjb25kLnB1YiB8fCBmaXJzdC5wcnYgIT09IHNlY29uZC5wcnYpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFNhZmUgY2hpbGQgc2VsZi1jaGVjayBmYWlsZWQgYXQgJHtmaXJzdC5kZXJpdmF0aW9uUGF0aH06IGRlcml2YXRpb24gd2FzIG5vdCBkZXRlcm1pbmlzdGljYCk7XG4gIH1cbiAgcmV0dXJuIGZpcnN0O1xufVxuXG4vKipcbiAqIFNMSVAtMDAxMCBoYXJkZW5lZCBkZXJpdmF0aW9uIG9mIGEgc2FmZSB1c2VyIGNoaWxkIGZyb20gYW4gZWQyNTUxOSByb290IHNlY3JldCBzZWVkLlxuICpcbiAqIGByb290UHJ2YCBpcyBhIFN0ZWxsYXIgU3RyS2V5IGBT4oCmYCBzZWNyZXQgc2VlZCAod2hhdCBzbG90LeKRoyBgZWQyNTUxOU11bHRpc2lnYCB1c2VyIHJvb3RzIHN0b3JlKS5cbiAqIFRoZSBkZXJpdmF0aW9uIHJldXNlcyB0aGUgZXhpc3RpbmcgU0xJUC0wMDEwIGltcGxlbWVudGF0aW9uIHtAbGluayBFZDI1NTE5S2V5RGVyaXZlci5kZXJpdmVQYXRofVxuICogKGhhcmRlbmVkLW9ubHkgQ0tEUHJpdiBvdmVyIHRoZSBgZWQyNTUxOSBzZWVkYCBITUFDIG1hc3RlciksIHRoZW4gZXhwYW5kcyB0aGUgcmVzdWx0aW5nIDMyLWJ5dGVcbiAqIGNoaWxkIHNlZWQgaW50byBhIGtleXBhaXIgd2l0aCBgbmFjbGAuIFRoZSBjaGlsZCBgcHViYCBpcyBhIGJhcmUgU3RyS2V5IGBH4oCmYDsgdGhlIGBwcnZgIGlzIHRoZVxuICogcmF3IDMyLWJ5dGUgY2hpbGQgc2VlZCBhcyBoZXggKHRoZSBzZWVkIGlucHV0IGEgc2lnbmVyIG5lZWRzKS5cbiAqXG4gKiBVbmxpa2UgdGhlIHNlY3AyNTZrMSBwYXRoLCBlZDI1NTE5IGhhcmRlbmVkIGRlcml2YXRpb24gbmVlZHMgbm8gY2hhaW4gY29kZSDigJQgdGhlIGNvbXBvc2l0ZVxuICogYHB1YuKAlmNoYWluQ29kZWAgZm9ybSBpcyBvbmx5IGZvciBTT0ZUIGNvLXNpZ25lciBkZXJpdmF0aW9uIGFuZCBpcyBub3QgdXNlZCBoZXJlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZGVyaXZlU2FmZUNoaWxkRWQyNTUxOUhhcmRlbmVkKHJvb3RQcnY6IHN0cmluZywgaW5kZXg6IHN0cmluZyB8IG51bWJlcik6IFNhZmVIYXJkZW5lZENoaWxkS2V5IHtcbiAgY29uc3QgaWR4ID0gcGFyc2VTYWZlRGVyaXZhdGlvbkluZGV4KGluZGV4KTtcbiAgY29uc3QgZGVyaXZhdGlvblBhdGggPSBnZXRTYWZlSGFyZGVuZWREZXJpdmF0aW9uUGF0aChpZHgpO1xuICBjb25zdCByYXdTZWVkSGV4ID0gZGVjb2RlRWQyNTUxOVN0cktleVNlY3JldFNlZWQocm9vdFBydikudG9TdHJpbmcoJ2hleCcpO1xuICBjb25zdCBjaGlsZFNlZWQgPSBFZDI1NTE5S2V5RGVyaXZlci5kZXJpdmVQYXRoKGRlcml2YXRpb25QYXRoLCByYXdTZWVkSGV4KS5rZXk7XG4gIGNvbnN0IGtleVBhaXIgPSBuYWNsLnNpZ24ua2V5UGFpci5mcm9tU2VlZChVaW50OEFycmF5LmZyb20oY2hpbGRTZWVkKSk7XG4gIGNvbnN0IHB1YiA9IGVuY29kZUVkMjU1MTlTdHJLZXlQdWJsaWNLZXkoQnVmZmVyLmZyb20oa2V5UGFpci5wdWJsaWNLZXkpKTtcbiAgcmV0dXJuIHtcbiAgICBwcnY6IEJ1ZmZlci5mcm9tKGNoaWxkU2VlZCkudG9TdHJpbmcoJ2hleCcpLFxuICAgIHB1YixcbiAgICBkZXJpdmF0aW9uUGF0aCxcbiAgfTtcbn1cbiJdfQ==
238
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2FmZURlcml2YXRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2FmZURlcml2YXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBb0NBLDBDQWFDO0FBeUNELGtGQUVDO0FBRUQsMEVBRUM7QUFrQkQsZ0RBTUM7QUFHRCxvREFNQztBQU1ELGdEQVVDO0FBR0Qsd0NBTUM7QUE2QkQsMEVBTUM7QUFHRCxrRkFVQztBQWNELHdFQWNDO0FBWUQsd0RBc0JDO0FBeFFEOzs7Ozs7Ozs7Ozs7R0FZRztBQUNILHlDQUEyQjtBQUMzQixnREFBa0M7QUFDbEMsbURBQTZEO0FBQzdELGlEQUFzRjtBQUV0RiwyREFBd0Q7QUFDeEQsNkNBQTJGO0FBRTNGLE1BQU0sbUJBQW1CLEdBQUcsa0NBQWtDLENBQUM7QUFDL0QsTUFBTSxlQUFlLEdBQUcsOEJBQThCLENBQUM7QUFDdkQsTUFBTSxrQkFBa0IsR0FBc0IsTUFBTSxDQUFDLE1BQU0sQ0FBQyxpQ0FBdUIsQ0FBQyxDQUFDO0FBUXJGOzs7O0dBSUc7QUFDSCxTQUFnQixlQUFlLENBQUMsSUFBWSxFQUFFLElBQTJCO0lBQ3ZFLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsYUFBYSxDQUFDO0lBQzFELElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7UUFDbkIsTUFBTSxJQUFJLEtBQUssQ0FBQyxXQUFXLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsTUFBTSxxQkFBcUIsSUFBSSxHQUFHLENBQUMsQ0FBQztJQUM5RixDQUFDO0lBQ0QsTUFBTSxVQUFVLEdBQUcsSUFBSTtTQUNwQixLQUFLLENBQUMsR0FBRyxDQUFDO1NBQ1YsS0FBSyxDQUFDLENBQUMsQ0FBQztT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S0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ2xELE1BQU0sU0FBUyxHQUFHLGdCQUFLLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNoRCxJQUFJLFFBQVEsQ0FBQyxVQUFVLEVBQUUsSUFBSSxVQUFVLENBQUMsVUFBVSxFQUFFLEVBQUUsQ0FBQztRQUNyRCxNQUFNLElBQUksS0FBSyxDQUFDLHNFQUFzRSxDQUFDLENBQUM7SUFDMUYsQ0FBQztJQUNELElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVSxFQUFFLEVBQUUsQ0FBQztRQUM1QixNQUFNLElBQUksS0FBSyxDQUFDLDBEQUEwRCxDQUFDLENBQUM7SUFDOUUsQ0FBQztJQUNELE1BQU0sUUFBUSxHQUFHLGNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN0QyxNQUFNLElBQUksR0FBRyxRQUFRLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3ZDLE1BQU0sTUFBTSxHQUFHLFVBQVUsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDL0MsT0FBTztRQUNMLElBQUksRUFBRSxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsUUFBUSxFQUFFLEVBQUUsR0FBRyxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxRQUFRLEVBQUUsRUFBRTtRQUMvRCxNQUFNLEVBQUUsRUFBRSxHQUFHLEVBQUUsTUFBTSxDQUFDLFFBQVEsRUFBRSxFQUFFLEdBQUcsRUFBRSxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUMsUUFBUSxFQUFFLEVBQUU7UUFDckUsS0FBSyxFQUFFLEVBQUUsR0FBRyxFQUFFLFNBQVMsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUMsUUFBUSxFQUFFLEVBQUU7S0FDMUQsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBwcmV0dGllclxuICpcbiAqIEBleHBlcmltZW50YWwgU2hhcmVkIHNhZmUgY2hpbGQgZGVyaXZhdGlvbiBmb3IgbWludCwgc2lnbiwgYW5kIHJlY292ZXJ5LlxuICpcbiAqIFVzZXIgY2hpbGQgKGV2ZXJ5IHNsb3QpOiBoYXJkZW5lZCBgbS80NCcvPGNvaW5UeXBlPicvPHNsb3Q+Jy88YWNjb3VudD4nYC5cbiAqIE11bHRpc2lnIGNvLXNpZ25lcnMgKGJhY2t1cCAvIEJpdEdvKTogdGhlIHNvZnQgdHdpbiBgbS80NC88Y29pblR5cGU+LzxzbG90Pi88YWNjb3VudD5gLlxuICogYDxjb2luVHlwZT5gIGlzIHN0YXRpY3MgYGJpcDQ0Q29pblR5cGVgLCBgPHNsb3Q+YCBpcyBzdGF0aWNzIGBTQUZFX1JPT1RfU0xPVF9PUkRJTkFMU1tzbG90XWAsXG4gKiBhbmQgYDxhY2NvdW50PmAgaXMgdGhlIHNhZmUncyBwZXItKHNsb3QsIGNvaW5UeXBlKSBjb3VudGVyLlxuICpcbiAqIERvIG5vdCB1c2UgYGRlcml2ZWRGcm9tUGFyZW50V2l0aFNlZWRgIC8gYGRlcml2ZUtleVdpdGhTZWVkYCAoYG0vOTk5OTk5L2EvYmApIOKAlFxuICogdGhhdCBpcyB0aGUgY3VzdG9keSBoYXNoZWQgcGF0aCBhbmQgY2Fubm90IHJlcHJvZHVjZSBhIHNhZmUgY2hpbGQuXG4gKi9cbmltcG9ydCAqIGFzIHQgZnJvbSAnaW8tdHMnO1xuaW1wb3J0ICogYXMgbmFjbCBmcm9tICd0d2VldG5hY2wnO1xuaW1wb3J0IHsgYmlwMzIsIEJJUDMySW50ZXJmYWNlIH0gZnJvbSAnQGJpdGdvLWJldGEvdXR4by1saWInO1xuaW1wb3J0IHsgY29pbnMsIE1BWF9CSVAzMl9JTkRFWCwgU0FGRV9ST09UX1NMT1RfT1JESU5BTFMgfSBmcm9tICdAYml0Z28tYmV0YS9zdGF0aWNzJztcbmltcG9ydCB0eXBlIHsgUm9vdEtleVR5cGUgfSBmcm9tICdAYml0Z28vcHVibGljLXR5cGVzJztcbmltcG9ydCB7IEVkMjU1MTlLZXlEZXJpdmVyIH0gZnJvbSAnLi9lZDI1NTE5S2V5RGVyaXZlcic7XG5pbXBvcnQgeyBkZWNvZGVFZDI1NTE5U3RyS2V5U2VjcmV0U2VlZCwgZW5jb2RlRWQyNTUxOVN0cktleVB1YmxpY0tleSB9IGZyb20gJy4vZWQyNTUxOVB1Yic7XG5cbmNvbnN0IEhBUkRFTkVEX0JJUDQ0X1BBVEggPSAvXm1cXC80NCdcXC8oXFxkKyknXFwvKFxcZCspJ1xcLyhcXGQrKSckLztcbmNvbnN0IFNPRlRfQklQNDRfUEFUSCA9IC9ebVxcLzQ0XFwvKFxcZCspXFwvKFxcZCspXFwvKFxcZCspJC87XG5jb25zdCBTQUZFX1NMT1RfT1JESU5BTFM6IHJlYWRvbmx5IG51bWJlcltdID0gT2JqZWN0LnZhbHVlcyhTQUZFX1JPT1RfU0xPVF9PUkRJTkFMUyk7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2FmZUJpcDQ0UGF0aFNlZ21lbnRzIHtcbiAgY29pblR5cGU6IG51bWJlcjtcbiAgc2xvdE9yZGluYWw6IG51bWJlcjtcbiAgYWNjb3VudDogbnVtYmVyO1xufVxuXG4vKipcbiAqIEFzc2VydCBgcGF0aGAgaXMgYSB2YWxpZCBCSVAzMiBwYXRoIGZvciB0aGUgZ2l2ZW4gZGVyaXZhdGlvbiBraW5kLiBIYXJkZW5lZCBwYXRocyByZXF1aXJlIGV2ZXJ5XG4gKiBzZWdtZW50IHRvIGNhcnJ5IHRoZSBgJ2AgbWFya2VyOyBzb2Z0IHBhdGhzIHJlamVjdCBpdC4gRXZlcnkgc2VnbWVudCBtdXN0IGJlIGEgbm9uLW5lZ2F0aXZlXG4gKiBpbnRlZ2VyIGF0IG9yIGJlbG93IHtAbGluayBNQVhfQklQMzJfSU5ERVh9LlxuICovXG5leHBvcnQgZnVuY3Rpb24gYXNzZXJ0QmlwMzJQYXRoKHBhdGg6IHN0cmluZywgb3B0czogeyBoYXJkZW5lZDogYm9vbGVhbiB9KTogdm9pZCB7XG4gIGNvbnN0IHJlID0gb3B0cy5oYXJkZW5lZCA/IC9ebShcXC9cXGQrJykrJC8gOiAvXm0oXFwvXFxkKykrJC87XG4gIGlmICghcmUudGVzdChwYXRoKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCAke29wdHMuaGFyZGVuZWQgPyAnaGFyZGVuZWQnIDogJ3NvZnQnfSBkZXJpdmF0aW9uIHBhdGggJyR7cGF0aH0nYCk7XG4gIH1cbiAgY29uc3Qgb3V0T2ZSYW5nZSA9IHBhdGhcbiAgICAuc3BsaXQoJy8nKVxuICAgIC5zbGljZSgxKVxuICAgIC5tYXAoKHNlZ21lbnQpID0+IE51bWJlcihvcHRzLmhhcmRlbmVkID8gc2VnbWVudC5zbGljZSgwLCAtMSkgOiBzZWdtZW50KSlcbiAgICAuc29tZSgoaW5kZXgpID0+ICFOdW1iZXIuaXNJbnRlZ2VyKGluZGV4KSB8fCBpbmRleCA8IDAgfHwgaW5kZXggPiBNQVhfQklQMzJfSU5ERVgpO1xuICBpZiAob3V0T2ZSYW5nZSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCAke29wdHMuaGFyZGVuZWQgPyAnaGFyZGVuZWQnIDogJ3NvZnQnfSBkZXJpdmF0aW9uIHBhdGggJyR7cGF0aH0nOiBpbmRleCBvdXQgb2YgcmFuZ2VgKTtcbiAgfVxufVxuXG4vKipcbiAqIENhbm9uaWNhbCBkZWNpbWFsIG9ubHk6IGAwNDRgIGFuZCBgNDRgIG5hbWUgb25lIGtleSB1bmRlciB0d28gc3RyaW5ncywgc28gc3RyaW5nLWVxdWFsaXR5XG4gKiBwYXRoIGNoZWNrcyAodGhlIHNlcnZlcidzIHVuaXF1ZSBpbmRleCkgd291bGQgdHJlYXQgb25lIGNoaWxkIGFzIHR3by5cbiAqL1xuZnVuY3Rpb24gcGFyc2VCaXAzMkluZGV4KHNlZ21lbnQ6IHN0cmluZyk6IG51bWJlciB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IGluZGV4ID0gTnVtYmVyKHNlZ21lbnQpO1xuICByZXR1cm4gTnVtYmVyLmlzSW50ZWdlcihpbmRleCkgJiYgaW5kZXggPD0gTUFYX0JJUDMyX0lOREVYICYmIFN0cmluZyhpbmRleCkgPT09IHNlZ21lbnQgPyBpbmRleCA6IHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gcGFyc2VCaXA0NFNlZ21lbnRzKG1hdGNoOiBSZWdFeHBFeGVjQXJyYXkgfCBudWxsKTogU2FmZUJpcDQ0UGF0aFNlZ21lbnRzIHwgdW5kZWZpbmVkIHtcbiAgaWYgKCFtYXRjaCkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgY29uc3QgY29pblR5cGUgPSBwYXJzZUJpcDMySW5kZXgobWF0Y2hbMV0pO1xuICBjb25zdCBzbG90T3JkaW5hbCA9IHBhcnNlQmlwMzJJbmRleChtYXRjaFsyXSk7XG4gIGNvbnN0IGFjY291bnQgPSBwYXJzZUJpcDMySW5kZXgobWF0Y2hbM10pO1xuICBpZiAoY29pblR5cGUgPT09IHVuZGVmaW5lZCB8fCBzbG90T3JkaW5hbCA9PT0gdW5kZWZpbmVkIHx8IGFjY291bnQgPT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgaWYgKCFTQUZFX1NMT1RfT1JESU5BTFMuaW5jbHVkZXMoc2xvdE9yZGluYWwpKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICByZXR1cm4geyBjb2luVHlwZSwgc2xvdE9yZGluYWwsIGFjY291bnQgfTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBEZXJpdmVkRnJvbVBhcmVudFdpdGhIYXJkZW5lZFBhdGhCcmFuZCB7XG4gIHJlYWRvbmx5IERlcml2ZWRGcm9tUGFyZW50V2l0aEhhcmRlbmVkUGF0aDogdW5pcXVlIHN5bWJvbDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBEZXJpdmVkRnJvbVBhcmVudFdpdGhTb2Z0UGF0aEJyYW5kIHtcbiAgcmVhZG9ubHkgRGVyaXZlZEZyb21QYXJlbnRXaXRoU29mdFBhdGg6IHVuaXF1ZSBzeW1ib2w7XG59XG5cbi8qKiBTYWZlIHVzZXItY2hpbGQgcGF0aCBgbS80NCcvPGNvaW5UeXBlPicvPHNsb3Q+Jy88YWNjb3VudD4nYDsgYWxzbyBldmVyeSBNUEMgY2hpbGQuICovXG5leHBvcnQgdHlwZSBEZXJpdmVkRnJvbVBhcmVudFdpdGhIYXJkZW5lZFBhdGggPSB0LkJyYW5kZWQ8c3RyaW5nLCBEZXJpdmVkRnJvbVBhcmVudFdpdGhIYXJkZW5lZFBhdGhCcmFuZD47XG5cbi8qKiBNdWx0aXNpZyBjby1zaWduZXIgcGF0aCBgbS80NC88Y29pblR5cGU+LzxzbG90Pi88YWNjb3VudD5gLCB0aGUgc29mdCB0d2luIG9mIGEgdXNlci1jaGlsZCBwYXRoLiAqL1xuZXhwb3J0IHR5cGUgRGVyaXZlZEZyb21QYXJlbnRXaXRoU29mdFBhdGggPSB0LkJyYW5kZWQ8c3RyaW5nLCBEZXJpdmVkRnJvbVBhcmVudFdpdGhTb2Z0UGF0aEJyYW5kPjtcblxuZXhwb3J0IGZ1bmN0aW9uIGlzRGVyaXZlZEZyb21QYXJlbnRXaXRoSGFyZGVuZWRQYXRoKHM6IHN0cmluZyk6IHMgaXMgRGVyaXZlZEZyb21QYXJlbnRXaXRoSGFyZGVuZWRQYXRoIHtcbiAgcmV0dXJuIHBhcnNlQmlwNDRTZWdtZW50cyhIQVJERU5FRF9CSVA0NF9QQVRILmV4ZWMocykpICE9PSB1bmRlZmluZWQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0Rlcml2ZWRGcm9tUGFyZW50V2l0aFNvZnRQYXRoKHM6IHN0cmluZyk6IHMgaXMgRGVyaXZlZEZyb21QYXJlbnRXaXRoU29mdFBhdGgge1xuICByZXR1cm4gcGFyc2VCaXA0NFNlZ21lbnRzKFNPRlRfQklQNDRfUEFUSC5leGVjKHMpKSAhPT0gdW5kZWZpbmVkO1xufVxuXG5leHBvcnQgY29uc3QgRGVyaXZlZEZyb21QYXJlbnRXaXRoSGFyZGVuZWRQYXRoID0gdC5icmFuZChcbiAgdC5zdHJpbmcsXG4gIChzKTogcyBpcyBEZXJpdmVkRnJvbVBhcmVudFdpdGhIYXJkZW5lZFBhdGggPT4gaXNEZXJpdmVkRnJvbVBhcmVudFdpdGhIYXJkZW5lZFBhdGgocyksXG4gICdEZXJpdmVkRnJvbVBhcmVudFdpdGhIYXJkZW5lZFBhdGgnXG4pO1xuXG5leHBvcnQgY29uc3QgRGVyaXZlZEZyb21QYXJlbnRXaXRoU29mdFBhdGggPSB0LmJyYW5kKFxuICB0LnN0cmluZyxcbiAgKHMpOiBzIGlzIERlcml2ZWRGcm9tUGFyZW50V2l0aFNvZnRQYXRoID0+IGlzRGVyaXZlZEZyb21QYXJlbnRXaXRoU29mdFBhdGgocyksXG4gICdEZXJpdmVkRnJvbVBhcmVudFdpdGhTb2Z0UGF0aCdcbik7XG5cbi8qKlxuICogUmVhZHMgdGhlIG51bWVyaWMgc2VnbWVudHMgb3V0IG9mIGEgdXNlci9NUEMgY2hpbGQgcGF0aC4gUmVqZWN0cyBhbnl0aGluZyBlbHNlLCBpbmNsdWRpbmcgYVxuICogY2FzdCBzb2Z0IHBhdGg6IGEgaGFyZGVuZWQgZGVyaXZlIGNlcmVtb255IG11c3QgbmV2ZXIgcnVuIGF0LCBvciByZWdpc3RlciwgYSBzb2Z0IHBhdGguXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZVNhZmVCaXA0NFBhdGgocGF0aDogRGVyaXZlZEZyb21QYXJlbnRXaXRoSGFyZGVuZWRQYXRoKTogU2FmZUJpcDQ0UGF0aFNlZ21lbnRzIHtcbiAgY29uc3Qgc2VnbWVudHMgPSBwYXJzZUJpcDQ0U2VnbWVudHMoSEFSREVORURfQklQNDRfUEFUSC5leGVjKHBhdGgpKTtcbiAgaWYgKHNlZ21lbnRzID09PSB1bmRlZmluZWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgc2FmZSBCSVA0NCBwYXRoICcke3BhdGh9J2ApO1xuICB9XG4gIHJldHVybiBzZWdtZW50cztcbn1cblxuLyoqIFRoZSBgPGNvaW5UeXBlPmAgc2VnbWVudCBmb3IgYSBjb2luLiBPRkMgYW5kIGZpYXQgY29pbnMgaGF2ZSBub25lIGFuZCBjYW5ub3QgbWludCBhIHNhZmUgY2hpbGQuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0U2FmZUJpcDQ0Q29pblR5cGUoY29pbjogc3RyaW5nKTogbnVtYmVyIHtcbiAgY29uc3QgY29pblR5cGUgPSBjb2lucy5nZXQoY29pbikuYmlwNDRDb2luVHlwZTtcbiAgaWYgKGNvaW5UeXBlID09PSB1bmRlZmluZWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYENvaW4gJyR7Y29pbn0nIGhhcyBubyBCSVA0NCBjb2luIHR5cGUgYW5kIGNhbm5vdCBkZXJpdmUgYSBzYWZlIGNoaWxkYCk7XG4gIH1cbiAgcmV0dXJuIGNvaW5UeXBlO1xufVxuXG4vKipcbiAqIEJ1aWxkcyB0aGUgdXNlci1jaGlsZCBwYXRoIGBtLzQ0Jy88Y29pblR5cGU+Jy88c2xvdD4nLzxhY2NvdW50PidgLiBgY29pblR5cGVgIGNvbWVzIGZyb20gc3RhdGljc1xuICogKG9yIHRoZSBkZXJpdmF0aW9uLWluZGV4IHJlc3BvbnNlKSBhbmQgYGFjY291bnRgIGZyb20gdGhlIHNhZmUncyBwZXItKHNsb3QsIGNvaW5UeXBlKSBjb3VudGVyLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRTYWZlQmlwNDRQYXRoKFxuICBjb2luVHlwZTogbnVtYmVyLFxuICBzbG90OiBSb290S2V5VHlwZSxcbiAgYWNjb3VudDogbnVtYmVyXG4pOiBEZXJpdmVkRnJvbVBhcmVudFdpdGhIYXJkZW5lZFBhdGgge1xuICBjb25zdCBwYXRoID0gYG0vNDQnLyR7Y29pblR5cGV9Jy8ke1NBRkVfUk9PVF9TTE9UX09SRElOQUxTW3Nsb3RdfScvJHthY2NvdW50fSdgO1xuICBpZiAoIWlzRGVyaXZlZEZyb21QYXJlbnRXaXRoSGFyZGVuZWRQYXRoKHBhdGgpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIHNhZmUgQklQNDQgcGF0aCBzZWdtZW50czogY29pblR5cGU9JHtjb2luVHlwZX0sIHNsb3Q9JHtzbG90fSwgYWNjb3VudD0ke2FjY291bnR9YCk7XG4gIH1cbiAgcmV0dXJuIHBhdGg7XG59XG5cbi8qKiBTdHJpcHMgaGFyZGVuaW5nIGZyb20gZXZlcnkgbGV2ZWw6IHRoZSBjby1zaWduZXIgcGF0aCBwYWlyZWQgd2l0aCBhIHVzZXItY2hpbGQgcGF0aC4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0b1NvZnRUd2luUGF0aChwYXRoOiBEZXJpdmVkRnJvbVBhcmVudFdpdGhIYXJkZW5lZFBhdGgpOiBEZXJpdmVkRnJvbVBhcmVudFdpdGhTb2Z0UGF0aCB7XG4gIGNvbnN0IHNvZnRQYXRoID0gcGF0aC5yZXBsYWNlKC8nL2csICcnKTtcbiAgaWYgKCFpc0Rlcml2ZWRGcm9tUGFyZW50V2l0aFNvZnRQYXRoKHNvZnRQYXRoKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBzYWZlIEJJUDQ0IHBhdGggJyR7cGF0aH0nOiBubyBzb2Z0IHR3aW5gKTtcbiAgfVxuICByZXR1cm4gc29mdFBhdGg7XG59XG5cbi8qKlxuICogVGhlIHR5cGUgYWxvbmUgaXMgbm90IGVub3VnaDogYSBjYXN0IHBhdGggd2l0aCBhIHNvZnQgbGV2ZWwgb24gYSB1c2VyIGNoaWxkIHdvdWxkIGxldCB0aGVcbiAqIHBhcmVudCB4cHViIHBsdXMgdGhlIGNoaWxkIHBydiByZWNvdmVyIHRoZSByb290LlxuICovXG5mdW5jdGlvbiBhc3NlcnRIYXJkZW5lZFBhdGgocGF0aDogc3RyaW5nKTogYXNzZXJ0cyBwYXRoIGlzIERlcml2ZWRGcm9tUGFyZW50V2l0aEhhcmRlbmVkUGF0aCB7XG4gIGlmICghaXNEZXJpdmVkRnJvbVBhcmVudFdpdGhIYXJkZW5lZFBhdGgocGF0aCkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgc2FmZSBjaGlsZCBwYXRoICcke3BhdGh9JzogZXhwZWN0ZWQgbS80NCcvPGNvaW5UeXBlPicvPHNsb3Q+Jy88YWNjb3VudD4nYCk7XG4gIH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBTYWZlSGFyZGVuZWRDaGlsZEtleSB7XG4gIHBydjogc3RyaW5nO1xuICBwdWI6IHN0cmluZztcbiAgZGVyaXZhdGlvblBhdGg6IERlcml2ZWRGcm9tUGFyZW50V2l0aEhhcmRlbmVkUGF0aDtcbn1cblxuZnVuY3Rpb24gY2hpbGRGcm9tTm9kZShjaGlsZDogQklQMzJJbnRlcmZhY2UsIGRlcml2YXRpb25QYXRoOiBEZXJpdmVkRnJvbVBhcmVudFdpdGhIYXJkZW5lZFBhdGgpOiBTYWZlSGFyZGVuZWRDaGlsZEtleSB7XG4gIGlmICghY2hpbGQucHJpdmF0ZUtleSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIGRlcml2ZSBoYXJkZW5lZCBzYWZlIGNoaWxkIGF0ICR7ZGVyaXZhdGlvblBhdGh9YCk7XG4gIH1cbiAgcmV0dXJuIHtcbiAgICBwcnY6IGNoaWxkLnRvQmFzZTU4KCksXG4gICAgcHViOiBjaGlsZC5uZXV0ZXJlZCgpLnRvQmFzZTU4KCksXG4gICAgZGVyaXZhdGlvblBhdGgsXG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkZXJpdmVTYWZlQ2hpbGRIYXJkZW5lZEZyb21YcHJ2KFxuICByb290WHBydjogc3RyaW5nLFxuICBwYXRoOiBEZXJpdmVkRnJvbVBhcmVudFdpdGhIYXJkZW5lZFBhdGhcbik6IFNhZmVIYXJkZW5lZENoaWxkS2V5IHtcbiAgYXNzZXJ0SGFyZGVuZWRQYXRoKHBhdGgpO1xuICByZXR1cm4gY2hpbGRGcm9tTm9kZShiaXAzMi5mcm9tQmFzZTU4KHJvb3RYcHJ2KS5kZXJpdmVQYXRoKHBhdGgpLCBwYXRoKTtcbn1cblxuLyoqIFJlLWRlcml2ZSBhbmQgYXNzZXJ0IGJvdGggcmVzdWx0cyBtYXRjaCBiZWZvcmUgdGhlIGNoaWxkIGlzIHJlZ2lzdGVyZWQuICovXG5leHBvcnQgZnVuY3Rpb24gZGVyaXZlQW5kU2VsZkNoZWNrU2FmZUNoaWxkSGFyZGVuZWQoXG4gIHJvb3RYcHJ2OiBzdHJpbmcsXG4gIHBhdGg6IERlcml2ZWRGcm9tUGFyZW50V2l0aEhhcmRlbmVkUGF0aFxuKTogU2FmZUhhcmRlbmVkQ2hpbGRLZXkge1xuICBjb25zdCBmaXJzdCA9IGRlcml2ZVNhZmVDaGlsZEhhcmRlbmVkRnJvbVhwcnYocm9vdFhwcnYsIHBhdGgpO1xuICBjb25zdCBzZWNvbmQgPSBkZXJpdmVTYWZlQ2hpbGRIYXJkZW5lZEZyb21YcHJ2KHJvb3RYcHJ2LCBwYXRoKTtcbiAgaWYgKGZpcnN0LnB1YiAhPT0gc2Vjb25kLnB1YiB8fCBmaXJzdC5wcnYgIT09IHNlY29uZC5wcnYpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFNhZmUgY2hpbGQgc2VsZi1jaGVjayBmYWlsZWQgYXQgJHtmaXJzdC5kZXJpdmF0aW9uUGF0aH06IGRlcml2YXRpb24gd2FzIG5vdCBkZXRlcm1pbmlzdGljYCk7XG4gIH1cbiAgcmV0dXJuIGZpcnN0O1xufVxuXG4vKipcbiAqIFNMSVAtMDAxMCBoYXJkZW5lZCBkZXJpdmF0aW9uIG9mIGEgc2FmZSB1c2VyIGNoaWxkIGZyb20gYW4gZWQyNTUxOSByb290IHNlY3JldCBzZWVkLlxuICpcbiAqIGByb290UHJ2YCBpcyBhIFN0ZWxsYXIgU3RyS2V5IGBT4oCmYCBzZWNyZXQgc2VlZCAod2hhdCBzbG90LeKRoSBgZWQyNTUxOU11bHRpc2lnYCB1c2VyIHJvb3RzIHN0b3JlKS5cbiAqIFRoZSBkZXJpdmF0aW9uIHJldXNlcyB0aGUgZXhpc3RpbmcgU0xJUC0wMDEwIGltcGxlbWVudGF0aW9uIHtAbGluayBFZDI1NTE5S2V5RGVyaXZlci5kZXJpdmVQYXRofVxuICogKGhhcmRlbmVkLW9ubHkgQ0tEUHJpdiBvdmVyIHRoZSBgZWQyNTUxOSBzZWVkYCBITUFDIG1hc3RlciksIHRoZW4gZXhwYW5kcyB0aGUgcmVzdWx0aW5nIDMyLWJ5dGVcbiAqIGNoaWxkIHNlZWQgaW50byBhIGtleXBhaXIgd2l0aCBgbmFjbGAuIFRoZSBjaGlsZCBgcHViYCBpcyBhIGJhcmUgU3RyS2V5IGBH4oCmYDsgdGhlIGBwcnZgIGlzIHRoZVxuICogcmF3IDMyLWJ5dGUgY2hpbGQgc2VlZCBhcyBoZXggKHRoZSBzZWVkIGlucHV0IGEgc2lnbmVyIG5lZWRzKS5cbiAqXG4gKiBVbmxpa2UgdGhlIHNlY3AyNTZrMSBwYXRoLCBlZDI1NTE5IGhhcmRlbmVkIGRlcml2YXRpb24gbmVlZHMgbm8gY2hhaW4gY29kZSDigJQgdGhlIGNvbXBvc2l0ZVxuICogYHB1YuKAlmNoYWluQ29kZWAgZm9ybSBpcyBvbmx5IGZvciBTT0ZUIGNvLXNpZ25lciBkZXJpdmF0aW9uIGFuZCBpcyBub3QgdXNlZCBoZXJlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZGVyaXZlU2FmZUNoaWxkRWQyNTUxOUhhcmRlbmVkKFxuICByb290UHJ2OiBzdHJpbmcsXG4gIHBhdGg6IERlcml2ZWRGcm9tUGFyZW50V2l0aEhhcmRlbmVkUGF0aFxuKTogU2FmZUhhcmRlbmVkQ2hpbGRLZXkge1xuICBhc3NlcnRIYXJkZW5lZFBhdGgocGF0aCk7XG4gIGNvbnN0IHJhd1NlZWRIZXggPSBkZWNvZGVFZDI1NTE5U3RyS2V5U2VjcmV0U2VlZChyb290UHJ2KS50b1N0cmluZygnaGV4Jyk7XG4gIGNvbnN0IGNoaWxkU2VlZCA9IEVkMjU1MTlLZXlEZXJpdmVyLmRlcml2ZVBhdGgocGF0aCwgcmF3U2VlZEhleCkua2V5O1xuICBjb25zdCBrZXlQYWlyID0gbmFjbC5zaWduLmtleVBhaXIuZnJvbVNlZWQoVWludDhBcnJheS5mcm9tKGNoaWxkU2VlZCkpO1xuICBjb25zdCBwdWIgPSBlbmNvZGVFZDI1NTE5U3RyS2V5UHVibGljS2V5KEJ1ZmZlci5mcm9tKGtleVBhaXIucHVibGljS2V5KSk7XG4gIHJldHVybiB7XG4gICAgcHJ2OiBCdWZmZXIuZnJvbShjaGlsZFNlZWQpLnRvU3RyaW5nKCdoZXgnKSxcbiAgICBwdWIsXG4gICAgZGVyaXZhdGlvblBhdGg6IHBhdGgsXG4gIH07XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2FmZVNlY3AyNTZrMUNoaWxkVHJpcGxldCB7XG4gIHVzZXI6IHsgcHJ2OiBzdHJpbmc7IHB1Yjogc3RyaW5nIH07XG4gIGJhY2t1cDogeyBwcnY6IHN0cmluZzsgcHViOiBzdHJpbmcgfTtcbiAgYml0Z286IHsgcHViOiBzdHJpbmcgfTtcbn1cblxuLyoqXG4gKiBEZXJpdmVzIHRoZSBzbG90LeKRoCAoc2VjcDI1NmsxTXVsdGlzaWcpIGNoaWxkIHRyaXBsZXQgZnJvbSB0aGUga2V5Y2FyZCByb290czogdGhlIHVzZXIgY2hpbGQgYXRcbiAqIHRoZSBoYXJkZW5lZCBgcGF0aGAsIHRoZSBiYWNrdXAgYW5kIEJpdEdvIGNoaWxkcmVuIGF0IGl0cyBzb2Z0IHR3aW4uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZXJpdmVTYWZlQ2hpbGRUcmlwbGV0KFxuICByb290czogeyB1c2VyOiBzdHJpbmc7IGJhY2t1cDogc3RyaW5nOyBiaXRnbzogc3RyaW5nIH0sXG4gIHBhdGg6IERlcml2ZWRGcm9tUGFyZW50V2l0aEhhcmRlbmVkUGF0aFxuKTogU2FmZVNlY3AyNTZrMUNoaWxkVHJpcGxldCB7XG4gIGFzc2VydEhhcmRlbmVkUGF0aChwYXRoKTtcbiAgY29uc3QgdXNlclJvb3QgPSBiaXAzMi5mcm9tQmFzZTU4KHJvb3RzLnVzZXIpO1xuICBjb25zdCBiYWNrdXBSb290ID0gYmlwMzIuZnJvbUJhc2U1OChyb290cy5iYWNrdXApO1xuICBjb25zdCBiaXRnb1Jvb3QgPSBiaXAzMi5mcm9tQmFzZTU4KHJvb3RzLmJpdGdvKTtcbiAgaWYgKHVzZXJSb290LmlzTmV1dGVyZWQoKSB8fCBiYWNrdXBSb290LmlzTmV1dGVyZWQoKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignZGVyaXZlU2FmZUNoaWxkVHJpcGxldDogdXNlciBhbmQgYmFja3VwIHJvb3RzIG11c3QgYmUgcHJpdmF0ZSAoeHBydiknKTtcbiAgfVxuICBpZiAoIWJpdGdvUm9vdC5pc05ldXRlcmVkKCkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2Rlcml2ZVNhZmVDaGlsZFRyaXBsZXQ6IGJpdGdvIHJvb3QgbXVzdCBiZSBwdWJsaWMgKHhwdWIpJyk7XG4gIH1cbiAgY29uc3Qgc29mdFBhdGggPSB0b1NvZnRUd2luUGF0aChwYXRoKTtcbiAgY29uc3QgdXNlciA9IHVzZXJSb290LmRlcml2ZVBhdGgocGF0aCk7XG4gIGNvbnN0IGJhY2t1cCA9IGJhY2t1cFJvb3QuZGVyaXZlUGF0aChzb2Z0UGF0aCk7XG4gIHJldHVybiB7XG4gICAgdXNlcjogeyBwcnY6IHVzZXIudG9CYXNlNTgoKSwgcHViOiB1c2VyLm5ldXRlcmVkKCkudG9CYXNlNTgoKSB9LFxuICAgIGJhY2t1cDogeyBwcnY6IGJhY2t1cC50b0Jhc2U1OCgpLCBwdWI6IGJhY2t1cC5uZXV0ZXJlZCgpLnRvQmFzZTU4KCkgfSxcbiAgICBiaXRnbzogeyBwdWI6IGJpdGdvUm9vdC5kZXJpdmVQYXRoKHNvZnRQYXRoKS50b0Jhc2U1OCgpIH0sXG4gIH07XG59XG4iXX0=