You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
503 lines
60 KiB
503 lines
60 KiB
(() => { |
|
// src/features/feature-inplace-encrypt/Decryptable.ts |
|
var Decryptable = class { |
|
}; |
|
|
|
// src/features/feature-inplace-encrypt/FeatureInplaceConstants.ts |
|
var _PREFIX_B = "%%\u{1F510}\u03B2 "; |
|
var _PREFIX_B_VISIBLE = "\u{1F510}\u03B2 "; |
|
var _PREFIX_A = "%%\u{1F510}\u03B1 "; |
|
var _PREFIX_A_VISIBLE = "\u{1F510}\u03B1 "; |
|
var _PREFIX_OBSOLETE = "%%\u{1F510} "; |
|
var _PREFIX_OBSOLETE_VISIBLE = "\u{1F510} "; |
|
var _PREFIX_ENCODE_DEFAULT = _PREFIX_B; |
|
var _PREFIX_ENCODE_DEFAULT_VISIBLE = _PREFIX_B_VISIBLE; |
|
var _PREFIXES = [ |
|
_PREFIX_B, |
|
_PREFIX_B_VISIBLE, |
|
_PREFIX_A, |
|
_PREFIX_A_VISIBLE, |
|
_PREFIX_OBSOLETE, |
|
_PREFIX_OBSOLETE_VISIBLE |
|
]; |
|
var _SUFFIX_WITH_COMMENT = " \u{1F510}%%"; |
|
var _SUFFIX_NO_COMMENT = " \u{1F510}"; |
|
var _SUFFIXES = [ |
|
_SUFFIX_WITH_COMMENT, |
|
_SUFFIX_NO_COMMENT |
|
]; |
|
var _HINT = "\u{1F4A1}"; |
|
|
|
// src/features/feature-inplace-encrypt/featureInplaceTextAnalysis.ts |
|
var FeatureInplaceTextAnalysis = class { |
|
constructor(text) { |
|
this.process(text); |
|
} |
|
process(text) { |
|
var _a, _b; |
|
this.processedText = text; |
|
this.isEmpty = text.length === 0; |
|
this.prefix = (_a = _PREFIXES.find((prefix) => text.startsWith(prefix))) != null ? _a : ""; |
|
this.suffix = (_b = _SUFFIXES.find((suffix) => text.endsWith(suffix))) != null ? _b : ""; |
|
this.hasEncryptedPrefix = this.prefix.length > 0; |
|
this.hasEncryptedSuffix = this.suffix.length > 0; |
|
this.hasObsoleteEncryptedPrefix = this.prefix === _PREFIX_OBSOLETE || this.prefix === _PREFIX_OBSOLETE_VISIBLE; |
|
this.containsEncryptedMarkers = [..._PREFIXES, ..._SUFFIXES].some((marker) => text.includes(marker)); |
|
this.canDecrypt = this.hasEncryptedPrefix && this.hasEncryptedSuffix; |
|
this.canEncrypt = !this.hasEncryptedPrefix && !this.containsEncryptedMarkers; |
|
if (this.canDecrypt) { |
|
const decryptable = this.parseDecryptableContent(text); |
|
if (decryptable != null) { |
|
this.decryptable = decryptable; |
|
} else { |
|
this.canDecrypt = false; |
|
} |
|
} |
|
} |
|
parseDecryptableContent(text) { |
|
const result = new Decryptable(); |
|
if (!this.hasEncryptedPrefix || !this.hasEncryptedSuffix) { |
|
return null; |
|
} |
|
if (this.hasObsoleteEncryptedPrefix) { |
|
result.version = 0; |
|
} else if (this.prefix == _PREFIX_B || this.prefix == _PREFIX_B_VISIBLE) { |
|
result.version = 2; |
|
} else if (this.prefix == _PREFIX_A || this.prefix == _PREFIX_A_VISIBLE) { |
|
result.version = 1; |
|
} |
|
const content = text.substring(this.prefix.length, text.length - this.suffix.length); |
|
if ([..._PREFIXES, ..._SUFFIXES].some((marker) => content.includes(marker))) { |
|
return null; |
|
} |
|
if (content.substring(0, _HINT.length) == _HINT) { |
|
const endHintMarker = content.indexOf(_HINT, _HINT.length); |
|
if (endHintMarker < 0) { |
|
return null; |
|
} |
|
result.hint = content.substring(_HINT.length, endHintMarker); |
|
result.base64CipherText = content.substring(endHintMarker + _HINT.length); |
|
} else { |
|
result.base64CipherText = content; |
|
} |
|
result.showInReadingView = !this.prefix.includes("%%"); |
|
return result; |
|
} |
|
}; |
|
|
|
// src/services/CryptoHelper.ts |
|
var vectorSize = 16; |
|
var utf8Encoder = new TextEncoder(); |
|
var utf8Decoder = new TextDecoder(); |
|
var iterations = 1e3; |
|
var salt = utf8Encoder.encode("XHWnDAT6ehMVY2zD"); |
|
var CryptoHelper = class { |
|
// constructor(){ |
|
// console.debug('new CryptoHelper'); |
|
// } |
|
async deriveKey(password) { |
|
const buffer = utf8Encoder.encode(password); |
|
const key = await crypto.subtle.importKey("raw", buffer, { name: "PBKDF2" }, false, ["deriveKey"]); |
|
const privateKey = crypto.subtle.deriveKey( |
|
{ |
|
name: "PBKDF2", |
|
hash: { name: "SHA-256" }, |
|
iterations, |
|
salt |
|
}, |
|
key, |
|
{ |
|
name: "AES-GCM", |
|
length: 256 |
|
}, |
|
false, |
|
["encrypt", "decrypt"] |
|
); |
|
return privateKey; |
|
} |
|
async encryptToBytes(text, password) { |
|
const key = await this.deriveKey(password); |
|
const textBytesToEncrypt = utf8Encoder.encode(text); |
|
const vector = crypto.getRandomValues(new Uint8Array(vectorSize)); |
|
const encryptedBytes = new Uint8Array( |
|
await crypto.subtle.encrypt( |
|
{ name: "AES-GCM", iv: vector }, |
|
key, |
|
textBytesToEncrypt |
|
) |
|
); |
|
const finalBytes = new Uint8Array(vector.byteLength + encryptedBytes.byteLength); |
|
finalBytes.set(vector, 0); |
|
finalBytes.set(encryptedBytes, vector.byteLength); |
|
return finalBytes; |
|
} |
|
convertToString(bytes) { |
|
let result = ""; |
|
for (let idx = 0; idx < bytes.length; idx++) { |
|
result += String.fromCharCode(bytes[idx]); |
|
} |
|
return result; |
|
} |
|
async encryptToBase64(text, password) { |
|
const finalBytes = await this.encryptToBytes(text, password); |
|
const base64Text = btoa(this.convertToString(finalBytes)); |
|
return base64Text; |
|
} |
|
stringToArray(str) { |
|
const result = []; |
|
for (let i = 0; i < str.length; i++) { |
|
result.push(str.charCodeAt(i)); |
|
} |
|
return new Uint8Array(result); |
|
} |
|
async decryptFromBytes(encryptedBytes, password) { |
|
try { |
|
const vector = encryptedBytes.slice(0, vectorSize); |
|
const encryptedTextBytes = encryptedBytes.slice(vectorSize); |
|
const key = await this.deriveKey(password); |
|
const decryptedBytes = await crypto.subtle.decrypt( |
|
{ name: "AES-GCM", iv: vector }, |
|
key, |
|
encryptedTextBytes |
|
); |
|
const decryptedText = utf8Decoder.decode(decryptedBytes); |
|
return decryptedText; |
|
} catch (e) { |
|
return null; |
|
} |
|
} |
|
async decryptFromBase64(base64Encoded, password) { |
|
try { |
|
const bytesToDecode = this.stringToArray(atob(base64Encoded)); |
|
return await this.decryptFromBytes(bytesToDecode, password); |
|
} catch (e) { |
|
return null; |
|
} |
|
} |
|
}; |
|
|
|
// src/services/CryptoHelper2304.ts |
|
var CryptoHelper2304 = class { |
|
constructor(vectorSize2, saltSize, iterations2) { |
|
this.vectorSize = vectorSize2; |
|
this.saltSize = saltSize; |
|
this.iterations = iterations2; |
|
} |
|
async deriveKey(password, salt2) { |
|
const utf8Encoder2 = new TextEncoder(); |
|
const buffer = utf8Encoder2.encode(password); |
|
const key = await crypto.subtle.importKey( |
|
/*format*/ |
|
"raw", |
|
/*keyData*/ |
|
buffer, |
|
/*algorithm*/ |
|
"PBKDF2", |
|
/*extractable*/ |
|
false, |
|
/*keyUsages*/ |
|
["deriveKey"] |
|
); |
|
try { |
|
const privateKey = await crypto.subtle.deriveKey( |
|
/*algorithm*/ |
|
{ |
|
name: "PBKDF2", |
|
hash: "SHA-512", |
|
salt: salt2, |
|
iterations: this.iterations |
|
}, |
|
/*baseKey*/ |
|
key, |
|
/*derivedKeyAlgorithm*/ |
|
{ |
|
name: "AES-GCM", |
|
length: 256 |
|
}, |
|
/*extractable*/ |
|
false, |
|
/*keyUsages*/ |
|
["encrypt", "decrypt"] |
|
); |
|
return privateKey; |
|
} finally { |
|
} |
|
} |
|
async encryptToBytes(text, password) { |
|
const salt2 = crypto.getRandomValues(new Uint8Array(this.saltSize)); |
|
const key = await this.deriveKey(password, salt2); |
|
const utf8Encoder2 = new TextEncoder(); |
|
const textBytesToEncrypt = utf8Encoder2.encode(text); |
|
const vector = crypto.getRandomValues(new Uint8Array(this.vectorSize)); |
|
const encryptedBytes = new Uint8Array( |
|
await crypto.subtle.encrypt( |
|
/*algorithm*/ |
|
{ |
|
name: "AES-GCM", |
|
iv: vector |
|
}, |
|
/*key*/ |
|
key, |
|
/*data*/ |
|
textBytesToEncrypt |
|
) |
|
); |
|
const finalBytes = new Uint8Array(vector.byteLength + salt2.byteLength + encryptedBytes.byteLength); |
|
finalBytes.set(vector, 0); |
|
finalBytes.set(salt2, vector.byteLength); |
|
finalBytes.set(encryptedBytes, vector.byteLength + salt2.byteLength); |
|
return finalBytes; |
|
} |
|
convertToString(bytes) { |
|
let result = ""; |
|
for (let idx = 0; idx < bytes.length; idx++) { |
|
result += String.fromCharCode(bytes[idx]); |
|
} |
|
return result; |
|
} |
|
async encryptToBase64(text, password) { |
|
const finalBytes = await this.encryptToBytes(text, password); |
|
const base64Text = btoa(this.convertToString(finalBytes)); |
|
return base64Text; |
|
} |
|
stringToArray(str) { |
|
const result = []; |
|
for (let i = 0; i < str.length; i++) { |
|
result.push(str.charCodeAt(i)); |
|
} |
|
return new Uint8Array(result); |
|
} |
|
async decryptFromBytes(encryptedBytes, password) { |
|
try { |
|
let offset; |
|
let nextOffset; |
|
offset = 0; |
|
nextOffset = offset + this.vectorSize; |
|
const vector = encryptedBytes.slice(offset, nextOffset); |
|
offset = nextOffset; |
|
nextOffset = offset + this.saltSize; |
|
const salt2 = encryptedBytes.slice(offset, nextOffset); |
|
offset = nextOffset; |
|
nextOffset = void 0; |
|
const encryptedTextBytes = encryptedBytes.slice(offset); |
|
const key = await this.deriveKey(password, salt2); |
|
const decryptedBytes = await crypto.subtle.decrypt( |
|
/*algorithm*/ |
|
{ |
|
name: "AES-GCM", |
|
iv: vector |
|
}, |
|
/*key*/ |
|
key, |
|
/*data*/ |
|
encryptedTextBytes |
|
); |
|
const utf8Decoder2 = new TextDecoder(); |
|
const decryptedText = utf8Decoder2.decode(decryptedBytes); |
|
return decryptedText; |
|
} catch (e) { |
|
return null; |
|
} |
|
} |
|
async decryptFromBase64(base64Encoded, password) { |
|
try { |
|
const bytesToDecode = this.stringToArray(atob(base64Encoded)); |
|
return await this.decryptFromBytes(bytesToDecode, password); |
|
} catch (e) { |
|
return null; |
|
} |
|
} |
|
}; |
|
|
|
// src/services/CryptoHelperObsolete.ts |
|
var algorithmObsolete = { |
|
name: "AES-GCM", |
|
iv: new Uint8Array([196, 190, 240, 190, 188, 78, 41, 132, 15, 220, 84, 211]), |
|
tagLength: 128 |
|
}; |
|
var CryptoHelperObsolete = class { |
|
async buildKey(password) { |
|
const utf8Encode = new TextEncoder(); |
|
const passwordBytes = utf8Encode.encode(password); |
|
const passwordDigest = await crypto.subtle.digest({ name: "SHA-256" }, passwordBytes); |
|
const key = await crypto.subtle.importKey( |
|
"raw", |
|
passwordDigest, |
|
algorithmObsolete, |
|
false, |
|
["encrypt", "decrypt"] |
|
); |
|
return key; |
|
} |
|
/** |
|
* @deprecated |
|
*/ |
|
async encryptToBase64(text, password) { |
|
const key = await this.buildKey(password); |
|
const utf8Encode = new TextEncoder(); |
|
const bytesToEncrypt = utf8Encode.encode(text); |
|
const encryptedBytes = new Uint8Array(await crypto.subtle.encrypt( |
|
algorithmObsolete, |
|
key, |
|
bytesToEncrypt |
|
)); |
|
const base64Text = btoa(String.fromCharCode(...encryptedBytes)); |
|
return base64Text; |
|
} |
|
stringToArray(str) { |
|
const result = []; |
|
for (let i = 0; i < str.length; i++) { |
|
result.push(str.charCodeAt(i)); |
|
} |
|
return new Uint8Array(result); |
|
} |
|
async decryptFromBase64(base64Encoded, password) { |
|
try { |
|
const bytesToDecrypt = this.stringToArray(atob(base64Encoded)); |
|
const key = await this.buildKey(password); |
|
const decryptedBytes = await crypto.subtle.decrypt(algorithmObsolete, key, bytesToDecrypt); |
|
const utf8Decode = new TextDecoder(); |
|
const decryptedText = utf8Decode.decode(decryptedBytes); |
|
return decryptedText; |
|
} catch (e) { |
|
return null; |
|
} |
|
} |
|
}; |
|
|
|
// src/services/CryptoHelperFactory.ts |
|
var _CryptoHelperFactory = class _CryptoHelperFactory { |
|
static BuildDefault() { |
|
return this.cryptoHelper2304_v2; |
|
} |
|
static BuildFromFileDataOrThrow(data) { |
|
const result = _CryptoHelperFactory.BuildFromFileDataOrNull(data); |
|
if (result != null) { |
|
return result; |
|
} |
|
throw new Error(`Unable to determine ICryptoHelper for File ver ${data.version}`); |
|
} |
|
static BuildFromFileDataOrNull(data) { |
|
if (data.version == "1.0") { |
|
return new CryptoHelper(); |
|
} |
|
if (data.version == "2.0") { |
|
return this.cryptoHelper2304_v2; |
|
} |
|
return null; |
|
} |
|
static BuildFromDecryptableOrThrow(decryptable) { |
|
const result = _CryptoHelperFactory.BuildFromDecryptableOrNull(decryptable); |
|
if (result != null) { |
|
return result; |
|
} |
|
throw new Error(`Unable to determine ICryptoHelper for Decryptable ver ${decryptable.version}`); |
|
} |
|
static BuildFromDecryptableOrNull(decryptable) { |
|
if (decryptable.version == 0) { |
|
return new CryptoHelperObsolete(); |
|
} |
|
if (decryptable.version == 1) { |
|
return new CryptoHelper(); |
|
} |
|
if (decryptable.version == 2) { |
|
return this.cryptoHelper2304_v2; |
|
} |
|
return null; |
|
} |
|
}; |
|
_CryptoHelperFactory.cryptoHelper2304_v2 = new CryptoHelper2304(16, 16, 21e4); |
|
var CryptoHelperFactory = _CryptoHelperFactory; |
|
|
|
// src/services/FileDataHelper.ts |
|
var FileData2 = class { |
|
constructor(version, hint, encodedData) { |
|
this.version = "1.0"; |
|
this.version = version; |
|
this.hint = hint; |
|
this.encodedData = encodedData; |
|
} |
|
}; |
|
var _FileDataHelper = class _FileDataHelper { |
|
static async encrypt(pass, hint, text) { |
|
const crypto2 = CryptoHelperFactory.BuildDefault(); |
|
const encryptedData = await crypto2.encryptToBase64(text, pass); |
|
return new FileData2(_FileDataHelper.DEFAULT_VERSION, hint, encryptedData); |
|
} |
|
static async decrypt(data, pass) { |
|
if (data.encodedData == "") { |
|
return ""; |
|
} |
|
const crypto2 = CryptoHelperFactory.BuildFromFileDataOrThrow(data); |
|
return await crypto2.decryptFromBase64(data.encodedData, pass); |
|
} |
|
}; |
|
_FileDataHelper.DEFAULT_VERSION = "2.0"; |
|
var FileDataHelper = _FileDataHelper; |
|
var JsonFileEncoding = class { |
|
static encode(data) { |
|
return JSON.stringify(data, null, 2); |
|
} |
|
static isEncoded(text) { |
|
try { |
|
JSON.parse(text); |
|
return true; |
|
} catch (error) { |
|
return false; |
|
} |
|
} |
|
static decode(encodedText) { |
|
if (encodedText === "") { |
|
return new FileData2(FileDataHelper.DEFAULT_VERSION, "", ""); |
|
} |
|
return JSON.parse(encodedText); |
|
} |
|
}; |
|
|
|
// src/tools/offline-decrypt.ts |
|
var OfflineDecrypt = class { |
|
async decrypt(content, password) { |
|
console.info("Trying the default decryption"); |
|
const chDef = CryptoHelperFactory.BuildDefault(); |
|
const result = await chDef.decryptFromBase64(content, password); |
|
if (result != null) { |
|
return result; |
|
} |
|
console.info("Trying marked inplace feature decryption"); |
|
const ta = new FeatureInplaceTextAnalysis(content); |
|
if (ta.decryptable != null) { |
|
const ch = CryptoHelperFactory.BuildFromDecryptableOrNull(ta.decryptable); |
|
if (ch != null) { |
|
const result2 = await ch.decryptFromBase64(ta.decryptable.base64CipherText, password); |
|
if (result2 != null) { |
|
return result2; |
|
} |
|
} |
|
} |
|
for (let ver = 10; ver >= 0; ver--) { |
|
console.info("Trying non-marked inplace feature decryption", "ver", ver); |
|
const decryptable = { version: ver, base64CipherText: content, hint: "", showInReadingView: false }; |
|
const ch = CryptoHelperFactory.BuildFromDecryptableOrNull(decryptable); |
|
const result2 = await (ch == null ? void 0 : ch.decryptFromBase64(decryptable.base64CipherText, password)); |
|
if (result2 != null) { |
|
return result2; |
|
} |
|
} |
|
console.info("Trying whole note feature decryption"); |
|
try { |
|
const fileData = JsonFileEncoding.decode(content); |
|
console.debug(fileData); |
|
const chFd = CryptoHelperFactory.BuildFromFileDataOrNull(fileData); |
|
const resultFd = await (chFd == null ? void 0 : chFd.decryptFromBase64(fileData.encodedData, password)); |
|
if (resultFd != null) { |
|
return resultFd; |
|
} |
|
} catch (e) { |
|
console.info(e); |
|
} |
|
return null; |
|
} |
|
}; |
|
window.$ = new OfflineDecrypt(); |
|
})(); |
|
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2ZlYXR1cmVzL2ZlYXR1cmUtaW5wbGFjZS1lbmNyeXB0L0RlY3J5cHRhYmxlLnRzIiwgIi4uL3NyYy9mZWF0dXJlcy9mZWF0dXJlLWlucGxhY2UtZW5jcnlwdC9GZWF0dXJlSW5wbGFjZUNvbnN0YW50cy50cyIsICIuLi9zcmMvZmVhdHVyZXMvZmVhdHVyZS1pbnBsYWNlLWVuY3J5cHQvZmVhdHVyZUlucGxhY2VUZXh0QW5hbHlzaXMudHMiLCAiLi4vc3JjL3NlcnZpY2VzL0NyeXB0b0hlbHBlci50cyIsICIuLi9zcmMvc2VydmljZXMvQ3J5cHRvSGVscGVyMjMwNC50cyIsICIuLi9zcmMvc2VydmljZXMvQ3J5cHRvSGVscGVyT2Jzb2xldGUudHMiLCAiLi4vc3JjL3NlcnZpY2VzL0NyeXB0b0hlbHBlckZhY3RvcnkudHMiLCAiLi4vc3JjL3NlcnZpY2VzL0ZpbGVEYXRhSGVscGVyLnRzIiwgIi4uL3NyYy90b29scy9vZmZsaW5lLWRlY3J5cHQudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImV4cG9ydCBjbGFzcyBEZWNyeXB0YWJsZXtcclxuXHR2ZXJzaW9uOiBudW1iZXI7XHJcblx0YmFzZTY0Q2lwaGVyVGV4dDpzdHJpbmc7XHJcblx0aGludDpzdHJpbmc7XHJcblx0c2hvd0luUmVhZGluZ1ZpZXc6IGJvb2xlYW47XHJcbn0iLCAiXHJcbmV4cG9ydCBjb25zdCBfUFJFRklYX0IgPSAnJSVcdUQ4M0RcdUREMTBcdTAzQjIgJztcclxuZXhwb3J0IGNvbnN0IF9QUkVGSVhfQl9WSVNJQkxFID0gJ1x1RDgzRFx1REQxMFx1MDNCMiAnO1xyXG5cclxuZXhwb3J0IGNvbnN0IF9QUkVGSVhfQSA9ICclJVx1RDgzRFx1REQxMFx1MDNCMSAnO1xyXG5leHBvcnQgY29uc3QgX1BSRUZJWF9BX1ZJU0lCTEUgPSAnXHVEODNEXHVERDEwXHUwM0IxICc7XHJcbmV4cG9ydCBjb25zdCBfUFJFRklYX09CU09MRVRFID0gJyUlXHVEODNEXHVERDEwICc7XHJcbmV4cG9ydCBjb25zdCBfUFJFRklYX09CU09MRVRFX1ZJU0lCTEUgPSAnXHVEODNEXHVERDEwICc7XHJcblxyXG5leHBvcnQgY29uc3QgX1BSRUZJWF9FTkNPREVfREVGQVVMVCA9IF9QUkVGSVhfQjtcclxuZXhwb3J0IGNvbnN0IF9QUkVGSVhfRU5DT0RFX0RFRkFVTFRfVklTSUJMRSA9IF9QUkVGSVhfQl9WSVNJQkxFO1xyXG5cclxuLy8gU2hvdWxkIGJlIGxpc3RlZCBieSBldmFsdWF0aW9uIHByaW9yaXR5XHJcbmV4cG9ydCBjb25zdCBfUFJFRklYRVMgPSBbXHJcblx0X1BSRUZJWF9CLFxyXG5cdF9QUkVGSVhfQl9WSVNJQkxFLFxyXG5cdF9QUkVGSVhfQSxcclxuXHRfUFJFRklYX0FfVklTSUJMRSxcclxuXHRfUFJFRklYX09CU09MRVRFLFxyXG5cdF9QUkVGSVhfT0JTT0xFVEVfVklTSUJMRVxyXG5dO1xyXG5cclxuZXhwb3J0IGNvbnN0IF9TVUZGSVhfV0lUSF9DT01NRU5UID0gJyBcdUQ4M0RcdUREMTAlJSc7XHJcbmV4cG9ydCBjb25zdCBfU1VGRklYX05PX0NPTU1FTlQgPSAnIFx1RDgzRFx1REQxMCc7XHJcblxyXG4vLyBTaG91bGQgYmUgbGlzdGVkIGJ5IGV2YWx1YXRpb24gcHJpb3JpdHlcclxuZXhwb3J0IGNvbnN0IF9TVUZGSVhFUyA9IFtcclxuXHRfU1VGRklYX1dJVEhfQ09NTUVOVCxcclxuXHRfU1VGRklYX05PX0NPTU1FTlRcclxuXVxyXG5cclxuZXhwb3J0IGNvbnN0IF9ISU5UID0gJ1x1RDgzRFx1RENBMSc7IiwgImltcG9ydCB7IERlY3J5cHRhYmxlIH0gZnJvbSBcIi4vRGVjcnlwdGFibGUudHNcIjtcclxuaW1wb3J0IHsgX0hJTlQsIF9QUkVGSVhFUywgX1BSRUZJWF9BLCBfUFJFRklYX0FfVklTSUJMRSwgX1BSRUZJWF9CLCBfUFJFRklYX0JfVklTSUJMRSwgX1BSRUZJWF9PQlNPTEVURSwgX1BSRUZJWF9PQlNPTEVURV9WSVNJQkxFLCBfU1VGRklYRVMgfSBmcm9tIFwiLi9GZWF0dXJlSW5wbGFjZUNvbnN0YW50cy50c1wiO1xyXG5cclxuZXhwb3J0IGNsYXNzIEZlYXR1cmVJbnBsYWNlVGV4dEFuYWx5c2lze1xyXG5cdHByb2Nlc3NlZFRleHQ6c3RyaW5nO1xyXG5cdGlzRW1wdHk6IGJvb2xlYW47XHJcblx0XHJcblx0cHJlZml4OiBzdHJpbmc7XHJcblx0c3VmZml4OiBzdHJpbmc7XHJcblxyXG5cdGhhc09ic29sZXRlRW5jcnlwdGVkUHJlZml4OiBib29sZWFuO1xyXG5cdGhhc0VuY3J5cHRlZFByZWZpeDogYm9vbGVhbjtcclxuXHRoYXNFbmNyeXB0ZWRTdWZmaXg6IGJvb2xlYW47XHJcblx0Y2FuRGVjcnlwdDogYm9vbGVhbjtcclxuXHRjYW5FbmNyeXB0OiBib29sZWFuO1xyXG5cdGNvbnRhaW5zRW5jcnlwdGVkTWFya2VyczogYm9vbGVhbjtcclxuXHRkZWNyeXB0YWJsZT8gOiBEZWNyeXB0YWJsZTtcclxuXHJcblx0Y29uc3RydWN0b3IodGV4dDogc3RyaW5nKXtcclxuXHRcdHRoaXMucHJvY2Vzcyh0ZXh0KTtcclxuXHR9XHJcblxyXG5cdHByaXZhdGUgcHJvY2VzcyggdGV4dDogc3RyaW5nICkgOiB2b2lke1xyXG5cdFx0XHJcblx0XHR0aGlzLnByb2Nlc3NlZFRleHQgPSB0ZXh0O1xyXG5cclxuXHRcdHRoaXMuaXNFbXB0eSA9IHRleHQubGVuZ3RoID09PSAwO1xyXG5cclxuXHRcdHRoaXMucHJlZml4ID0gX1BSRUZJWEVTLmZpbmQoIChwcmVmaXgpID0+IHRleHQuc3RhcnRzV2l0aChwcmVmaXgpICkgPz8gJyc7XHJcblx0XHR0aGlzLnN1ZmZpeCA9IF9TVUZGSVhFUy5maW5kKCAoc3VmZml4KSA9PiB0ZXh0LmVuZHNXaXRoKHN1ZmZpeCkgKSA/PyAnJztcclxuXHRcdFxyXG5cdFx0dGhpcy5oYXNFbmNyeXB0ZWRQcmVmaXggPSB0aGlzLnByZWZpeC5sZW5ndGggPiAwO1xyXG5cdFx0dGhpcy5oYXNFbmNyeXB0ZWRTdWZmaXggPSB0aGlzLnN1ZmZpeC5sZW5ndGggPiAwO1xyXG5cclxuXHRcdHRoaXMuaGFzT2Jzb2xldGVFbmNyeXB0ZWRQcmVmaXggPSB0aGlzLnByZWZpeCA9PT0gX1BSRUZJWF9PQlNPTEVURSB8fCB0aGlzLnByZWZpeCA9PT0gX1BSRUZJWF9PQlNPTEVURV9WSVNJQkxFO1xyXG5cclxuXHRcdHRoaXMuY29udGFpbnNFbmNyeXB0ZWRNYXJrZXJzID0gWy4uLl9QUkVGSVhFUywgLi4uX1NVRkZJWEVTXS5zb21lKCAobWFya2VyKSA9PiB0ZXh0LmluY2x1ZGVzKG1hcmtlciApKTtcclxuXHJcblx0XHR0aGlzLmNhbkRlY3J5cHQgPSB0aGlzLmhhc0VuY3J5cHRlZFByZWZpeCAmJiB0aGlzLmhhc0VuY3J5cHRlZFN1ZmZpeDtcclxuXHRcdHRoaXMuY2FuRW5jcnlwdCA9ICF0aGlzLmhhc0VuY3J5cHRlZFByZWZpeCAmJiAhdGhpcy5jb250YWluc0VuY3J5cHRlZE1hcmtlcnM7XHJcblx0XHRcclxuXHRcdGlmICh0aGlzLmNhbkRlY3J5cHQpe1xyXG5cdFx0XHRjb25zdCBkZWNyeXB0YWJsZSA9IHRoaXMucGFyc2VEZWNyeXB0YWJsZUNvbnRlbnQodGV4dCk7XHJcblxyXG5cdFx0XHRpZiAoIGRlY3J5cHRhYmxlICE9IG51bGwgKXtcclxuXHRcdFx0XHR0aGlzLmRlY3J5cHRhYmxlID0gZGVjcnlwdGFibGU7XHJcblx0XHRcdH1lbHNle1xyXG5cdFx0XHRcdHRoaXMuY2FuRGVjcnlwdCA9IGZhbHNlO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRwcml2YXRlIHBhcnNlRGVjcnlwdGFibGVDb250ZW50KHRleHQ6IHN0cmluZykgOiBEZWNyeXB0YWJsZSB8IG51bGwge1xyXG5cdFx0Y29uc3QgcmVzdWx0ID0gbmV3IERlY3J5cHRhYmxlKCk7XHJcblxyXG5cdFx0aWYgKFxyXG5cdFx0XHQhdGhpcy5oYXNFbmNyeXB0ZWRQcmVmaXhcclxuXHRcdFx0fHwgIXRoaXMuaGFzRW5jcnlwdGVkU3VmZml4XHJcblx0XHQpe1xyXG5cdFx0XHRyZXR1cm4gbnVsbDsgLy8gaW52YWxpZCBmb3JtYXRcclxuXHRcdH1cclxuXHRcdFxyXG5cdFx0aWYgKCB0aGlzLmhhc09ic29sZXRlRW5jcnlwdGVkUHJlZml4ICl7XHJcblx0XHRcdHJlc3VsdC52ZXJzaW9uID0gMDtcclxuXHRcdH1lbHNlIGlmICggdGhpcy5wcmVmaXggPT0gX1BSRUZJWF9CIHx8IHRoaXMucHJlZml4ID09IF9QUkVGSVhfQl9WSVNJQkxFICl7XHJcblx0XHRcdHJlc3VsdC52ZXJzaW9uID0gMjtcclxuXHRcdH1lbHNlIGlmICggdGhpcy5wcmVmaXggPT0gX1BSRUZJWF9BIHx8IHRoaXMucHJlZml4ID09IF9QUkVGSVhfQV9WSVNJQkxFICl7XHJcblx0XHRcdHJlc3VsdC52ZXJzaW9uID0gMTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyByZW1vdmUgbWFya2VycyBmcm9tIHN0YXJ0IGFuZCBlbmRcdFxyXG5cdFx0Y29uc3QgY29udGVudCA9IHRleHQuc3Vic3RyaW5nKHRoaXMucHJlZml4Lmxlbmd0aCwgdGV4dC5sZW5ndGggLSB0aGlzLnN1ZmZpeC5sZW5ndGgpO1xyXG5cclxuXHRcdGlmICggWy4uLl9QUkVGSVhFUywgLi4uX1NVRkZJWEVTXS5zb21lKCAobWFya2VyKSA9PiBjb250ZW50LmluY2x1ZGVzKCBtYXJrZXIgKSkgKXtcclxuXHRcdFx0Ly8gY29udGVudCwgaXRzZWxmIGhhcyBtYXJrZXJzXHJcblx0XHRcdHJldHVybiBudWxsO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIGNoZWNrIGlmIHRoZXJlIGlzIGEgaGludFxyXG5cdFx0aWYgKGNvbnRlbnQuc3Vic3RyaW5nKDAsX0hJTlQubGVuZ3RoKSA9PSBfSElOVCl7XHJcblx0XHRcdGNvbnN0IGVuZEhpbnRNYXJrZXIgPSBjb250ZW50LmluZGV4T2YoX0hJTlQsX0hJTlQubGVuZ3RoKTtcclxuXHRcdFx0aWYgKGVuZEhpbnRNYXJrZXI8MCl7XHJcblx0XHRcdFx0cmV0dXJuIG51bGw7IC8vIGludmFsaWQgZm9ybWF0XHJcblx0XHRcdH1cclxuXHRcdFx0cmVzdWx0LmhpbnQgPSBjb250ZW50LnN1YnN0cmluZyhfSElOVC5sZW5ndGgsZW5kSGludE1hcmtlcilcclxuXHRcdFx0cmVzdWx0LmJhc2U2NENpcGhlclRleHQgPSBjb250ZW50LnN1YnN0cmluZyhlbmRIaW50TWFya2VyK19ISU5ULmxlbmd0aCk7XHJcblx0XHR9ZWxzZXtcclxuXHRcdFx0cmVzdWx0LmJhc2U2NENpcGhlclRleHQgPSBjb250ZW50O1xyXG5cdFx0fVxyXG5cdFx0cmVzdWx0LnNob3dJblJlYWRpbmdWaWV3ID0gIXRoaXMucHJlZml4LmluY2x1ZGVzKFwiJSVcIik7XHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cclxuXHR9XHJcbn0iLCAiY29uc3QgdmVjdG9yU2l6ZVx0PSAxNjtcclxuY29uc3QgdXRmOEVuY29kZXJcdD0gbmV3IFRleHRFbmNvZGVyKCk7XHJcbmNvbnN0IHV0ZjhEZWNvZGVyXHQ9IG5ldyBUZXh0RGVjb2RlcigpO1xyXG5jb25zdCBpdGVyYXRpb25zXHQ9IDEwMDA7XHJcbmNvbnN0IHNhbHRcdFx0XHQ9IHV0ZjhFbmNvZGVyLmVuY29kZSgnWEhXbkRBVDZlaE1WWTJ6RCcpO1xyXG5cclxuZXhwb3J0IGNsYXNzIENyeXB0b0hlbHBlciB7XHJcblxyXG5cdC8vIGNvbnN0cnVjdG9yKCl7XHJcblx0Ly8gXHRjb25zb2xlLmRlYnVnKCduZXcgQ3J5cHRvSGVscGVyJyk7XHJcblx0Ly8gfVxyXG5cclxuXHRwcml2YXRlIGFzeW5jIGRlcml2ZUtleShwYXNzd29yZDpzdHJpbmcpIDpQcm9taXNlPENyeXB0b0tleT4ge1xyXG5cdFx0Y29uc3QgYnVmZmVyICAgICA9IHV0ZjhFbmNvZGVyLmVuY29kZShwYXNzd29yZCk7XHJcblx0XHRjb25zdCBrZXkgICAgICAgID0gYXdhaXQgY3J5cHRvLnN1YnRsZS5pbXBvcnRLZXkoJ3JhdycsIGJ1ZmZlciwge25hbWU6ICdQQktERjInfSwgZmFsc2UsIFsnZGVyaXZlS2V5J10pO1xyXG5cdFx0Y29uc3QgcHJpdmF0ZUtleSA9IGNyeXB0by5zdWJ0bGUuZGVyaXZlS2V5KFxyXG5cdFx0XHR7XHJcblx0XHRcdFx0bmFtZTogJ1BCS0RGMicsXHJcblx0XHRcdFx0aGFzaDoge25hbWU6ICdTSEEtMjU2J30sXHJcblx0XHRcdFx0aXRlcmF0aW9ucyxcclxuXHRcdFx0XHRzYWx0XHJcblx0XHRcdH0sXHJcblx0XHRcdGtleSxcclxuXHRcdFx0e1xyXG5cdFx0XHRcdG5hbWU6ICdBRVMtR0NNJyxcclxuXHRcdFx0XHRsZW5ndGg6IDI1NlxyXG5cdFx0XHR9LFxyXG5cdFx0XHRmYWxzZSxcclxuXHRcdFx0WydlbmNyeXB0JywgJ2RlY3J5cHQnXVxyXG5cdFx0KTtcclxuXHRcdFxyXG5cdFx0cmV0dXJuIHByaXZhdGVLZXk7XHJcblx0fVxyXG5cclxuXHRwdWJsaWMgYXN5bmMgZW5jcnlwdFRvQnl0ZXModGV4dDogc3RyaW5nLCBwYXNzd29yZDogc3RyaW5nKTogUHJvbWlzZTxVaW50OEFycmF5PiB7XHJcblxyXG5cdFx0Y29uc3Qga2V5ID0gYXdhaXQgdGhpcy5kZXJpdmVLZXkocGFzc3dvcmQpO1xyXG5cdFx0XHJcblx0XHRjb25zdCB0ZXh0Qnl0ZXNUb0VuY3J5cHQgPSB1dGY4RW5jb2Rlci5lbmNvZGUodGV4dCk7XHJcblx0XHRjb25zdCB2ZWN0b3IgPSBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKG5ldyBVaW50OEFycmF5KHZlY3RvclNpemUpKTtcclxuXHRcdFxyXG5cdFx0Ly8gZW5jcnlwdCBpbnRvIGJ5dGVzXHJcblx0XHRjb25zdCBlbmNyeXB0ZWRCeXRlcyA9IG5ldyBVaW50OEFycmF5KFxyXG5cdFx0XHRhd2FpdCBjcnlwdG8uc3VidGxlLmVuY3J5cHQoXHJcblx0XHRcdFx0e25hbWU6ICdBRVMtR0NNJywgaXY6IHZlY3Rvcn0sXHJcblx0XHRcdFx0a2V5LFxyXG5cdFx0XHRcdHRleHRCeXRlc1RvRW5jcnlwdFxyXG5cdFx0XHQpXHJcblx0XHQpO1xyXG5cdFx0XHJcblx0XHRjb25zdCBmaW5hbEJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkoIHZlY3Rvci5ieXRlTGVuZ3RoICsgZW5jcnlwdGVkQnl0ZXMuYnl0ZUxlbmd0aCApO1xyXG5cdFx0ZmluYWxCeXRlcy5zZXQoIHZlY3RvciwgMCApO1xyXG5cdFx0ZmluYWxCeXRlcy5zZXQoIGVuY3J5cHRlZEJ5dGVzLCB2ZWN0b3IuYnl0ZUxlbmd0aCApO1xyXG5cclxuXHRcdHJldHVybiBmaW5hbEJ5dGVzO1xyXG5cdH1cclxuXHJcblx0cHJpdmF0ZSBjb252ZXJ0VG9TdHJpbmcoIGJ5dGVzIDogVWludDhBcnJheSApOiBzdHJpbmcge1xyXG5cdFx0bGV0IHJlc3VsdCA9ICcnO1xyXG5cdFx0Zm9yIChsZXQgaWR4ID0gMDsgaWR4IDwgYnl0ZXMubGVuZ3RoOyBpZHgrKykge1xyXG5cdFx0XHQvLyBhcHBlbmQgdG8gcmVzdWx0XHJcblx0XHRcdHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ5dGVzW2lkeF0pO1xyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHB1YmxpYyBhc3luYyBlbmNyeXB0VG9CYXNlNjQodGV4dDogc3RyaW5nLCBwYXNzd29yZDogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+IHtcclxuXHJcblx0XHRjb25zdCBmaW5hbEJ5dGVzID0gYXdhaXQgdGhpcy5lbmNyeXB0VG9CeXRlcyh0ZXh0LCBwYXNzd29yZCk7XHJcblxyXG5cdFx0Ly9jb252ZXJ0IGFycmF5IHRvIGJhc2U2NFxyXG5cdFx0Y29uc3QgYmFzZTY0VGV4dCA9IGJ0b2EoIHRoaXMuY29udmVydFRvU3RyaW5nKGZpbmFsQnl0ZXMpICk7XHJcblxyXG5cdFx0cmV0dXJuIGJhc2U2NFRleHQ7XHJcblx0fVxyXG5cclxuXHRwcml2YXRlIHN0cmluZ1RvQXJyYXkoc3RyOiBzdHJpbmcpOiBVaW50OEFycmF5IHtcclxuXHRcdGNvbnN0IHJlc3VsdCA9IFtdO1xyXG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyBpKyspIHtcclxuXHRcdFx0cmVzdWx0LnB1c2goc3RyLmNoYXJDb2RlQXQoaSkpO1xyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIG5ldyBVaW50OEFycmF5KHJlc3VsdCk7XHJcblx0fVxyXG5cclxuXHRwdWJsaWMgYXN5bmMgZGVjcnlwdEZyb21CeXRlcyhlbmNyeXB0ZWRCeXRlczogVWludDhBcnJheSwgcGFzc3dvcmQ6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nfG51bGw+IHtcclxuXHRcdHRyeSB7XHJcblxyXG5cdFx0XHQvLyBleHRyYWN0IGl2XHJcblx0XHRcdGNvbnN0IHZlY3RvciA9IGVuY3J5cHRlZEJ5dGVzLnNsaWNlKDAsdmVjdG9yU2l6ZSk7XHJcblxyXG5cdFx0XHQvLyBleHRyYWN0IGVuY3J5cHRlZCB0ZXh0XHJcblx0XHRcdGNvbnN0IGVuY3J5cHRlZFRleHRCeXRlcyA9IGVuY3J5cHRlZEJ5dGVzLnNsaWNlKHZlY3RvclNpemUpO1xyXG5cclxuXHRcdFx0Y29uc3Qga2V5ID0gYXdhaXQgdGhpcy5kZXJpdmVLZXkocGFzc3dvcmQpO1xyXG5cclxuXHRcdFx0Ly8gZGVjcnlwdCBpbnRvIGJ5dGVzXHJcblx0XHRcdGNvbnN0IGRlY3J5cHRlZEJ5dGVzID0gYXdhaXQgY3J5cHRvLnN1YnRsZS5kZWNyeXB0KFxyXG5cdFx0XHRcdHtuYW1lOiAnQUVTLUdDTScsIGl2OiB2ZWN0b3J9LFxyXG5cdFx0XHRcdGtleSxcclxuXHRcdFx0XHRlbmNyeXB0ZWRUZXh0Qnl0ZXNcclxuXHRcdFx0KTtcclxuXHJcblx0XHRcdC8vIGNvbnZlcnQgYnl0ZXMgdG8gdGV4dFxyXG5cdFx0XHRjb25zdCBkZWNyeXB0ZWRUZXh0ID0gdXRmOERlY29kZXIuZGVjb2RlKGRlY3J5cHRlZEJ5dGVzKTtcclxuXHRcdFx0cmV0dXJuIGRlY3J5cHRlZFRleHQ7XHJcblx0XHR9IGNhdGNoIChlKSB7XHJcblx0XHRcdC8vY29uc29sZS5lcnJvcihlKTtcclxuXHRcdFx0cmV0dXJuIG51bGw7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRwdWJsaWMgYXN5bmMgZGVjcnlwdEZyb21CYXNlNjQoYmFzZTY0RW5jb2RlZDogc3RyaW5nLCBwYXNzd29yZDogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmd8bnVsbD4ge1xyXG5cdFx0dHJ5IHtcclxuXHJcblx0XHRcdGNvbnN0IGJ5dGVzVG9EZWNvZGUgPSB0aGlzLnN0cmluZ1RvQXJyYXkoYXRvYihiYXNlNjRFbmNvZGVkKSk7XHJcblx0XHRcdFxyXG5cdFx0XHRyZXR1cm4gYXdhaXQgdGhpcy5kZWNyeXB0RnJvbUJ5dGVzKGJ5dGVzVG9EZWNvZGUsIHBhc3N3b3JkKTtcclxuXHJcblx0XHRcdC8vIC8vIGV4dHJhY3QgaXZcclxuXHRcdFx0Ly8gY29uc3QgdmVjdG9yID0gYnl0ZXNUb0RlY29kZS5zbGljZSgwLHZlY3RvclNpemUpO1xyXG5cclxuXHRcdFx0Ly8gLy8gZXh0cmFjdCBlbmNyeXB0ZWQgdGV4dFxyXG5cdFx0XHQvLyBjb25zdCBlbmNyeXB0ZWRUZXh0Qnl0ZXMgPSBieXRlc1RvRGVjb2RlLnNsaWNlKHZlY3RvclNpemUpO1xyXG5cclxuXHRcdFx0Ly8gY29uc3Qga2V5ID0gYXdhaXQgdGhpcy5kZXJpdmVLZXkocGFzc3dvcmQpO1xyXG5cclxuXHRcdFx0Ly8gLy8gZGVjcnlwdCBpbnRvIGJ5dGVzXHJcblx0XHRcdC8vIGxldCBkZWNyeXB0ZWRCeXRlcyA9IGF3YWl0IGNyeXB0by5zdWJ0bGUuZGVjcnlwdChcclxuXHRcdFx0Ly8gXHR7bmFtZTogJ0FFUy1HQ00nLCBpdjogdmVjdG9yfSxcclxuXHRcdFx0Ly8gXHRrZXksXHJcblx0XHRcdC8vIFx0ZW5jcnlwdGVkVGV4dEJ5dGVzXHJcblx0XHRcdC8vICk7XHJcblxyXG5cdFx0XHQvLyAvLyBjb252ZXJ0IGJ5dGVzIHRvIHRleHRcclxuXHRcdFx0Ly8gbGV0IGRlY3J5cHRlZFRleHQgPSB1dGY4RGVjb2Rlci5kZWNvZGUoZGVjcnlwdGVkQnl0ZXMpO1xyXG5cdFx0XHQvLyByZXR1cm4gZGVjcnlwdGVkVGV4dDtcclxuXHRcdH0gY2F0Y2ggKGUpIHtcclxuXHRcdFx0Ly9jb25zb2xlLmVycm9yKGUpO1xyXG5cdFx0XHRyZXR1cm4gbnVsbDtcclxuXHRcdH1cclxuXHR9XHJcblxyXG59XHJcblxyXG5cclxuXHJcbiIsICJpbXBvcnQgeyBJQ3J5cHRvSGVscGVyIH0gZnJvbSBcIi4vSUNyeXB0b0hlbHBlci50c1wiO1xyXG5cclxuZXhwb3J0IGNsYXNzIENyeXB0b0hlbHBlcjIzMDQgaW1wbGVtZW50cyBJQ3J5cHRvSGVscGVyIHtcclxuXHRwdWJsaWMgdmVjdG9yU2l6ZTogbnVtYmVyO1xyXG5cdHB1YmxpYyBzYWx0U2l6ZTogbnVtYmVyO1xyXG5cdHB1YmxpYyBpdGVyYXRpb25zOiBudW1iZXI7XHJcblxyXG5cdGNvbnN0cnVjdG9yKCB2ZWN0b3JTaXplOiBudW1iZXIsIHNhbHRTaXplOiBudW1iZXIsIGl0ZXJhdGlvbnM6IG51bWJlciApe1xyXG5cdFx0Ly9jb25zb2xlLmRlYnVnKCduZXcgQ3J5cHRvSGVscGVyMjMwNCcsIHt2ZWN0b3JTaXplLCBzYWx0U2l6ZSwgaXRlcmF0aW9uc30pO1xyXG5cdFx0dGhpcy52ZWN0b3JTaXplID0gdmVjdG9yU2l6ZTtcclxuXHRcdHRoaXMuc2FsdFNpemUgPSBzYWx0U2l6ZTtcclxuXHRcdHRoaXMuaXRlcmF0aW9ucyA9IGl0ZXJhdGlvbnM7XHJcblx0fVxyXG5cclxuXHRwcml2YXRlIGFzeW5jIGRlcml2ZUtleSggcGFzc3dvcmQ6c3RyaW5nLCBzYWx0OlVpbnQ4QXJyYXkgKSA6UHJvbWlzZTxDcnlwdG9LZXk+IHtcclxuXHRcdC8vIGNvbnNvbGUudHJhY2UoJ0NyeXB0b0hlbHBlcjIzMDQuZGVyaXZlS2V5Jyk7XHJcblx0XHQvL1NlZTogaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL1N1YnRsZUNyeXB0b1xyXG5cdFx0Y29uc3QgdXRmOEVuY29kZXJcdD0gbmV3IFRleHRFbmNvZGVyKCk7XHJcblx0XHRjb25zdCBidWZmZXIgICAgID0gdXRmOEVuY29kZXIuZW5jb2RlKHBhc3N3b3JkKTtcclxuXHRcdGNvbnN0IGtleSAgICAgICAgPSBhd2FpdCBjcnlwdG8uc3VidGxlLmltcG9ydEtleShcclxuXHRcdFx0Lypmb3JtYXQqLyAncmF3JyxcclxuXHRcdFx0LyprZXlEYXRhKi8gYnVmZmVyLFxyXG5cdFx0XHQvKmFsZ29yaXRobSovICdQQktERjInLFxyXG5cdFx0XHQvKmV4dHJhY3RhYmxlKi8gZmFsc2UsXHJcblx0XHRcdC8qa2V5VXNhZ2VzKi8gWydkZXJpdmVLZXknXVxyXG5cdFx0KTtcclxuXHRcdFxyXG5cdFx0Ly9jb25zb2xlLnRpbWUoJ0NyeXB0b0hlbHBlcjIzMDQuZGVyaXZlS2V5Jyk7XHJcblx0XHR0cnl7XHJcblx0XHRcdGNvbnN0IHByaXZhdGVLZXkgPSBhd2FpdCBjcnlwdG8uc3VidGxlLmRlcml2ZUtleShcclxuXHRcdFx0XHQvKmFsZ29yaXRobSovIHtcclxuXHRcdFx0XHRcdG5hbWU6ICdQQktERjInLFxyXG5cdFx0XHRcdFx0aGFzaDogJ1NIQS01MTInLFxyXG5cdFx0XHRcdFx0c2FsdCxcclxuXHRcdFx0XHRcdGl0ZXJhdGlvbnM6IHRoaXMuaXRlcmF0aW9ucyxcclxuXHRcdFx0XHR9LFxyXG5cdFx0XHRcdC8qYmFzZUtleSovIGtleSxcclxuXHRcdFx0XHQvKmRlcml2ZWRLZXlBbGdvcml0aG0qLyB7XHJcblx0XHRcdFx0XHRuYW1lOiAnQUVTLUdDTScsXHJcblx0XHRcdFx0XHRsZW5ndGg6IDI1NlxyXG5cdFx0XHRcdH0sXHJcblx0XHRcdFx0LypleHRyYWN0YWJsZSovIGZhbHNlLFxyXG5cdFx0XHRcdC8qa2V5VXNhZ2VzKi8gWydlbmNyeXB0JywgJ2RlY3J5cHQnXVxyXG5cdFx0XHQpO1xyXG5cdFx0XHRcclxuXHRcdFx0cmV0dXJuIHByaXZhdGVLZXk7XHJcblx0XHR9ZmluYWxseXtcclxuXHRcdFx0Ly9jb25zb2xlLnRpbWVFbmQoJ0NyeXB0b0hlbHBlcjIzMDQuZGVyaXZlS2V5Jyk7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRwcml2YXRlIGFzeW5jIGVuY3J5cHRUb0J5dGVzKCB0ZXh0OiBzdHJpbmcsIHBhc3N3b3JkOiBzdHJpbmcgKTogUHJvbWlzZTxVaW50OEFycmF5PiB7XHJcblxyXG5cdFx0Y29uc3Qgc2FsdCA9IGNyeXB0by5nZXRSYW5kb21WYWx1ZXMoIG5ldyBVaW50OEFycmF5KHRoaXMuc2FsdFNpemUpICk7XHJcblxyXG5cdFx0Y29uc3Qga2V5ID0gYXdhaXQgdGhpcy5kZXJpdmVLZXkoIHBhc3N3b3JkLCBzYWx0ICk7XHJcblx0XHRcclxuXHRcdGNvbnN0IHV0ZjhFbmNvZGVyXHQ9IG5ldyBUZXh0RW5jb2RlcigpO1xyXG5cdFx0Y29uc3QgdGV4dEJ5dGVzVG9FbmNyeXB0ID0gdXRmOEVuY29kZXIuZW5jb2RlKHRleHQpO1xyXG5cdFx0Y29uc3QgdmVjdG9yID0gY3J5cHRvLmdldFJhbmRvbVZhbHVlcyhuZXcgVWludDhBcnJheSh0aGlzLnZlY3RvclNpemUpKTtcclxuXHRcdFxyXG5cdFx0Ly8gZW5jcnlwdCBpbnRvIGJ5dGVzXHJcblx0XHRjb25zdCBlbmNyeXB0ZWRCeXRlcyA9IG5ldyBVaW50OEFycmF5KFxyXG5cdFx0XHRhd2FpdCBjcnlwdG8uc3VidGxlLmVuY3J5cHQoXHJcblx0XHRcdFx0LyphbGdvcml0aG0qLyB7XHJcblx0XHRcdFx0XHRuYW1lOiAnQUVTLUdDTScsXHJcblx0XHRcdFx0XHRpdjogdmVjdG9yXHJcblx0XHRcdFx0fSxcclxuXHRcdFx0XHQvKmtleSovIGtleSxcclxuXHRcdFx0XHQvKmRhdGEqLyB0ZXh0Qnl0ZXNUb0VuY3J5cHRcclxuXHRcdFx0KVxyXG5cdFx0KTtcclxuXHRcdFxyXG5cdFx0Y29uc3QgZmluYWxCeXRlcyA9IG5ldyBVaW50OEFycmF5KCB2ZWN0b3IuYnl0ZUxlbmd0aCArIHNhbHQuYnl0ZUxlbmd0aCArIGVuY3J5cHRlZEJ5dGVzLmJ5dGVMZW5ndGggKTtcclxuXHRcdGZpbmFsQnl0ZXMuc2V0KCB2ZWN0b3IsIDAgKTtcclxuXHRcdGZpbmFsQnl0ZXMuc2V0KCBzYWx0LCB2ZWN0b3IuYnl0ZUxlbmd0aCApO1xyXG5cdFx0ZmluYWxCeXRlcy5zZXQoIGVuY3J5cHRlZEJ5dGVzLCB2ZWN0b3IuYnl0ZUxlbmd0aCArIHNhbHQuYnl0ZUxlbmd0aCApO1xyXG5cclxuXHRcdHJldHVybiBmaW5hbEJ5dGVzO1xyXG5cdH1cclxuXHJcblx0cHJpdmF0ZSBjb252ZXJ0VG9TdHJpbmcoIGJ5dGVzIDogVWludDhBcnJheSApOiBzdHJpbmcge1xyXG5cdFx0bGV0IHJlc3VsdCA9ICcnO1xyXG5cdFx0Zm9yIChsZXQgaWR4ID0gMDsgaWR4IDwgYnl0ZXMubGVuZ3RoOyBpZHgrKykge1xyXG5cdFx0XHQvLyBhcHBlbmQgdG8gcmVzdWx0XHJcblx0XHRcdHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ5dGVzW2lkeF0pO1xyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHB1YmxpYyBhc3luYyBlbmNyeXB0VG9CYXNlNjQodGV4dDogc3RyaW5nLCBwYXNzd29yZDogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+IHtcclxuXHJcblx0XHRjb25zdCBmaW5hbEJ5dGVzID0gYXdhaXQgdGhpcy5lbmNyeXB0VG9CeXRlcyh0ZXh0LCBwYXNzd29yZCk7XHJcblxyXG5cdFx0Ly9jb252ZXJ0IGFycmF5IHRvIGJhc2U2NFxyXG5cdFx0Y29uc3QgYmFzZTY0VGV4dCA9IGJ0b2EoIHRoaXMuY29udmVydFRvU3RyaW5nKGZpbmFsQnl0ZXMpICk7XHJcblxyXG5cdFx0cmV0dXJuIGJhc2U2NFRleHQ7XHJcblx0fVxyXG5cclxuXHRwcml2YXRlIHN0cmluZ1RvQXJyYXkoc3RyOiBzdHJpbmcpOiBVaW50OEFycmF5IHtcclxuXHRcdGNvbnN0IHJlc3VsdCA9IFtdO1xyXG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyBpKyspIHtcclxuXHRcdFx0cmVzdWx0LnB1c2goc3RyLmNoYXJDb2RlQXQoaSkpO1xyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIG5ldyBVaW50OEFycmF5KHJlc3VsdCk7XHJcblx0fVxyXG5cclxuXHRwcml2YXRlIGFzeW5jIGRlY3J5cHRGcm9tQnl0ZXMoXHJcblx0XHRlbmNyeXB0ZWRCeXRlczogVWludDhBcnJheSxcclxuXHRcdHBhc3N3b3JkOiBzdHJpbmdcclxuXHQpOiBQcm9taXNlPHN0cmluZ3xudWxsPiB7XHJcblx0XHR0cnkge1xyXG5cdFx0XHRcclxuXHRcdFx0bGV0IG9mZnNldDogbnVtYmVyO1xyXG5cdFx0XHRsZXQgbmV4dE9mZnNldCA6IG51bWJlcnx1bmRlZmluZWQ7XHJcblx0XHRcdFxyXG5cdFx0XHQvLyBleHRyYWN0IGl2XHJcblx0XHRcdG9mZnNldCA9IDA7XHJcblx0XHRcdG5leHRPZmZzZXQgPSBvZmZzZXQgKyB0aGlzLnZlY3RvclNpemU7XHJcblx0XHRcdGNvbnN0IHZlY3RvciA9IGVuY3J5cHRlZEJ5dGVzLnNsaWNlKG9mZnNldCwgbmV4dE9mZnNldCk7XHJcblx0XHRcdFxyXG5cdFx0XHQvLyBleHRyYWN0IHNhbHRcclxuXHRcdFx0b2Zmc2V0ID0gbmV4dE9mZnNldDtcclxuXHRcdFx0bmV4dE9mZnNldCA9IG9mZnNldCArIHRoaXMuc2FsdFNpemU7XHJcblx0XHRcdGNvbnN0IHNhbHQgPSBlbmNyeXB0ZWRCeXRlcy5zbGljZShvZmZzZXQsIG5leHRPZmZzZXQpO1xyXG5cdFx0XHRcclxuXHRcdFx0Ly8gZXh0cmFjdCBlbmNyeXB0ZWQgdGV4dFxyXG5cdFx0XHRvZmZzZXQgPSBuZXh0T2Zmc2V0O1xyXG5cdFx0XHRuZXh0T2Zmc2V0ID0gdW5kZWZpbmVkO1xyXG5cdFx0XHRjb25zdCBlbmNyeXB0ZWRUZXh0Qnl0ZXMgPSBlbmNyeXB0ZWRCeXRlcy5zbGljZShvZmZzZXQpO1xyXG5cdFx0XHRcclxuXHRcdFx0Y29uc3Qga2V5ID0gYXdhaXQgdGhpcy5kZXJpdmVLZXkocGFzc3dvcmQsIHNhbHQpO1xyXG5cdFx0XHRcclxuXHRcdFx0Ly8gZGVjcnlwdCBpbnRvIGJ5dGVzXHJcblx0XHRcdGNvbnN0IGRlY3J5cHRlZEJ5dGVzID0gYXdhaXQgY3J5cHRvLnN1YnRsZS5kZWNyeXB0KFxyXG5cdFx0XHRcdC8qYWxnb3JpdGhtKi8ge1xyXG5cdFx0XHRcdFx0bmFtZTogJ0FFUy1HQ00nLFxyXG5cdFx0XHRcdFx0aXY6IHZlY3RvclxyXG5cdFx0XHRcdH0sXHJcblx0XHRcdFx0LyprZXkqLyBrZXksXHJcblx0XHRcdFx0LypkYXRhKi8gZW5jcnlwdGVkVGV4dEJ5dGVzXHJcblx0XHRcdCk7XHJcblx0XHRcdFxyXG5cdFx0XHQvLyBjb252ZXJ0IGJ5dGVzIHRvIHRleHRcclxuXHRcdFx0Y29uc3QgdXRmOERlY29kZXJcdD0gbmV3IFRleHREZWNvZGVyKCk7XHJcblx0XHRcdGNvbnN0IGRlY3J5cHRlZFRleHQgPSB1dGY4RGVjb2Rlci5kZWNvZGUoZGVjcnlwdGVkQnl0ZXMpO1xyXG5cdFx0XHRyZXR1cm4gZGVjcnlwdGVkVGV4dDtcclxuXHRcdFx0XHJcblx0XHR9IGNhdGNoIChlKSB7XHJcblx0XHRcdC8vY29uc29sZS5lcnJvcihlKTtcclxuXHRcdFx0cmV0dXJuIG51bGw7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRwdWJsaWMgYXN5bmMgZGVjcnlwdEZyb21CYXNlNjQoIGJhc2U2NEVuY29kZWQ6IHN0cmluZywgcGFzc3dvcmQ6IHN0cmluZyApOiBQcm9taXNlPHN0cmluZ3xudWxsPiB7XHJcblx0XHR0cnkge1xyXG5cdFx0XHRjb25zdCBieXRlc1RvRGVjb2RlID0gdGhpcy5zdHJpbmdUb0FycmF5KGF0b2IoYmFzZTY0RW5jb2RlZCkpO1xyXG5cdFx0XHRyZXR1cm4gYXdhaXQgdGhpcy5kZWNyeXB0RnJvbUJ5dGVzKCBieXRlc1RvRGVjb2RlLCBwYXNzd29yZCApO1xyXG5cdFx0fSBjYXRjaCAoZSkge1xyXG5cdFx0XHRyZXR1cm4gbnVsbDtcclxuXHRcdH1cclxuXHR9XHJcblxyXG59IiwgImV4cG9ydCBjb25zdCBhbGdvcml0aG1PYnNvbGV0ZSA9IHtcclxuXHRuYW1lOiAnQUVTLUdDTScsXHJcblx0aXY6IG5ldyBVaW50OEFycmF5KFsxOTYsIDE5MCwgMjQwLCAxOTAsIDE4OCwgNzgsIDQxLCAxMzIsIDE1LCAyMjAsIDg0LCAyMTFdKSxcclxuXHR0YWdMZW5ndGg6IDEyOFxyXG59XHJcblxyXG5leHBvcnQgY2xhc3MgQ3J5cHRvSGVscGVyT2Jzb2xldGUge1xyXG5cclxuXHRwcml2YXRlIGFzeW5jIGJ1aWxkS2V5KHBhc3N3b3JkOiBzdHJpbmcpIHtcclxuXHRcdGNvbnN0IHV0ZjhFbmNvZGUgPSBuZXcgVGV4dEVuY29kZXIoKTtcclxuXHRcdGNvbnN0IHBhc3N3b3JkQnl0ZXMgPSB1dGY4RW5jb2RlLmVuY29kZShwYXNzd29yZCk7XHJcblxyXG5cdFx0Y29uc3QgcGFzc3dvcmREaWdlc3QgPSBhd2FpdCBjcnlwdG8uc3VidGxlLmRpZ2VzdCh7IG5hbWU6ICdTSEEtMjU2JyB9LCBwYXNzd29yZEJ5dGVzKTtcclxuXHJcblx0XHRjb25zdCBrZXkgPSBhd2FpdCBjcnlwdG8uc3VidGxlLmltcG9ydEtleShcclxuXHRcdFx0J3JhdycsXHJcblx0XHRcdHBhc3N3b3JkRGlnZXN0LFxyXG5cdFx0XHRhbGdvcml0aG1PYnNvbGV0ZSxcclxuXHRcdFx0ZmFsc2UsXHJcblx0XHRcdFsnZW5jcnlwdCcsICdkZWNyeXB0J11cclxuXHRcdCk7XHJcblxyXG5cdFx0cmV0dXJuIGtleTtcclxuXHR9XHJcblx0XHJcblx0LyoqXHJcbiAgXHQqIEBkZXByZWNhdGVkXHJcbiBcdCovXHJcblx0cHVibGljIGFzeW5jIGVuY3J5cHRUb0Jhc2U2NCh0ZXh0OiBzdHJpbmcsIHBhc3N3b3JkOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xyXG5cdFx0Y29uc3Qga2V5ID0gYXdhaXQgdGhpcy5idWlsZEtleShwYXNzd29yZCk7XHJcblxyXG5cdFx0Y29uc3QgdXRmOEVuY29kZSA9IG5ldyBUZXh0RW5jb2RlcigpO1xyXG5cdFx0Y29uc3QgYnl0ZXNUb0VuY3J5cHQgPSB1dGY4RW5jb2RlLmVuY29kZSh0ZXh0KTtcclxuXHJcblx0XHQvLyBlbmNyeXB0IGludG8gYnl0ZXNcclxuXHRcdGNvbnN0IGVuY3J5cHRlZEJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkoYXdhaXQgY3J5cHRvLnN1YnRsZS5lbmNyeXB0KFxyXG5cdFx0XHRhbGdvcml0aG1PYnNvbGV0ZSwga2V5LCBieXRlc1RvRW5jcnlwdFxyXG5cdFx0KSk7XHJcblxyXG5cdFx0Ly9jb252ZXJ0IGFycmF5IHRvIGJhc2U2NFxyXG5cdFx0Y29uc3QgYmFzZTY0VGV4dCA9IGJ0b2EoU3RyaW5nLmZyb21DaGFyQ29kZSguLi5lbmNyeXB0ZWRCeXRlcykpO1xyXG5cclxuXHRcdHJldHVybiBiYXNlNjRUZXh0O1xyXG5cdH1cclxuXHJcblx0cHJpdmF0ZSBzdHJpbmdUb0FycmF5KHN0cjogc3RyaW5nKTogVWludDhBcnJheSB7XHJcblx0XHRjb25zdCByZXN1bHQgPSBbXTtcclxuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgaSsrKSB7XHJcblx0XHRcdHJlc3VsdC5wdXNoKHN0ci5jaGFyQ29kZUF0KGkpKTtcclxuXHRcdH1cclxuXHRcdHJldHVybiBuZXcgVWludDhBcnJheShyZXN1bHQpO1xyXG5cdH1cclxuXHJcblx0cHVibGljIGFzeW5jIGRlY3J5cHRGcm9tQmFzZTY0KGJhc2U2NEVuY29kZWQ6IHN0cmluZywgcGFzc3dvcmQ6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nfG51bGw+IHtcclxuXHRcdHRyeSB7XHJcblx0XHRcdC8vIGNvbnZlcnQgYmFzZSA2NCB0byBhcnJheVxyXG5cdFx0XHRjb25zdCBieXRlc1RvRGVjcnlwdCA9IHRoaXMuc3RyaW5nVG9BcnJheShhdG9iKGJhc2U2NEVuY29kZWQpKTtcclxuXHJcblx0XHRcdGNvbnN0IGtleSA9IGF3YWl0IHRoaXMuYnVpbGRLZXkocGFzc3dvcmQpO1xyXG5cclxuXHRcdFx0Ly8gZGVjcnlwdCBpbnRvIGJ5dGVzXHJcblx0XHRcdGNvbnN0IGRlY3J5cHRlZEJ5dGVzID0gYXdhaXQgY3J5cHRvLnN1YnRsZS5kZWNyeXB0KGFsZ29yaXRobU9ic29sZXRlLCBrZXksIGJ5dGVzVG9EZWNyeXB0KTtcclxuXHJcblx0XHRcdC8vIGNvbnZlcnQgYnl0ZXMgdG8gdGV4dFxyXG5cdFx0XHRjb25zdCB1dGY4RGVjb2RlID0gbmV3IFRleHREZWNvZGVyKCk7XHJcblx0XHRcdGNvbnN0IGRlY3J5cHRlZFRleHQgPSB1dGY4RGVjb2RlLmRlY29kZShkZWNyeXB0ZWRCeXRlcyk7XHJcblx0XHRcdHJldHVybiBkZWNyeXB0ZWRUZXh0O1xyXG5cdFx0fSBjYXRjaCAoZSkge1xyXG5cdFx0XHRyZXR1cm4gbnVsbDtcclxuXHRcdH1cclxuXHR9XHJcblxyXG59XHJcbiIsICJpbXBvcnQgeyBGaWxlRGF0YSB9IGZyb20gXCIuL0ZpbGVEYXRhSGVscGVyLnRzXCI7XHJcbmltcG9ydCB7IERlY3J5cHRhYmxlIH0gZnJvbSBcIi4uL2ZlYXR1cmVzL2ZlYXR1cmUtaW5wbGFjZS1lbmNyeXB0L0RlY3J5cHRhYmxlLnRzXCI7XHJcbmltcG9ydCB7IENyeXB0b0hlbHBlciB9IGZyb20gXCIuL0NyeXB0b0hlbHBlci50c1wiO1xyXG5pbXBvcnQgeyBJQ3J5cHRvSGVscGVyIH0gZnJvbSBcIi4vSUNyeXB0b0hlbHBlci50c1wiO1xyXG5pbXBvcnQgeyBDcnlwdG9IZWxwZXIyMzA0IH0gZnJvbSBcIi4vQ3J5cHRvSGVscGVyMjMwNC50c1wiO1xyXG5pbXBvcnQgeyBDcnlwdG9IZWxwZXJPYnNvbGV0ZSB9IGZyb20gXCIuL0NyeXB0b0hlbHBlck9ic29sZXRlLnRzXCI7XHJcblxyXG5leHBvcnQgY2xhc3MgQ3J5cHRvSGVscGVyRmFjdG9yeXtcclxuXHJcblx0cHVibGljIHN0YXRpYyBjcnlwdG9IZWxwZXIyMzA0X3YyID0gbmV3IENyeXB0b0hlbHBlcjIzMDQoIDE2LCAxNiwgMjEwMDAwICk7XHJcblxyXG5cdHB1YmxpYyBzdGF0aWMgQnVpbGREZWZhdWx0KCk6IElDcnlwdG9IZWxwZXJ7XHJcblx0XHRyZXR1cm4gdGhpcy5jcnlwdG9IZWxwZXIyMzA0X3YyO1xyXG5cdH1cclxuXHJcblx0cHVibGljIHN0YXRpYyBCdWlsZEZyb21GaWxlRGF0YU9yVGhyb3coIGRhdGE6IEZpbGVEYXRhICkgOiBJQ3J5cHRvSGVscGVyIHtcclxuXHRcdGNvbnN0IHJlc3VsdCA9IENyeXB0b0hlbHBlckZhY3RvcnkuQnVpbGRGcm9tRmlsZURhdGFPck51bGwoZGF0YSk7XHJcblx0XHRpZiAoIHJlc3VsdCAhPSBudWxsICl7XHJcblx0XHRcdHJldHVybiByZXN1bHQ7XHJcblx0XHR9XHJcblx0XHR0aHJvdyBuZXcgRXJyb3IoIGBVbmFibGUgdG8gZGV0ZXJtaW5lIElDcnlwdG9IZWxwZXIgZm9yIEZpbGUgdmVyICR7ZGF0YS52ZXJzaW9ufWApO1xyXG5cdH1cclxuXHJcblx0cHVibGljIHN0YXRpYyBCdWlsZEZyb21GaWxlRGF0YU9yTnVsbCggZGF0YTogRmlsZURhdGEgKSA6IElDcnlwdG9IZWxwZXIgfCBudWxsIHtcclxuXHRcdGlmICggZGF0YS52ZXJzaW9uID09ICcxLjAnICl7XHJcblx0XHRcdHJldHVybiBuZXcgQ3J5cHRvSGVscGVyKCk7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gbm90ZVx0XHRcdFx0djIuMFx0Q3J5cHRvSGVscGVyMjMwNFxyXG5cdFx0aWYgKCBkYXRhLnZlcnNpb24gPT0gJzIuMCcgKXtcclxuXHRcdFx0cmV0dXJuIHRoaXMuY3J5cHRvSGVscGVyMjMwNF92MjtcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gbnVsbDtcclxuXHR9XHJcblxyXG5cdHB1YmxpYyBzdGF0aWMgQnVpbGRGcm9tRGVjcnlwdGFibGVPclRocm93KCBkZWNyeXB0YWJsZTogRGVjcnlwdGFibGUgKSA6IElDcnlwdG9IZWxwZXIge1xyXG5cdFx0Y29uc3QgcmVzdWx0ID0gQ3J5cHRvSGVscGVyRmFjdG9yeS5CdWlsZEZyb21EZWNyeXB0YWJsZU9yTnVsbCggZGVjcnlwdGFibGUgKTtcclxuXHJcblx0XHRpZiAocmVzdWx0ICE9IG51bGwpe1xyXG5cdFx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdFx0fVxyXG5cdFx0dGhyb3cgbmV3IEVycm9yKCBgVW5hYmxlIHRvIGRldGVybWluZSBJQ3J5cHRvSGVscGVyIGZvciBEZWNyeXB0YWJsZSB2ZXIgJHtkZWNyeXB0YWJsZS52ZXJzaW9ufWApO1xyXG5cdH1cclxuXHJcblx0cHVibGljIHN0YXRpYyBCdWlsZEZyb21EZWNyeXB0YWJsZU9yTnVsbCggZGVjcnlwdGFibGU6IERlY3J5cHRhYmxlICkgOiBJQ3J5cHRvSGVscGVyIHwgbnVsbCB7XHJcblx0XHQvLyBWZXJzaW9uc1xyXG5cdFx0Ly8gaW5wbGFjZSBvcmlnaW5hbFx0X1BSRUZJWF9PQlNPTEVURSA9ICclJVx1RDgzRFx1REQxMCAnICBDcnlwdG9IZWxwZXJPYnNvbGV0ZVxyXG5cdFx0XHJcblx0XHQvLyBpbnBsYWNlIGFscGhhXHRfUFJFRklYX0EgPSAnJSVcdUQ4M0RcdUREMTBcdTAzQjEgJ1x0XHRDcnlwdG9IZWxwZXJcclxuXHRcdC8vIFx0XHRcdFx0XHRfUFJFRklYX0FfVklTSUJMRSA9ICdcdUQ4M0RcdUREMTBcdTAzQjEgJ1x0Q3J5cHRvSGVscGVyXHJcblxyXG5cdFx0Ly8gaW5wbGFjZSBiZXRhIFx0X1BSRUZJWF9CID0gJyUlXHVEODNEXHVERDEwXHUwM0IyICdcdFx0Q3J5cHRvSGVscGVyMjMwNCggMTYsIDE2LCAyMTAwMDAgKVxyXG5cdFx0Ly9cdFx0XHRcdFx0X1BSRUZJWF9CX1ZJU0lCTEUgPSAnXHVEODNEXHVERDEwXHUwM0IyICdcdENyeXB0b0hlbHBlcjIzMDQoIDE2LCAxNiwgMjEwMDAwIClcclxuXHRcdFxyXG5cdFx0aWYgKCBkZWNyeXB0YWJsZS52ZXJzaW9uID09IDAgKXtcclxuXHRcdFx0cmV0dXJuIG5ldyBDcnlwdG9IZWxwZXJPYnNvbGV0ZSgpO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmICggZGVjcnlwdGFibGUudmVyc2lvbiA9PSAxICl7XHJcblx0XHRcdHJldHVybiBuZXcgQ3J5cHRvSGVscGVyKCk7XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKCBkZWNyeXB0YWJsZS52ZXJzaW9uID09IDIgKXtcclxuXHRcdFx0cmV0dXJuIHRoaXMuY3J5cHRvSGVscGVyMjMwNF92MjtcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gbnVsbDtcclxuXHR9XHJcblxyXG59IiwgImltcG9ydCB7IENyeXB0b0hlbHBlckZhY3RvcnkgfSBmcm9tIFwiLi9DcnlwdG9IZWxwZXJGYWN0b3J5LnRzXCI7XHJcblxyXG5leHBvcnQgY2xhc3MgRmlsZURhdGEge1xyXG5cdFxyXG5cdHB1YmxpYyB2ZXJzaW9uID0gJzEuMCc7XHJcblx0cHVibGljIGhpbnQ6IHN0cmluZztcclxuXHRwdWJsaWMgZW5jb2RlZERhdGE6c3RyaW5nO1xyXG5cclxuXHRjb25zdHJ1Y3RvciggdmVyc2lvbjpzdHJpbmcsIGhpbnQ6c3RyaW5nLCBlbmNvZGVkRGF0YTpzdHJpbmcgKXtcclxuXHRcdHRoaXMudmVyc2lvbiA9IHZlcnNpb247XHJcblx0XHR0aGlzLmhpbnQgPSBoaW50O1xyXG5cdFx0dGhpcy5lbmNvZGVkRGF0YSA9IGVuY29kZWREYXRhO1xyXG5cdH1cclxufVxyXG5cclxuZXhwb3J0IGNsYXNzIEZpbGVEYXRhSGVscGVye1xyXG5cclxuXHRwdWJsaWMgc3RhdGljIERFRkFVTFRfVkVSU0lPTiA9ICcyLjAnO1xyXG5cclxuXHRwdWJsaWMgc3RhdGljIGFzeW5jIGVuY3J5cHQoIHBhc3M6IHN0cmluZywgaGludDpzdHJpbmcsIHRleHQ6c3RyaW5nICkgOiBQcm9taXNlPEZpbGVEYXRhPntcclxuXHRcdGNvbnN0IGNyeXB0byA9IENyeXB0b0hlbHBlckZhY3RvcnkuQnVpbGREZWZhdWx0KCk7XHJcblx0XHRjb25zdCBlbmNyeXB0ZWREYXRhID0gYXdhaXQgY3J5cHRvLmVuY3J5cHRUb0Jhc2U2NCh0ZXh0LCBwYXNzKTtcclxuXHRcdHJldHVybiBuZXcgRmlsZURhdGEoIEZpbGVEYXRhSGVscGVyLkRFRkFVTFRfVkVSU0lPTiwgaGludCwgZW5jcnlwdGVkRGF0YSk7XHJcblx0fVxyXG5cclxuXHRwdWJsaWMgc3RhdGljIGFzeW5jIGRlY3J5cHQoIGRhdGE6IEZpbGVEYXRhLCBwYXNzOnN0cmluZyApIDogUHJvbWlzZTxzdHJpbmd8bnVsbD57XHJcblx0XHRpZiAoIGRhdGEuZW5jb2RlZERhdGEgPT0gJycgKXtcclxuXHRcdFx0cmV0dXJuICcnO1xyXG5cdFx0fVxyXG5cdFx0Y29uc3QgY3J5cHRvID0gQ3J5cHRvSGVscGVyRmFjdG9yeS5CdWlsZEZyb21GaWxlRGF0YU9yVGhyb3coIGRhdGEgKTtcclxuXHRcdHJldHVybiBhd2FpdCBjcnlwdG8uZGVjcnlwdEZyb21CYXNlNjQoIGRhdGEuZW5jb2RlZERhdGEsIHBhc3MgKTtcclxuXHR9XHJcbn1cclxuXHJcbmV4cG9ydCBjbGFzcyBKc29uRmlsZUVuY29kaW5nIHtcclxuXHJcblx0cHVibGljIHN0YXRpYyBlbmNvZGUoIGRhdGE6IEZpbGVEYXRhICkgOiBzdHJpbmd7XHJcblx0XHQvL2NvbnNvbGUuZGVidWcoICdKc29uRmlsZUVuY29kaW5nLmVuY29kZScsIHtkYXRhfSApO1xyXG5cdFx0cmV0dXJuIEpTT04uc3RyaW5naWZ5KGRhdGEsIG51bGwsIDIpO1xyXG5cdH1cclxuXHJcblx0cHVibGljIHN0YXRpYyBpc0VuY29kZWQoIHRleHQ6IHN0cmluZyApIDogYm9vbGVhbiB7XHJcblx0XHR0cnkge1xyXG5cdFx0XHRKU09OLnBhcnNlKCB0ZXh0ICk7XHJcblx0XHRcdHJldHVybiB0cnVlO1xyXG5cdFx0fSBjYXRjaCAoIGVycm9yICkge1xyXG5cdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRwdWJsaWMgc3RhdGljIGRlY29kZSggZW5jb2RlZFRleHQ6c3RyaW5nICkgOiBGaWxlRGF0YSB7XHJcblx0XHQvL2NvbnNvbGUuZGVidWcoJ0pzb25GaWxlRW5jb2RpbmcuZGVjb2RlJyx7ZW5jb2RlZFRleHR9KTtcclxuXHRcdGlmICggZW5jb2RlZFRleHQgPT09ICcnICl7XHJcblx0XHRcdHJldHVybiBuZXcgRmlsZURhdGEoIEZpbGVEYXRhSGVscGVyLkRFRkFVTFRfVkVSU0lPTiwgJycsICcnICk7XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gSlNPTi5wYXJzZSggZW5jb2RlZFRleHQgKSBhcyBGaWxlRGF0YTtcclxuXHR9XHJcbn0iLCAiaW1wb3J0IHsgRGVjcnlwdGFibGUgfSBmcm9tIFwiLi4vZmVhdHVyZXMvZmVhdHVyZS1pbnBsYWNlLWVuY3J5cHQvRGVjcnlwdGFibGUudHNcIjtcclxuaW1wb3J0IHsgRmVhdHVyZUlucGxhY2VUZXh0QW5hbHlzaXMgfSBmcm9tIFwiLi4vZmVhdHVyZXMvZmVhdHVyZS1pbnBsYWNlLWVuY3J5cHQvZmVhdHVyZUlucGxhY2VUZXh0QW5hbHlzaXMudHNcIjtcclxuaW1wb3J0IHsgQ3J5cHRvSGVscGVyRmFjdG9yeSB9IGZyb20gXCIuLi9zZXJ2aWNlcy9DcnlwdG9IZWxwZXJGYWN0b3J5LnRzXCI7XHJcbmltcG9ydCB7IEpzb25GaWxlRW5jb2RpbmcgfSBmcm9tIFwiLi4vc2VydmljZXMvRmlsZURhdGFIZWxwZXIudHNcIjtcclxuXHJcbmV4cG9ydCBjbGFzcyBPZmZsaW5lRGVjcnlwdCB7XHJcblxyXG5cdHB1YmxpYyBhc3luYyBkZWNyeXB0KCBjb250ZW50OnN0cmluZywgcGFzc3dvcmQ6IHN0cmluZyApIDogUHJvbWlzZTxzdHJpbmcgfCBudWxsPiB7XHJcblxyXG5cdFx0Ly8gVHJ5aW5nIHRoZSBkZWZhdWx0IGRlY3J5cHRpb25cclxuXHRcdGNvbnNvbGUuaW5mbyggJ1RyeWluZyB0aGUgZGVmYXVsdCBkZWNyeXB0aW9uJyApO1xyXG5cdFx0Y29uc3QgY2hEZWYgPSBDcnlwdG9IZWxwZXJGYWN0b3J5LkJ1aWxkRGVmYXVsdCgpO1xyXG5cdFx0Y29uc3QgcmVzdWx0ID0gYXdhaXQgY2hEZWYuZGVjcnlwdEZyb21CYXNlNjQoIGNvbnRlbnQsIHBhc3N3b3JkICk7XHJcblx0XHRpZiAoIHJlc3VsdCAhPSBudWxsICl7XHJcblx0XHRcdHJldHVybiByZXN1bHQ7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gVHJ5aW5nIG1hcmtlZCBpbnBsYWNlIGZlYXR1cmUgZGVjcnlwdGlvblxyXG5cdFx0Y29uc29sZS5pbmZvKCAnVHJ5aW5nIG1hcmtlZCBpbnBsYWNlIGZlYXR1cmUgZGVjcnlwdGlvbicgKTtcclxuXHRcdGNvbnN0IHRhID0gbmV3IEZlYXR1cmVJbnBsYWNlVGV4dEFuYWx5c2lzKCBjb250ZW50ICk7XHJcblx0XHRpZiAoIHRhLmRlY3J5cHRhYmxlICE9IG51bGwgKXtcclxuXHRcdFx0Y29uc3QgY2ggPSBDcnlwdG9IZWxwZXJGYWN0b3J5LkJ1aWxkRnJvbURlY3J5cHRhYmxlT3JOdWxsKHRhLmRlY3J5cHRhYmxlKTtcclxuXHRcdFx0aWYgKGNoICE9IG51bGwpe1xyXG5cdFx0XHRcdGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNoLmRlY3J5cHRGcm9tQmFzZTY0KCB0YS5kZWNyeXB0YWJsZS5iYXNlNjRDaXBoZXJUZXh0LCBwYXNzd29yZCApO1xyXG5cdFx0XHRcdGlmICggcmVzdWx0ICE9IG51bGwgKXtcclxuXHRcdFx0XHRcdHJldHVybiByZXN1bHQ7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gVHJ5aW5nIG5vbi1tYXJrZWQgaW5wbGFjZSBmZWF0dXJlIGRlY3J5cHRpb25cclxuXHRcdGZvciAobGV0IHZlciA9IDEwOyB2ZXIgPj0gMDsgdmVyLS0pIHtcclxuXHRcdFx0Y29uc29sZS5pbmZvKCAnVHJ5aW5nIG5vbi1tYXJrZWQgaW5wbGFjZSBmZWF0dXJlIGRlY3J5cHRpb24nLCAndmVyJywgdmVyICk7XHJcblx0XHRcdGNvbnN0IGRlY3J5cHRhYmxlIDogRGVjcnlwdGFibGUgPSB7IHZlcnNpb246IHZlciwgYmFzZTY0Q2lwaGVyVGV4dDogY29udGVudCwgaGludDogJycsIHNob3dJblJlYWRpbmdWaWV3OiBmYWxzZSB9O1xyXG5cdFx0XHRjb25zdCBjaCA9IENyeXB0b0hlbHBlckZhY3RvcnkuQnVpbGRGcm9tRGVjcnlwdGFibGVPck51bGwoZGVjcnlwdGFibGUpXHJcblx0XHRcdGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNoPy5kZWNyeXB0RnJvbUJhc2U2NCggZGVjcnlwdGFibGUuYmFzZTY0Q2lwaGVyVGV4dCwgcGFzc3dvcmQgKTtcclxuXHRcdFx0aWYgKCByZXN1bHQgIT0gbnVsbCApe1xyXG5cdFx0XHRcdHJldHVybiByZXN1bHQ7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblxyXG5cdFx0Ly8gVHJ5aW5nIHdob2xlIG5vdGUgZmVhdHVyZSBkZWNyeXB0aW9uXHJcblx0XHRjb25zb2xlLmluZm8oICdUcnlpbmcgd2hvbGUgbm90ZSBmZWF0dXJlIGRlY3J5cHRpb24nICk7XHJcblx0XHR0cnl7XHJcblx0XHRcdGNvbnN0IGZpbGVEYXRhID0gSnNvbkZpbGVFbmNvZGluZy5kZWNvZGUoIGNvbnRlbnQgKTtcclxuXHRcdFx0Y29uc29sZS5kZWJ1ZyhmaWxlRGF0YSk7XHJcblx0XHRcdGNvbnN0IGNoRmQgPSBDcnlwdG9IZWxwZXJGYWN0b3J5LkJ1aWxkRnJvbUZpbGVEYXRhT3JOdWxsKCBmaWxlRGF0YSApO1xyXG5cdFx0XHRjb25zdCByZXN1bHRGZCA9IGF3YWl0IGNoRmQ/LmRlY3J5cHRGcm9tQmFzZTY0KCBmaWxlRGF0YS5lbmNvZGVkRGF0YSwgcGFzc3dvcmQgKTtcclxuXHRcdFx0aWYgKCByZXN1bHRGZCAhPSBudWxsICl7XHJcblx0XHRcdFx0cmV0dXJuIHJlc3VsdEZkO1xyXG5cdFx0XHR9XHJcblx0XHR9IGNhdGNoIChlKXtcclxuXHRcdFx0Y29uc29sZS5pbmZvKGUpO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBudWxsO1xyXG5cdH1cclxufVxyXG5kZWNsYXJlIGdsb2JhbCB7XHJcbiAgICBpbnRlcmZhY2UgV2luZG93IHsgJDogT2ZmbGluZURlY3J5cHQ7IH1cclxufVxyXG5cclxud2luZG93LiQgPSBuZXcgT2ZmbGluZURlY3J5cHQoKTtc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TUFBTTtBQUNwQixpQkFBT0E7QUFBQSxRQUNSO0FBQUEsTUFDRDtBQUlBLGNBQVEsS0FBTSxzQ0FBdUM7QUFDckQsVUFBRztBQUNGLGNBQU0sV0FBVyxpQkFBaUIsT0FBUSxPQUFRO0FBQ2xELGdCQUFRLE1BQU0sUUFBUTtBQUN0QixjQUFNLE9BQU8sb0JBQW9CLHdCQUF5QixRQUFTO0FBQ25FLGNBQU0sV0FBVyxPQUFNLDZCQUFNLGtCQUFtQixTQUFTLGFBQWE7QUFDdEUsWUFBSyxZQUFZLE1BQU07QUFDdEIsaUJBQU87QUFBQSxRQUNSO0FBQUEsTUFDRCxTQUFTLEdBQUU7QUFDVixnQkFBUSxLQUFLLENBQUM7QUFBQSxNQUNmO0FBRUEsYUFBTztBQUFBLElBQ1I7QUFBQSxFQUNEO0FBS0EsU0FBTyxJQUFJLElBQUksZUFBZTsiLAogICJuYW1lcyI6IFsidmVjdG9yU2l6ZSIsICJpdGVyYXRpb25zIiwgInNhbHQiLCAidXRmOEVuY29kZXIiLCAidXRmOERlY29kZXIiLCAiRmlsZURhdGEiLCAiY3J5cHRvIiwgInJlc3VsdCJdCn0K
|
|
|