ngx-ui-hero
Version:
Simple, fast and reliable utilities for Angular.
369 lines • 52.1 kB
JavaScript
/**
* @hidden
*/
export const MASK_FLAGS = ['C', '&', 'a', 'A', '?', 'L', '9', '0', '#'];
/**
* @hidden
*/
export const KEYS = {
Ctrl: 17,
Z: 90,
Y: 89,
X: 88,
BACKSPACE: 8,
DELETE: 46
};
/**
* @hidden
*/
export class MaskHelper {
get cursor() {
return this._cursor;
}
parseValueByMask(value, maskOptions, cursor) {
let inputValue = value;
const mask = maskOptions.format;
const literals = this.getMaskLiterals(mask);
const literalKeys = Array.from(literals.keys());
const nonLiteralIndeces = this.getNonLiteralIndeces(mask, literalKeys);
if (inputValue.length < mask.length) { // BACKSPACE, DELETE
if (inputValue === '' && cursor === -1) {
this._cursor = 0;
return this.parseValueByMaskOnInit(value, maskOptions);
} // workaround for IE 'x' button
if (nonLiteralIndeces.indexOf(cursor + 1) !== -1) {
inputValue = this.insertCharAt(inputValue, cursor + 1, maskOptions.promptChar);
this._cursor = cursor + 1;
}
else {
inputValue = this.insertCharAt(inputValue, cursor + 1, mask[cursor + 1]);
this._cursor = cursor + 1;
for (let i = this._cursor; i < 0; i--) {
if (literalKeys.indexOf(this._cursor) !== -1) {
this._cursor--;
}
else {
break;
}
}
}
}
else {
const char = inputValue[cursor];
let isCharValid = this.validateCharOnPostion(char, cursor, mask);
if (nonLiteralIndeces.indexOf(cursor) !== -1) {
inputValue = this.replaceCharAt(inputValue, cursor, '');
if (isCharValid) {
inputValue = this.replaceCharAt(inputValue, cursor, char);
this._cursor = cursor + 1;
}
else {
this._cursor = cursor;
}
}
else {
inputValue = this.replaceCharAt(inputValue, cursor, '');
this._cursor = ++cursor;
for (let i = cursor; i < mask.length; i++) {
if (literalKeys.indexOf(this._cursor) !== -1) {
this._cursor = ++cursor;
}
else {
isCharValid = this.validateCharOnPostion(char, cursor, mask);
if (isCharValid) {
inputValue = this.replaceCharAt(inputValue, cursor, char);
this._cursor = ++cursor;
break;
}
else {
break;
}
}
}
}
}
return inputValue;
}
parseMask(maskOptions) {
let outputVal = '';
const mask = maskOptions.format;
const literals = this.getMaskLiterals(mask);
for (const maskSym of mask) {
outputVal += maskOptions.promptChar;
}
literals.forEach((val, key) => {
outputVal = this.replaceCharAt(outputVal, key, val);
});
return outputVal;
}
parseValueByMaskOnInit(inputVal, maskOptions) {
let outputVal = '';
let value = '';
const mask = maskOptions.format;
const literals = this.getMaskLiterals(mask);
const literalKeys = Array.from(literals.keys());
const nonLiteralIndeces = this.getNonLiteralIndeces(mask, literalKeys);
const literalValues = Array.from(literals.values());
if (inputVal != null) {
value = inputVal.toString();
}
for (const maskSym of mask) {
outputVal += maskOptions.promptChar;
}
literals.forEach((val, key) => {
outputVal = this.replaceCharAt(outputVal, key, val);
});
if (!value) {
return outputVal;
}
const nonLiteralValues = this.getNonLiteralValues(value, literalValues);
for (let i = 0; i < nonLiteralValues.length; i++) {
const char = nonLiteralValues[i];
const isCharValid = this.validateCharOnPostion(char, nonLiteralIndeces[i], mask);
if (!isCharValid && char !== maskOptions.promptChar) {
nonLiteralValues[i] = maskOptions.promptChar;
}
}
if (nonLiteralValues.length > nonLiteralIndeces.length) {
nonLiteralValues.splice(nonLiteralIndeces.length);
}
let pos = 0;
for (const nonLiteralValue of nonLiteralValues) {
const char = nonLiteralValue;
outputVal = this.replaceCharAt(outputVal, nonLiteralIndeces[pos++], char);
}
return outputVal;
}
restoreValueFromMask(value, maskOptions) {
let outputVal = '';
const mask = maskOptions.format;
const literals = this.getMaskLiterals(mask);
const literalValues = Array.from(literals.values());
for (const val of value) {
if (literalValues.indexOf(val) === -1) {
if (val !== maskOptions.promptChar) {
outputVal += val;
}
}
}
return outputVal;
}
parseValueByMaskUponSelection(value, maskOptions, cursor, selection) {
let isCharValid;
let inputValue = value;
const char = inputValue[cursor];
const mask = maskOptions.format;
const literals = this.getMaskLiterals(mask);
const literalKeys = Array.from(literals.keys());
const nonLiteralIndeces = this.getNonLiteralIndeces(mask, literalKeys);
if (!this.data) {
this._cursor = cursor < 0 ? ++cursor : cursor;
if (nonLiteralIndeces.indexOf(this._cursor) !== -1) {
isCharValid = this.validateCharOnPostion(char, this._cursor, mask);
inputValue = isCharValid ? this.replaceCharAt(inputValue, this._cursor++, char) :
inputValue = this.replaceCharAt(inputValue, this._cursor++, maskOptions.promptChar);
selection--;
if (selection > 0) {
for (let i = 0; i < selection; i++) {
cursor++;
inputValue = nonLiteralIndeces.indexOf(cursor) !== -1 ?
this.insertCharAt(inputValue, cursor, maskOptions.promptChar) :
this.insertCharAt(inputValue, cursor, mask[cursor]);
}
}
}
else {
inputValue = this.replaceCharAt(inputValue, this._cursor, mask[this._cursor]);
this._cursor++;
selection--;
let isMarked = false;
if (selection > 0) {
cursor = this._cursor;
for (let i = 0; i < selection; i++) {
if (nonLiteralIndeces.indexOf(cursor) !== -1) {
isCharValid = this.validateCharOnPostion(char, cursor, mask);
if (isCharValid && !isMarked) {
inputValue = this.insertCharAt(inputValue, cursor, char);
cursor++;
this._cursor++;
isMarked = true;
}
else {
inputValue = this.insertCharAt(inputValue, cursor, maskOptions.promptChar);
cursor++;
}
}
else {
inputValue = this.insertCharAt(inputValue, cursor, mask[cursor]);
if (cursor === this._cursor) {
this._cursor++;
}
cursor++;
}
}
}
}
}
else {
if (inputValue === '' && cursor === -1) {
this._cursor = 0;
return this.parseValueByMaskOnInit(value, maskOptions);
} // workaround for IE 'x' button
if (this._cursor < 0) {
this._cursor++;
cursor++;
}
cursor++;
this._cursor = cursor;
for (let i = 0; i < selection; i++) {
if (nonLiteralIndeces.indexOf(cursor) !== -1) {
inputValue = this.insertCharAt(inputValue, cursor, maskOptions.promptChar);
cursor++;
}
else {
inputValue = this.insertCharAt(inputValue, cursor, mask[cursor]);
cursor++;
}
}
}
return inputValue;
}
parseValueByMaskUponCopyPaste(value, maskOptions, cursor, clipboardData, selection) {
let inputValue = value;
const mask = maskOptions.format;
const literals = this.getMaskLiterals(mask);
const literalKeys = Array.from(literals.keys());
const nonLiteralIndeces = this.getNonLiteralIndeces(mask, literalKeys);
const selectionEnd = cursor + selection;
this._cursor = cursor;
for (const clipboardSym of clipboardData) {
const char = clipboardSym;
if (this._cursor > mask.length) {
return inputValue;
}
if (nonLiteralIndeces.indexOf(this._cursor) !== -1) {
const isCharValid = this.validateCharOnPostion(char, this._cursor, mask);
if (isCharValid) {
inputValue = this.replaceCharAt(inputValue, this._cursor++, char);
}
}
else {
for (let i = cursor; i < mask.length; i++) {
if (literalKeys.indexOf(this._cursor) !== -1) {
this._cursor++;
}
else {
const isCharValid = this.validateCharOnPostion(char, this._cursor, mask);
if (isCharValid) {
inputValue = this.replaceCharAt(inputValue, this._cursor++, char);
}
break;
}
}
}
selection--;
}
if (selection > 0) {
for (let i = this._cursor; i < selectionEnd; i++) {
if (literalKeys.indexOf(this._cursor) !== -1) {
this._cursor++;
}
else {
inputValue = this.replaceCharAt(inputValue, this._cursor++, maskOptions.promptChar);
}
}
}
return inputValue;
}
validateCharOnPostion(inputChar, position, mask) {
let regex;
let isValid;
const letterOrDigitRegEx = '[\\d\\u00C0-\\u1FFF\\u2C00-\\uD7FFa-zA-Z]';
const letterDigitOrSpaceRegEx = '[\\d\\u00C0-\\u1FFF\\u2C00-\\uD7FFa-zA-Z\\u0020]';
const letterRegEx = '[\\u00C0-\\u1FFF\\u2C00-\\uD7FFa-zA-Z]';
const letteSpaceRegEx = '[\\u00C0-\\u1FFF\\u2C00-\\uD7FFa-zA-Z\\u0020]';
const digitRegEx = '[\\d]';
const digitSpaceRegEx = '[\\d\\u0020]';
const digitSpecialRegEx = '[\\d-\\+]';
switch (mask.charAt(position)) {
case 'C':
isValid = inputChar !== '';
break;
case '&':
regex = new RegExp('[\\u0020]');
isValid = !regex.test(inputChar);
break;
case 'a':
regex = new RegExp(letterDigitOrSpaceRegEx);
isValid = regex.test(inputChar);
break;
case 'A':
regex = new RegExp(letterOrDigitRegEx);
isValid = regex.test(inputChar);
break;
case '?':
regex = new RegExp(letteSpaceRegEx);
isValid = regex.test(inputChar);
break;
case 'L':
regex = new RegExp(letterRegEx);
isValid = regex.test(inputChar);
break;
case '0':
regex = new RegExp(digitRegEx);
isValid = regex.test(inputChar);
break;
case '9':
regex = new RegExp(digitSpaceRegEx);
isValid = regex.test(inputChar);
break;
case '#':
regex = new RegExp(digitSpecialRegEx);
isValid = regex.test(inputChar);
break;
default: {
isValid = null;
}
}
return isValid;
}
replaceCharAt(strValue, index, char) {
if (strValue !== undefined) {
return strValue.substring(0, index) + char + strValue.substring(index + 1);
}
}
insertCharAt(strValue, index, char) {
if (strValue !== undefined) {
return strValue.substring(0, index) + char + strValue.substring(index);
}
}
getMaskLiterals(mask) {
const literals = new Map();
for (let i = 0; i < mask.length; i++) {
const char = mask.charAt(i);
if (MASK_FLAGS.indexOf(char) === -1) {
literals.set(i, char);
}
}
return literals;
}
getNonLiteralIndeces(mask, literalKeys) {
const nonLiteralsIndeces = new Array();
for (let i = 0; i < mask.length; i++) {
if (literalKeys.indexOf(i) === -1) {
nonLiteralsIndeces.push(i);
}
}
return nonLiteralsIndeces;
}
getNonLiteralValues(value, literalValues) {
const nonLiteralValues = new Array();
for (const val of value) {
if (literalValues.indexOf(val) === -1) {
nonLiteralValues.push(val);
}
}
return nonLiteralValues;
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFzay1oZWxwZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtdWktaGVyby9zcmMvbGliL2lucHV0LWZvcm1zL21hc2tpbmcvbWFzay1oZWxwZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFDSCxNQUFNLENBQUMsTUFBTSxVQUFVLEdBQUcsQ0FBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBRSxDQUFDO0FBRTFFOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sSUFBSSxHQUFHO0lBQ2hCLElBQUksRUFBRyxFQUFFO0lBQ1QsQ0FBQyxFQUFHLEVBQUU7SUFDTixDQUFDLEVBQUcsRUFBRTtJQUNOLENBQUMsRUFBRyxFQUFFO0lBQ04sU0FBUyxFQUFHLENBQUM7SUFDYixNQUFNLEVBQUcsRUFBRTtDQUNaLENBQUM7QUFHSjs7R0FFRztBQUNILE1BQU0sT0FBTyxVQUFVO0lBRW5CLElBQVcsTUFBTTtRQUNiLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQztJQUN4QixDQUFDO0lBR00sZ0JBQWdCLENBQUMsS0FBSyxFQUFFLFdBQVcsRUFBRSxNQUFNO1FBQzlDLElBQUksVUFBVSxHQUFXLEtBQUssQ0FBQztRQUMvQixNQUFNLElBQUksR0FBVyxXQUFXLENBQUMsTUFBTSxDQUFDO1FBQ3hDLE1BQU0sUUFBUSxHQUF3QixJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2pFLE1BQU0sV0FBVyxHQUFhLEtBQUssQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7UUFDMUQsTUFBTSxpQkFBaUIsR0FBYSxJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxFQUFFLFdBQVcsQ0FBQyxDQUFDO1FBRWpGLElBQUksVUFBVSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLEVBQUUsb0JBQW9CO1lBQ3ZELElBQUksVUFBVSxLQUFLLEVBQUUsSUFBSSxNQUFNLEtBQUssQ0FBQyxDQUFDLEVBQUU7Z0JBQ3BDLElBQUksQ0FBQyxPQUFPLEdBQUcsQ0FBQyxDQUFDO2dCQUNqQixPQUFPLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxLQUFLLEVBQUUsV0FBVyxDQUFDLENBQUM7YUFDMUQsQ0FBQywrQkFBK0I7WUFFakMsSUFBSSxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFO2dCQUM5QyxVQUFVLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxVQUFVLEVBQUUsTUFBTSxHQUFHLENBQUMsRUFBRSxXQUFXLENBQUMsVUFBVSxDQUFDLENBQUM7Z0JBQy9FLElBQUksQ0FBQyxPQUFPLEdBQUcsTUFBTSxHQUFHLENBQUMsQ0FBQzthQUM3QjtpQkFBTTtnQkFDSCxVQUFVLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxVQUFVLEVBQUUsTUFBTSxHQUFHLENBQUMsRUFBRSxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3pFLElBQUksQ0FBQyxPQUFPLEdBQUcsTUFBTSxHQUFHLENBQUMsQ0FBQztnQkFDMUIsS0FBSyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUU7b0JBQ25DLElBQUksV0FBVyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUU7d0JBQzFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztxQkFDbEI7eUJBQU07d0JBQ0gsTUFBTTtxQkFDVDtpQkFDSjthQUNKO1NBQ0o7YUFBTTtZQUNILE1BQU0sSUFBSSxHQUFHLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUNoQyxJQUFJLFdBQVcsR0FBRyxJQUFJLENBQUMscUJBQXFCLENBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQztZQUNqRSxJQUFJLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRTtnQkFDMUMsVUFBVSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsVUFBVSxFQUFFLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQztnQkFDeEQsSUFBSSxXQUFXLEVBQUU7b0JBQ2IsVUFBVSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsVUFBVSxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQztvQkFDMUQsSUFBSSxDQUFDLE9BQU8sR0FBRyxNQUFNLEdBQUcsQ0FBQyxDQUFDO2lCQUM3QjtxQkFBTTtvQkFDSCxJQUFJLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQztpQkFDekI7YUFDSjtpQkFBTTtnQkFDSCxVQUFVLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxVQUFVLEVBQUUsTUFBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDO2dCQUN4RCxJQUFJLENBQUMsT0FBTyxHQUFHLEVBQUUsTUFBTSxDQUFDO2dCQUN4QixLQUFLLElBQUksQ0FBQyxHQUFHLE1BQU0sRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtvQkFDdkMsSUFBSSxXQUFXLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRTt3QkFDMUMsSUFBSSxDQUFDLE9BQU8sR0FBRyxFQUFFLE1BQU0sQ0FBQztxQkFDM0I7eUJBQU07d0JBQ0gsV0FBVyxHQUFHLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDO3dCQUM3RCxJQUFJLFdBQVcsRUFBRTs0QkFDYixVQUFVLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxVQUFVLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDOzRCQUMxRCxJQUFJLENBQUMsT0FBTyxHQUFHLEVBQUUsTUFBTSxDQUFDOzRCQUN4QixNQUFNO3lCQUNUOzZCQUFNOzRCQUNILE1BQU07eUJBQ1Q7cUJBQ0o7aUJBQ0o7YUFDSjtTQUNKO1FBRUQsT0FBTyxVQUFVLENBQUM7SUFDdEIsQ0FBQztJQUVNLFNBQVMsQ0FBQyxXQUFXO1FBQ3hCLElBQUksU0FBUyxHQUFHLEVBQUUsQ0FBQztRQUNuQixNQUFNLElBQUksR0FBVyxXQUFXLENBQUMsTUFBTSxDQUFDO1FBQ3hDLE1BQU0sUUFBUSxHQUF3QixJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRWpFLEtBQUssTUFBTSxPQUFPLElBQUksSUFBSSxFQUFFO1lBQ3hCLFNBQVMsSUFBSSxXQUFXLENBQUMsVUFBVSxDQUFDO1NBQ3ZDO1FBRUQsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQVcsRUFBRSxHQUFXLEVBQUUsRUFBRTtZQUMxQyxTQUFTLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxTQUFTLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ3hELENBQUMsQ0FBQyxDQUFDO1FBRUgsT0FBTyxTQUFTLENBQUM7SUFDckIsQ0FBQztJQUVNLHNCQUFzQixDQUFDLFFBQVEsRUFBRSxXQUFXO1FBQy9DLElBQUksU0FBUyxHQUFHLEVBQUUsQ0FBQztRQUNuQixJQUFJLEtBQUssR0FBRyxFQUFFLENBQUM7UUFDZixNQUFNLElBQUksR0FBVyxXQUFXLENBQUMsTUFBTSxDQUFDO1FBQ3hDLE1BQU0sUUFBUSxHQUF3QixJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2pFLE1BQU0sV0FBVyxHQUFhLEtBQUssQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7UUFDMUQsTUFBTSxpQkFBaUIsR0FBYSxJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxFQUFFLFdBQVcsQ0FBQyxDQUFDO1FBQ2pGLE1BQU0sYUFBYSxHQUFhLEtBQUssQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFFOUQsSUFBSSxRQUFRLElBQUksSUFBSSxFQUFFO1lBQ2xCLEtBQUssR0FBRyxRQUFRLENBQUMsUUFBUSxFQUFFLENBQUM7U0FDL0I7UUFFRCxLQUFLLE1BQU0sT0FBTyxJQUFJLElBQUksRUFBRTtZQUN4QixTQUFTLElBQUksV0FBVyxDQUFDLFVBQVUsQ0FBQztTQUN2QztRQUVELFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxHQUFXLEVBQUUsR0FBVyxFQUFFLEVBQUU7WUFDMUMsU0FBUyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsU0FBUyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUN4RCxDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxLQUFLLEVBQUU7WUFDUixPQUFPLFNBQVMsQ0FBQztTQUNwQjtRQUVELE1BQU0sZ0JBQWdCLEdBQWEsSUFBSSxDQUFDLG1CQUFtQixDQUFDLEtBQUssRUFBRSxhQUFhLENBQUMsQ0FBQztRQUVsRixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsZ0JBQWdCLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQzlDLE1BQU0sSUFBSSxHQUFHLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2pDLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLEVBQUUsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFFakYsSUFBSSxDQUFDLFdBQVcsSUFBSSxJQUFJLEtBQUssV0FBVyxDQUFDLFVBQVUsRUFBRTtnQkFDakQsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLEdBQUcsV0FBVyxDQUFDLFVBQVUsQ0FBQzthQUNoRDtTQUNKO1FBRUQsSUFBSSxnQkFBZ0IsQ0FBQyxNQUFNLEdBQUcsaUJBQWlCLENBQUMsTUFBTSxFQUFFO1lBQ3BELGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsQ0FBQztTQUNyRDtRQUVELElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQztRQUNaLEtBQUssTUFBTSxlQUFlLElBQUksZ0JBQWdCLEVBQUU7WUFDNUMsTUFBTSxJQUFJLEdBQUcsZUFBZSxDQUFDO1lBQzdCLFNBQVMsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLFNBQVMsRUFBRSxpQkFBaUIsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO1NBQzdFO1FBRUQsT0FBTyxTQUFTLENBQUM7SUFDckIsQ0FBQztJQUVNLG9CQUFvQixDQUFDLEtBQUssRUFBRSxXQUFXO1FBQzFDLElBQUksU0FBUyxHQUFHLEVBQUUsQ0FBQztRQUNuQixNQUFNLElBQUksR0FBVyxXQUFXLENBQUMsTUFBTSxDQUFDO1FBQ3hDLE1BQU0sUUFBUSxHQUF3QixJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2pFLE1BQU0sYUFBYSxHQUFhLEtBQUssQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFFOUQsS0FBSyxNQUFNLEdBQUcsSUFBSSxLQUFLLEVBQUU7WUFDckIsSUFBSSxhQUFhLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFO2dCQUNuQyxJQUFJLEdBQUcsS0FBSyxXQUFXLENBQUMsVUFBVSxFQUFFO29CQUNoQyxTQUFTLElBQUksR0FBRyxDQUFDO2lCQUNwQjthQUNKO1NBQ0o7UUFFRCxPQUFPLFNBQVMsQ0FBQztJQUNyQixDQUFDO0lBRU0sNkJBQTZCLENBQUMsS0FBSyxFQUFFLFdBQVcsRUFBRSxNQUFNLEVBQUUsU0FBUztRQUN0RSxJQUFJLFdBQW9CLENBQUM7UUFDekIsSUFBSSxVQUFVLEdBQVcsS0FBSyxDQUFDO1FBQy9CLE1BQU0sSUFBSSxHQUFXLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN4QyxNQUFNLElBQUksR0FBVyxXQUFXLENBQUMsTUFBTSxDQUFDO1FBQ3hDLE1BQU0sUUFBUSxHQUF3QixJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2pFLE1BQU0sV0FBVyxHQUFhLEtBQUssQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7UUFDMUQsTUFBTSxpQkFBaUIsR0FBYSxJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxFQUFFLFdBQVcsQ0FBQyxDQUFDO1FBRWpGLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFO1lBQ1osSUFBSSxDQUFDLE9BQU8sR0FBRyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDO1lBQzlDLElBQUksaUJBQWlCLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRTtnQkFDaEQsV0FBVyxHQUFHLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsQ0FBQztnQkFDbkUsVUFBVSxHQUFHLFdBQVcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLE9BQU8sRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7b0JBQzdFLFVBQVUsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFLEVBQUUsV0FBVyxDQUFDLFVBQVUsQ0FBQyxDQUFDO2dCQUN4RixTQUFTLEVBQUUsQ0FBQztnQkFDWixJQUFJLFNBQVMsR0FBRyxDQUFDLEVBQUU7b0JBQ2YsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFNBQVMsRUFBRSxDQUFDLEVBQUUsRUFBRTt3QkFDaEMsTUFBTSxFQUFFLENBQUM7d0JBQ1QsVUFBVSxHQUFHLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDOzRCQUNuRCxJQUFJLENBQUMsWUFBWSxDQUFDLFVBQVUsRUFBRSxNQUFNLEVBQUUsV0FBVyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7NEJBQy9ELElBQUksQ0FBQyxZQUFZLENBQUMsVUFBVSxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztxQkFDM0Q7aUJBQ0o7YUFDSjtpQkFBTTtnQkFDSCxVQUFVLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7Z0JBQzlFLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztnQkFDZixTQUFTLEVBQUUsQ0FBQztnQkFDWixJQUFJLFFBQVEsR0FBRyxLQUFLLENBQUM7Z0JBQ3JCLElBQUksU0FBUyxHQUFHLENBQUMsRUFBRTtvQkFDZixNQUFNLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQztvQkFDdEIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFNBQVMsRUFBRSxDQUFDLEVBQUUsRUFBRTt3QkFDaEMsSUFBSSxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUU7NEJBQzFDLFdBQVcsR0FBRyxJQUFJLENBQUMscUJBQXFCLENBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQzs0QkFDN0QsSUFBSSxXQUFXLElBQUksQ0FBQyxRQUFRLEVBQUU7Z0NBQzFCLFVBQVUsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLFVBQVUsRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0NBQ3pELE1BQU0sRUFBRSxDQUFDO2dDQUNULElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztnQ0FDZixRQUFRLEdBQUcsSUFBSSxDQUFDOzZCQUNuQjtpQ0FBTTtnQ0FDSCxVQUFVLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxVQUFVLEVBQUUsTUFBTSxFQUFFLFdBQVcsQ0FBQyxVQUFVLENBQUMsQ0FBQztnQ0FDM0UsTUFBTSxFQUFFLENBQUM7NkJBQ1o7eUJBQ0o7NkJBQU07NEJBQ0gsVUFBVSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsVUFBVSxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQzs0QkFDakUsSUFBSSxNQUFNLEtBQUssSUFBSSxDQUFDLE9BQU8sRUFBRTtnQ0FDekIsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDOzZCQUNsQjs0QkFDRCxNQUFNLEVBQUUsQ0FBQzt5QkFDWjtxQkFDSjtpQkFDSjthQUNKO1NBQ0o7YUFBTTtZQUNILElBQUksVUFBVSxLQUFLLEVBQUUsSUFBSSxNQUFNLEtBQUssQ0FBQyxDQUFDLEVBQUU7Z0JBQ3BDLElBQUksQ0FBQyxPQUFPLEdBQUcsQ0FBQyxDQUFDO2dCQUNqQixPQUFPLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxLQUFLLEVBQUUsV0FBVyxDQUFDLENBQUM7YUFDMUQsQ0FBQywrQkFBK0I7WUFFakMsSUFBSSxJQUFJLENBQUMsT0FBTyxHQUFHLENBQUMsRUFBRTtnQkFDbEIsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUNmLE1BQU0sRUFBRSxDQUFDO2FBQ1o7WUFDRCxNQUFNLEVBQUUsQ0FBQztZQUNULElBQUksQ0FBQyxPQUFPLEdBQUcsTUFBTSxDQUFDO1lBQ3RCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxTQUFTLEVBQUUsQ0FBQyxFQUFFLEVBQUU7Z0JBQ2hDLElBQUksaUJBQWlCLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFO29CQUMxQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxVQUFVLEVBQUUsTUFBTSxFQUFFLFdBQVcsQ0FBQyxVQUFVLENBQUMsQ0FBQztvQkFDM0UsTUFBTSxFQUFFLENBQUM7aUJBQ1o7cUJBQU07b0JBQ0gsVUFBVSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsVUFBVSxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztvQkFDakUsTUFBTSxFQUFFLENBQUM7aUJBQ1o7YUFDSjtTQUNKO1FBRUQsT0FBTyxVQUFVLENBQUM7SUFDdEIsQ0FBQztJQUVNLDZCQUE2QixDQUFDLEtBQUssRUFBRSxXQUFXLEVBQUUsTUFBTSxFQUFFLGFBQWEsRUFBRSxTQUFTO1FBQ3JGLElBQUksVUFBVSxHQUFXLEtBQUssQ0FBQztRQUMvQixNQUFNLElBQUksR0FBVyxXQUFXLENBQUMsTUFBTSxDQUFDO1FBQ3hDLE1BQU0sUUFBUSxHQUF3QixJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2pFLE1BQU0sV0FBVyxHQUFhLEtBQUssQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7UUFDMUQsTUFBTSxpQkFBaUIsR0FBYSxJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxFQUFFLFdBQVcsQ0FBQyxDQUFDO1FBRWpGLE1BQU0sWUFBWSxHQUFHLE1BQU0sR0FBRyxTQUFTLENBQUM7UUFFeEMsSUFBSSxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUM7UUFDdEIsS0FBSyxNQUFNLFlBQVksSUFBSSxhQUFhLEVBQUU7WUFDdEMsTUFBTSxJQUFJLEdBQUcsWUFBWSxDQUFDO1lBRTFCLElBQUksSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFO2dCQUM1QixPQUFPLFVBQVUsQ0FBQzthQUNyQjtZQUVELElBQUksaUJBQWlCLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRTtnQkFDaEQsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLHFCQUFxQixDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDO2dCQUN6RSxJQUFJLFdBQVcsRUFBRTtvQkFDYixVQUFVLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLE9BQU8sRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDO2lCQUNyRTthQUNKO2lCQUFNO2dCQUNILEtBQUssSUFBSSxDQUFDLEdBQUcsTUFBTSxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO29CQUN2QyxJQUFJLFdBQVcsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFO3dCQUMxQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7cUJBQ2xCO3lCQUFNO3dCQUNILE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsQ0FBQzt3QkFDekUsSUFBSSxXQUFXLEVBQUU7NEJBQ2IsVUFBVSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxPQUFPLEVBQUUsRUFBRSxJQUFJLENBQUMsQ0FBQzt5QkFDckU7d0JBQ0QsTUFBTTtxQkFDVDtpQkFDSjthQUNKO1lBRUQsU0FBUyxFQUFFLENBQUM7U0FDZjtRQUVELElBQUksU0FBUyxHQUFHLENBQUMsRUFBRTtZQUNmLEtBQUssSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLEdBQUcsWUFBWSxFQUFFLENBQUMsRUFBRSxFQUFFO2dCQUM5QyxJQUFJLFdBQVcsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFO29CQUMxQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7aUJBQ2xCO3FCQUFNO29CQUNILFVBQVUsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFLEVBQUUsV0FBVyxDQUFDLFVBQVUsQ0FBQyxDQUFDO2lCQUN2RjthQUNKO1NBQ0o7UUFFRCxPQUFPLFVBQVUsQ0FBQztJQUN0QixDQUFDO0lBRU8scUJBQXFCLENBQUMsU0FBaUIsRUFBRSxRQUFnQixFQUFFLElBQVk7UUFDM0UsSUFBSSxLQUFhLENBQUM7UUFDbEIsSUFBSSxPQUFnQixDQUFDO1FBQ3JCLE1BQU0sa0JBQWtCLEdBQUcsMkNBQTJDLENBQUM7UUFDdkUsTUFBTSx1QkFBdUIsR0FBRyxrREFBa0QsQ0FBQztRQUNuRixNQUFNLFdBQVcsR0FBRyx3Q0FBd0MsQ0FBQztRQUM3RCxNQUFNLGVBQWUsR0FBRywrQ0FBK0MsQ0FBQztRQUN4RSxNQUFNLFVBQVUsR0FBRyxPQUFPLENBQUM7UUFDM0IsTUFBTSxlQUFlLEdBQUcsY0FBYyxDQUFDO1FBQ3ZDLE1BQU0saUJBQWlCLEdBQUcsV0FBVyxDQUFDO1FBRXRDLFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsRUFBRTtZQUMzQixLQUFLLEdBQUc7Z0JBQ0osT0FBTyxHQUFHLFNBQVMsS0FBSyxFQUFFLENBQUM7Z0JBQzNCLE1BQU07WUFDVixLQUFLLEdBQUc7Z0JBQ0osS0FBSyxHQUFHLElBQUksTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDO2dCQUNoQyxPQUFPLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO2dCQUNqQyxNQUFNO1lBQ1YsS0FBSyxHQUFHO2dCQUNKLEtBQUssR0FBRyxJQUFJLE1BQU0sQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO2dCQUM1QyxPQUFPLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztnQkFDaEMsTUFBTTtZQUNWLEtBQUssR0FBRztnQkFDSixLQUFLLEdBQUcsSUFBSSxNQUFNLENBQUMsa0JBQWtCLENBQUMsQ0FBQztnQkFDdkMsT0FBTyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7Z0JBQ2hDLE1BQU07WUFDVixLQUFLLEdBQUc7Z0JBQ0osS0FBSyxHQUFHLElBQUksTUFBTSxDQUFDLGVBQWUsQ0FBQyxDQUFDO2dCQUNwQyxPQUFPLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztnQkFDaEMsTUFBTTtZQUNWLEtBQUssR0FBRztnQkFDSixLQUFLLEdBQUcsSUFBSSxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7Z0JBQ2hDLE9BQU8sR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO2dCQUNoQyxNQUFNO1lBQ1YsS0FBSyxHQUFHO2dCQUNKLEtBQUssR0FBRyxJQUFJLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztnQkFDL0IsT0FBTyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7Z0JBQ2hDLE1BQU07WUFDVixLQUFLLEdBQUc7Z0JBQ0osS0FBSyxHQUFHLElBQUksTUFBTSxDQUFDLGVBQWUsQ0FBQyxDQUFDO2dCQUNwQyxPQUFPLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztnQkFDaEMsTUFBTTtZQUNWLEtBQUssR0FBRztnQkFDSixLQUFLLEdBQUcsSUFBSSxNQUFNLENBQUMsaUJBQWlCLENBQUMsQ0FBQztnQkFDdEMsT0FBTyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7Z0JBQ2hDLE1BQU07WUFDVixPQUFPLENBQUMsQ0FBQztnQkFDTCxPQUFPLEdBQUcsSUFBSSxDQUFDO2FBQ2xCO1NBQ0o7UUFFRCxPQUFPLE9BQU8sQ0FBQztJQUNuQixDQUFDO0lBQ08sYUFBYSxDQUFDLFFBQWdCLEVBQUUsS0FBYSxFQUFFLElBQVk7UUFDL0QsSUFBSSxRQUFRLEtBQUssU0FBUyxFQUFFO1lBQ3hCLE9BQU8sUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLEdBQUcsSUFBSSxHQUFHLFFBQVEsQ0FBQyxTQUFTLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDO1NBQzlFO0lBQ0wsQ0FBQztJQUNPLFlBQVksQ0FBQyxRQUFnQixFQUFFLEtBQWEsRUFBRSxJQUFZO1FBQzlELElBQUksUUFBUSxLQUFLLFNBQVMsRUFBRTtZQUN4QixPQUFPLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxHQUFHLElBQUksR0FBRyxRQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1NBQzFFO0lBQ0wsQ0FBQztJQUNPLGVBQWUsQ0FBQyxJQUFZO1FBQ2hDLE1BQU0sUUFBUSxHQUFHLElBQUksR0FBRyxFQUFrQixDQUFDO1FBRTNDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQ2xDLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDNUIsSUFBSSxVQUFVLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFO2dCQUNqQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQzthQUN6QjtTQUNKO1FBRUQsT0FBTyxRQUFRLENBQUM7SUFDcEIsQ0FBQztJQUNPLG9CQUFvQixDQUFDLElBQVksRUFBRSxXQUFxQjtRQUM1RCxNQUFNLGtCQUFrQixHQUFhLElBQUksS0FBSyxFQUFFLENBQUM7UUFFakQsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDbEMsSUFBSSxXQUFXLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFO2dCQUMvQixrQkFBa0IsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDOUI7U0FDSjtRQUVELE9BQU8sa0JBQWtCLENBQUM7SUFDOUIsQ0FBQztJQUNPLG1CQUFtQixDQUFDLEtBQWEsRUFBRSxhQUF1QjtRQUM5RCxNQUFNLGdCQUFnQixHQUFhLElBQUksS0FBSyxFQUFFLENBQUM7UUFFL0MsS0FBSyxNQUFNLEdBQUcsSUFBSSxLQUFLLEVBQUU7WUFDckIsSUFBSSxhQUFhLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFO2dCQUNuQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7YUFDOUI7U0FDSjtRQUVELE9BQU8sZ0JBQWdCLENBQUM7SUFDNUIsQ0FBQztDQUNKIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAaGlkZGVuXG4gKi9cbmV4cG9ydCBjb25zdCBNQVNLX0ZMQUdTID0gWyAnQycsICcmJywgJ2EnLCAnQScsICc/JywgJ0wnLCAnOScsICcwJywgJyMnIF07XG5cbi8qKlxuICogQGhpZGRlblxuICovXG5leHBvcnQgY29uc3QgS0VZUyA9IHtcbiAgICBDdHJsIDogMTcsXG4gICAgWiA6IDkwLFxuICAgIFkgOiA4OSxcbiAgICBYIDogODgsXG4gICAgQkFDS1NQQUNFIDogOCxcbiAgICBERUxFVEUgOiA0NlxuICB9O1xuXG5cbi8qKlxuICogQGhpZGRlblxuICovXG5leHBvcnQgY2xhc3MgTWFza0hlbHBlciB7XG4gICAgcHJpdmF0ZSBfY3Vyc29yO1xuICAgIHB1YmxpYyBnZXQgY3Vyc29yKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY3Vyc29yO1xuICAgIH1cbiAgICBwdWJsaWMgZGF0YTogYm9vbGVhbjtcblxuICAgIHB1YmxpYyBwYXJzZVZhbHVlQnlNYXNrKHZhbHVlLCBtYXNrT3B0aW9ucywgY3Vyc29yKTogc3RyaW5nIHtcbiAgICAgICAgbGV0IGlucHV0VmFsdWU6IHN0cmluZyA9IHZhbHVlO1xuICAgICAgICBjb25zdCBtYXNrOiBzdHJpbmcgPSBtYXNrT3B0aW9ucy5mb3JtYXQ7XG4gICAgICAgIGNvbnN0IGxpdGVyYWxzOiBNYXA8bnVtYmVyLCBzdHJpbmc+ID0gdGhpcy5nZXRNYXNrTGl0ZXJhbHMobWFzayk7XG4gICAgICAgIGNvbnN0IGxpdGVyYWxLZXlzOiBudW1iZXJbXSA9IEFycmF5LmZyb20obGl0ZXJhbHMua2V5cygpKTtcbiAgICAgICAgY29uc3Qgbm9uTGl0ZXJhbEluZGVjZXM6IG51bWJlcltdID0gdGhpcy5nZXROb25MaXRlcmFsSW5kZWNlcyhtYXNrLCBsaXRlcmFsS2V5cyk7XG5cbiAgICAgICAgaWYgKGlucHV0VmFsdWUubGVuZ3RoIDwgbWFzay5sZW5ndGgpIHsgLy8gQkFDS1NQQUNFLCBERUxFVEVcbiAgICAgICAgICAgIGlmIChpbnB1dFZhbHVlID09PSAnJyAmJiBjdXJzb3IgPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fY3Vyc29yID0gMDtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5wYXJzZVZhbHVlQnlNYXNrT25Jbml0KHZhbHVlLCBtYXNrT3B0aW9ucyk7XG4gICAgICAgICAgICB9IC8vIHdvcmthcm91bmQgZm9yIElFICd4JyBidXR0b25cblxuICAgICAgICAgICAgaWYgKG5vbkxpdGVyYWxJbmRlY2VzLmluZGV4T2YoY3Vyc29yICsgMSkgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgaW5wdXRWYWx1ZSA9IHRoaXMuaW5zZXJ0Q2hhckF0KGlucHV0VmFsdWUsIGN1cnNvciArIDEsIG1hc2tPcHRpb25zLnByb21wdENoYXIpO1xuICAgICAgICAgICAgICAgIHRoaXMuX2N1cnNvciA9IGN1cnNvciArIDE7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlucHV0VmFsdWUgPSB0aGlzLmluc2VydENoYXJBdChpbnB1dFZhbHVlLCBjdXJzb3IgKyAxLCBtYXNrW2N1cnNvciArIDFdKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9jdXJzb3IgPSBjdXJzb3IgKyAxO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSB0aGlzLl9jdXJzb3I7IGkgPCAwOyBpLS0pIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGxpdGVyYWxLZXlzLmluZGV4T2YodGhpcy5fY3Vyc29yKSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2N1cnNvci0tO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBjaGFyID0gaW5wdXRWYWx1ZVtjdXJzb3JdO1xuICAgICAgICAgICAgbGV0IGlzQ2hhclZhbGlkID0gdGhpcy52YWxpZGF0ZUNoYXJPblBvc3Rpb24oY2hhciwgY3Vyc29yLCBtYXNrKTtcbiAgICAgICAgICAgIGlmIChub25MaXRlcmFsSW5kZWNlcy5pbmRleE9mKGN1cnNvcikgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgaW5wdXRWYWx1ZSA9IHRoaXMucmVwbGFjZUNoYXJBdChpbnB1dFZhbHVlLCBjdXJzb3IsICcnKTtcbiAgICAgICAgICAgICAgICBpZiAoaXNDaGFyVmFsaWQpIHtcbiAgICAgICAgICAgICAgICAgICAgaW5wdXRWYWx1ZSA9IHRoaXMucmVwbGFjZUNoYXJBdChpbnB1dFZhbHVlLCBjdXJzb3IsIGNoYXIpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9jdXJzb3IgPSBjdXJzb3IgKyAxO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2N1cnNvciA9IGN1cnNvcjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlucHV0VmFsdWUgPSB0aGlzLnJlcGxhY2VDaGFyQXQoaW5wdXRWYWx1ZSwgY3Vyc29yLCAnJyk7XG4gICAgICAgICAgICAgICAgdGhpcy5fY3Vyc29yID0gKytjdXJzb3I7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IGN1cnNvcjsgaSA8IG1hc2subGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGxpdGVyYWxLZXlzLmluZGV4T2YodGhpcy5fY3Vyc29yKSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2N1cnNvciA9ICsrY3Vyc29yO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgaXNDaGFyVmFsaWQgPSB0aGlzLnZhbGlkYXRlQ2hhck9uUG9zdGlvbihjaGFyLCBjdXJzb3IsIG1hc2spO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzQ2hhclZhbGlkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXRWYWx1ZSA9IHRoaXMucmVwbGFjZUNoYXJBdChpbnB1dFZhbHVlLCBjdXJzb3IsIGNoYXIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2N1cnNvciA9ICsrY3Vyc29yO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBpbnB1dFZhbHVlO1xuICAgIH1cblxuICAgIHB1YmxpYyBwYXJzZU1hc2sobWFza09wdGlvbnMpOiBzdHJpbmcge1xuICAgICAgICBsZXQgb3V0cHV0VmFsID0gJyc7XG4gICAgICAgIGNvbnN0IG1hc2s6IHN0cmluZyA9IG1hc2tPcHRpb25zLmZvcm1hdDtcbiAgICAgICAgY29uc3QgbGl0ZXJhbHM6IE1hcDxudW1iZXIsIHN0cmluZz4gPSB0aGlzLmdldE1hc2tMaXRlcmFscyhtYXNrKTtcblxuICAgICAgICBmb3IgKGNvbnN0IG1hc2tTeW0gb2YgbWFzaykge1xuICAgICAgICAgICAgb3V0cHV0VmFsICs9IG1hc2tPcHRpb25zLnByb21wdENoYXI7XG4gICAgICAgIH1cblxuICAgICAgICBsaXRlcmFscy5mb3JFYWNoKCh2YWw6IHN0cmluZywga2V5OiBudW1iZXIpID0+IHtcbiAgICAgICAgICAgIG91dHB1dFZhbCA9IHRoaXMucmVwbGFjZUNoYXJBdChvdXRwdXRWYWwsIGtleSwgdmFsKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIG91dHB1dFZhbDtcbiAgICB9XG5cbiAgICBwdWJsaWMgcGFyc2VWYWx1ZUJ5TWFza09uSW5pdChpbnB1dFZhbCwgbWFza09wdGlvbnMpOiBzdHJpbmcge1xuICAgICAgICBsZXQgb3V0cHV0VmFsID0gJyc7XG4gICAgICAgIGxldCB2YWx1ZSA9ICcnO1xuICAgICAgICBjb25zdCBtYXNrOiBzdHJpbmcgPSBtYXNrT3B0aW9ucy5mb3JtYXQ7XG4gICAgICAgIGNvbnN0IGxpdGVyYWxzOiBNYXA8bnVtYmVyLCBzdHJpbmc+ID0gdGhpcy5nZXRNYXNrTGl0ZXJhbHMobWFzayk7XG4gICAgICAgIGNvbnN0IGxpdGVyYWxLZXlzOiBudW1iZXJbXSA9IEFycmF5LmZyb20obGl0ZXJhbHMua2V5cygpKTtcbiAgICAgICAgY29uc3Qgbm9uTGl0ZXJhbEluZGVjZXM6IG51bWJlcltdID0gdGhpcy5nZXROb25MaXRlcmFsSW5kZWNlcyhtYXNrLCBsaXRlcmFsS2V5cyk7XG4gICAgICAgIGNvbnN0IGxpdGVyYWxWYWx1ZXM6IHN0cmluZ1tdID0gQXJyYXkuZnJvbShsaXRlcmFscy52YWx1ZXMoKSk7XG5cbiAgICAgICAgaWYgKGlucHV0VmFsICE9IG51bGwpIHtcbiAgICAgICAgICAgIHZhbHVlID0gaW5wdXRWYWwudG9TdHJpbmcoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAoY29uc3QgbWFza1N5bSBvZiBtYXNrKSB7XG4gICAgICAgICAgICBvdXRwdXRWYWwgKz0gbWFza09wdGlvbnMucHJvbXB0Q2hhcjtcbiAgICAgICAgfVxuXG4gICAgICAgIGxpdGVyYWxzLmZvckVhY2goKHZhbDogc3RyaW5nLCBrZXk6IG51bWJlcikgPT4ge1xuICAgICAgICAgICAgb3V0cHV0VmFsID0gdGhpcy5yZXBsYWNlQ2hhckF0KG91dHB1dFZhbCwga2V5LCB2YWwpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpZiAoIXZhbHVlKSB7XG4gICAgICAgICAgICByZXR1cm4gb3V0cHV0VmFsO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgbm9uTGl0ZXJhbFZhbHVlczogc3RyaW5nW10gPSB0aGlzLmdldE5vbkxpdGVyYWxWYWx1ZXModmFsdWUsIGxpdGVyYWxWYWx1ZXMpO1xuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbm9uTGl0ZXJhbFZhbHVlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgY29uc3QgY2hhciA9IG5vbkxpdGVyYWxWYWx1ZXNbaV07XG4gICAgICAgICAgICBjb25zdCBpc0NoYXJWYWxpZCA9IHRoaXMudmFsaWRhdGVDaGFyT25Qb3N0aW9uKGNoYXIsIG5vbkxpdGVyYWxJbmRlY2VzW2ldLCBtYXNrKTtcblxuICAgICAgICAgICAgaWYgKCFpc0NoYXJWYWxpZCAmJiBjaGFyICE9PSBtYXNrT3B0aW9ucy5wcm9tcHRDaGFyKSB7XG4gICAgICAgICAgICAgICAgbm9uTGl0ZXJhbFZhbHVlc1tpXSA9IG1hc2tPcHRpb25zLnByb21wdENoYXI7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobm9uTGl0ZXJhbFZhbHVlcy5sZW5ndGggPiBub25MaXRlcmFsSW5kZWNlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIG5vbkxpdGVyYWxWYWx1ZXMuc3BsaWNlKG5vbkxpdGVyYWxJbmRlY2VzLmxlbmd0aCk7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgcG9zID0gMDtcbiAgICAgICAgZm9yIChjb25zdCBub25MaXRlcmFsVmFsdWUgb2Ygbm9uTGl0ZXJhbFZhbHVlcykge1xuICAgICAgICAgICAgY29uc3QgY2hhciA9IG5vbkxpdGVyYWxWYWx1ZTtcbiAgICAgICAgICAgIG91dHB1dFZhbCA9IHRoaXMucmVwbGFjZUNoYXJBdChvdXRwdXRWYWwsIG5vbkxpdGVyYWxJbmRlY2VzW3BvcysrXSwgY2hhcik7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gb3V0cHV0VmFsO1xuICAgIH1cblxuICAgIHB1YmxpYyByZXN0b3JlVmFsdWVGcm9tTWFzayh2YWx1ZSwgbWFza09wdGlvbnMpOiBzdHJpbmcge1xuICAgICAgICBsZXQgb3V0cHV0VmFsID0gJyc7XG4gICAgICAgIGNvbnN0IG1hc2s6IHN0cmluZyA9IG1hc2tPcHRpb25zLmZvcm1hdDtcbiAgICAgICAgY29uc3QgbGl0ZXJhbHM6IE1hcDxudW1iZXIsIHN0cmluZz4gPSB0aGlzLmdldE1hc2tMaXRlcmFscyhtYXNrKTtcbiAgICAgICAgY29uc3QgbGl0ZXJhbFZhbHVlczogc3RyaW5nW10gPSBBcnJheS5mcm9tKGxpdGVyYWxzLnZhbHVlcygpKTtcblxuICAgICAgICBmb3IgKGNvbnN0IHZhbCBvZiB2YWx1ZSkge1xuICAgICAgICAgICAgaWYgKGxpdGVyYWxWYWx1ZXMuaW5kZXhPZih2YWwpID09PSAtMSkge1xuICAgICAgICAgICAgICAgIGlmICh2YWwgIT09IG1hc2tPcHRpb25zLnByb21wdENoYXIpIHtcbiAgICAgICAgICAgICAgICAgICAgb3V0cHV0VmFsICs9IHZhbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gb3V0cHV0VmFsO1xuICAgIH1cblxuICAgIHB1YmxpYyBwYXJzZVZhbHVlQnlNYXNrVXBvblNlbGVjdGlvbih2YWx1ZSwgbWFza09wdGlvbnMsIGN1cnNvciwgc2VsZWN0aW9uKTogc3RyaW5nIHtcbiAgICAgICAgbGV0IGlzQ2hhclZhbGlkOiBib29sZWFuO1xuICAgICAgICBsZXQgaW5wdXRWYWx1ZTogc3RyaW5nID0gdmFsdWU7XG4gICAgICAgIGNvbnN0IGNoYXI6IHN0cmluZyA9IGlucHV0VmFsdWVbY3Vyc29yXTtcbiAgICAgICAgY29uc3QgbWFzazogc3RyaW5nID0gbWFza09wdGlvbnMuZm9ybWF0O1xuICAgICAgICBjb25zdCBsaXRlcmFsczogTWFwPG51bWJlciwgc3RyaW5nPiA9IHRoaXMuZ2V0TWFza0xpdGVyYWxzKG1hc2spO1xuICAgICAgICBjb25zdCBsaXRlcmFsS2V5czogbnVtYmVyW10gPSBBcnJheS5mcm9tKGxpdGVyYWxzLmtleXMoKSk7XG4gICAgICAgIGNvbnN0IG5vbkxpdGVyYWxJbmRlY2VzOiBudW1iZXJbXSA9IHRoaXMuZ2V0Tm9uTGl0ZXJhbEluZGVjZXMobWFzaywgbGl0ZXJhbEtleXMpO1xuXG4gICAgICAgIGlmICghdGhpcy5kYXRhKSB7XG4gICAgICAgICAgICB0aGlzLl9jdXJzb3IgPSBjdXJzb3IgPCAwID8gKytjdXJzb3IgOiBjdXJzb3I7XG4gICAgICAgICAgICBpZiAobm9uTGl0ZXJhbEluZGVjZXMuaW5kZXhPZih0aGlzLl9jdXJzb3IpICE9PSAtMSkge1xuICAgICAgICAgICAgICAgIGlzQ2hhclZhbGlkID0gdGhpcy52YWxpZGF0ZUNoYXJPblBvc3Rpb24oY2hhciwgdGhpcy5fY3Vyc29yLCBtYXNrKTtcbiAgICAgICAgICAgICAgICBpbnB1dFZhbHVlID0gaXNDaGFyVmFsaWQgPyB0aGlzLnJlcGxhY2VDaGFyQXQoaW5wdXRWYWx1ZSwgdGhpcy5fY3Vyc29yKyssIGNoYXIpIDpcbiAgICAgICAgICAgICAgICAgICAgaW5wdXRWYWx1ZSA9IHRoaXMucmVwbGFjZUNoYXJBdChpbnB1dFZhbHVlLCB0aGlzLl9jdXJzb3IrKywgbWFza09wdGlvbnMucHJvbXB0Q2hhcik7XG4gICAgICAgICAgICAgICAgc2VsZWN0aW9uLS07XG4gICAgICAgICAgICAgICAgaWYgKHNlbGVjdGlvbiA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWxlY3Rpb247IGkrKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY3Vyc29yKys7XG4gICAgICAgICAgICAgICAgICAgICAgICBpbnB1dFZhbHVlID0gbm9uTGl0ZXJhbEluZGVjZXMuaW5kZXhPZihjdXJzb3IpICE9PSAtMSA/XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnNlcnRDaGFyQXQoaW5wdXRWYWx1ZSwgY3Vyc29yLCBtYXNrT3B0aW9ucy5wcm9tcHRDaGFyKSA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnNlcnRDaGFyQXQoaW5wdXRWYWx1ZSwgY3Vyc29yLCBtYXNrW2N1cnNvcl0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpbnB1dFZhbHVlID0gdGhpcy5yZXBsYWNlQ2hhckF0KGlucHV0VmFsdWUsIHRoaXMuX2N1cnNvciwgbWFza1t0aGlzLl9jdXJzb3JdKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9jdXJzb3IrKztcbiAgICAgICAgICAgICAgICBzZWxlY3Rpb24tLTtcbiAgICAgICAgICAgICAgICBsZXQgaXNNYXJrZWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBpZiAoc2VsZWN0aW9uID4gMCkge1xuICAgICAgICAgICAgICAgICAgICBjdXJzb3IgPSB0aGlzLl9jdXJzb3I7XG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2VsZWN0aW9uOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChub25MaXRlcmFsSW5kZWNlcy5pbmRleE9mKGN1cnNvcikgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNDaGFyVmFsaWQgPSB0aGlzLnZhbGlkYXRlQ2hhck9uUG9zdGlvbihjaGFyLCBjdXJzb3IsIG1hc2spO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc0NoYXJWYWxpZCAmJiAhaXNNYXJrZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXRWYWx1ZSA9IHRoaXMuaW5zZXJ0Q2hhckF0KGlucHV0VmFsdWUsIGN1cnNvciwgY2hhcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnNvcisrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9jdXJzb3IrKztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNNYXJrZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0VmFsdWUgPSB0aGlzLmluc2VydENoYXJBdChpbnB1dFZhbHVlLCBjdXJzb3IsIG1hc2tPcHRpb25zLnByb21wdENoYXIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJzb3IrKztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0VmFsdWUgPSB0aGlzLmluc2VydENoYXJBdChpbnB1dFZhbHVlLCBjdXJzb3IsIG1hc2tbY3Vyc29yXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnNvciA9PT0gdGhpcy5fY3Vyc29yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2N1cnNvcisrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJzb3IrKztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmIChpbnB1dFZhbHVlID09PSAnJyAmJiBjdXJzb3IgPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fY3Vyc29yID0gMDtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5wYXJzZVZhbHVlQnlNYXNrT25Jbml0KHZhbHVlLCBtYXNrT3B0aW9ucyk7XG4gICAgICAgICAgICB9IC8vIHdvcmthcm91bmQgZm9yIElFICd4JyBidXR0b25cblxuICAgICAgICAgICAgaWYgKHRoaXMuX2N1cnNvciA8IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9jdXJzb3IrKztcbiAgICAgICAgICAgICAgICBjdXJzb3IrKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGN1cnNvcisrO1xuICAgICAgICAgICAgdGhpcy5fY3Vyc29yID0gY3Vyc29yO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWxlY3Rpb247IGkrKykge1xuICAgICAgICAgICAgICAgIGlmIChub25MaXRlcmFsSW5kZWNlcy5pbmRleE9mKGN1cnNvcikgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIGlucHV0VmFsdWUgPSB0aGlzLmluc2VydENoYXJBdChpbnB1dFZhbHVlLCBjdXJzb3IsIG1hc2tPcHRpb25zLnByb21wdENoYXIpO1xuICAgICAgICAgICAgICAgICAgICBjdXJzb3IrKztcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBpbnB1dFZhbHVlID0gdGhpcy5pbnNlcnRDaGFyQXQoaW5wdXRWYWx1ZSwgY3Vyc29yLCBtYXNrW2N1cnNvcl0pO1xuICAgICAgICAgICAgICAgICAgICBjdXJzb3IrKztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gaW5wdXRWYWx1ZTtcbiAgICB9XG5cbiAgICBwdWJsaWMgcGFyc2VWYWx1ZUJ5TWFza1Vwb25Db3B5UGFzdGUodmFsdWUsIG1hc2tPcHRpb25zLCBjdXJzb3IsIGNsaXBib2FyZERhdGEsIHNlbGVjdGlvbik6IHN0cmluZyB7XG4gICAgICAgIGxldCBpbnB1dFZhbHVlOiBzdHJpbmcgPSB2YWx1ZTtcbiAgICAgICAgY29uc3QgbWFzazogc3RyaW5nID0gbWFza09wdGlvbnMuZm9ybWF0O1xuICAgICAgICBjb25zdCBsaXRlcmFsczogTWFwPG51bWJlciwgc3RyaW5nPiA9IHRoaXMuZ2V0TWFza0xpdGVyYWxzKG1hc2spO1xuICAgICAgICBjb25zdCBsaXRlcmFsS2V5czogbnVtYmVyW10gPSBBcnJheS5mcm9tKGxpdGVyYWxzLmtleXMoKSk7XG4gICAgICAgIGNvbnN0IG5vbkxpdGVyYWxJbmRlY2VzOiBudW1iZXJbXSA9IHRoaXMuZ2V0Tm9uTGl0ZXJhbEluZGVjZXMobWFzaywgbGl0ZXJhbEtleXMpO1xuXG4gICAgICAgIGNvbnN0IHNlbGVjdGlvbkVuZCA9IGN1cnNvciArIHNlbGVjdGlvbjtcblxuICAgICAgICB0aGlzLl9jdXJzb3IgPSBjdXJzb3I7XG4gICAgICAgIGZvciAoY29uc3QgY2xpcGJvYXJkU3ltIG9mIGNsaXBib2FyZERhdGEpIHtcbiAgICAgICAgICAgIGNvbnN0IGNoYXIgPSBjbGlwYm9hcmRTeW07XG5cbiAgICAgICAgICAgIGlmICh0aGlzLl9jdXJzb3IgPiBtYXNrLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dFZhbHVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAobm9uTGl0ZXJhbEluZGVjZXMuaW5kZXhPZih0aGlzLl9jdXJzb3IpICE9PSAtMSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGlzQ2hhclZhbGlkID0gdGhpcy52YWxpZGF0ZUNoYXJPblBvc3Rpb24oY2hhciwgdGhpcy5fY3Vyc29yLCBtYXNrKTtcbiAgICAgICAgICAgICAgICBpZiAoaXNDaGFyVmFsaWQpIHtcbiAgICAgICAgICAgICAgICAgICAgaW5wdXRWYWx1ZSA9IHRoaXMucmVwbGFjZUNoYXJBdChpbnB1dFZhbHVlLCB0aGlzLl9jdXJzb3IrKywgY2hhcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gY3Vyc29yOyBpIDwgbWFzay5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBpZiAobGl0ZXJhbEtleXMuaW5kZXhPZih0aGlzLl9jdXJzb3IpICE9PSAtMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fY3Vyc29yKys7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBpc0NoYXJWYWxpZCA9IHRoaXMudmFsaWRhdGVDaGFyT25Qb3N0aW9uKGNoYXIsIHRoaXMuX2N1cnNvciwgbWFzayk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNDaGFyVmFsaWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dFZhbHVlID0gdGhpcy5yZXBsYWNlQ2hhckF0KGlucHV0VmFsdWUsIHRoaXMuX2N1cnNvcisrLCBjaGFyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBzZWxlY3Rpb24tLTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzZWxlY3Rpb24gPiAwKSB7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gdGhpcy5fY3Vyc29yOyBpIDwgc2VsZWN0aW9uRW5kOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAobGl0ZXJhbEtleXMuaW5kZXhPZih0aGlzLl9jdXJzb3IpICE9PSAtMSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9jdXJzb3IrKztcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBpbnB1dFZhbHVlID0gdGhpcy5yZXBsYWNlQ2hhckF0KGlucHV0VmFsdWUsIHRoaXMuX2N1cnNvcisrLCBtYXNrT3B0aW9ucy5wcm9tcHRDaGFyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gaW5wdXRWYWx1ZTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHZhbGlkYXRlQ2hhck9uUG9zdGlvbihpbnB1dENoYXI6IHN0cmluZywgcG9zaXRpb246IG51bWJlciwgbWFzazogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgICAgIGxldCByZWdleDogUmVnRXhwO1xuICAgICAgICBsZXQgaXNWYWxpZDogYm9vbGVhbjtcbiAgICAgICAgY29uc3QgbGV0dGVyT3JEaWdpdFJlZ0V4ID0gJ1tcXFxcZFxcXFx1MDBDMC1cXFxcdTFGRkZcXFxcdTJDMDAtXFxcXHVEN0ZGYS16QS1aXSc7XG4gICAgICAgIGNvbnN0IGxldHRlckRpZ2l0T3JTcGFjZVJlZ0V4ID0gJ1tcXFxcZFxcXFx1MDBDMC1cXFxcdTFGRkZcXFxcdTJDMDAtXFxcXHVEN0ZGYS16QS1aXFxcXHUwMDIwXSc7XG4gICAgICAgIGNvbnN0IGxldHRlclJlZ0V4ID0gJ1tcXFxcdTAwQzAtXFxcXHUxRkZGXFxcXHUyQzAwLVxcXFx1RDdGRmEtekEtWl0nO1xuICAgICAgICBjb25zdCBsZXR0ZVNwYWNlUmVnRXggPSAnW1xcXFx1MDBDMC1cXFxcdTFGRkZcXFxcdTJDMDAtXFxcXHVEN0ZGYS16QS1aXFxcXHUwMDIwXSc7XG4gICAgICAgIGNvbnN0IGRpZ2l0UmVnRXggPSAnW1xcXFxkXSc7XG4gICAgICAgIGNvbnN0IGRpZ2l0U3BhY2VSZWdFeCA9ICdbXFxcXGRcXFxcdTAwMjBdJztcbiAgICAgICAgY29uc3QgZGlnaXRTcGVjaWFsUmVnRXggPSAnW1xcXFxkLVxcXFwrXSc7XG5cbiAgICAgICAgc3dpdGNoIChtYXNrLmNoYXJBdChwb3NpdGlvbikpIHtcbiAgICAgICAgICAgIGNhc2UgJ0MnOlxuICAgICAgICAgICAgICAgIGlzVmFsaWQgPSBpbnB1dENoYXIgIT09ICcnO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnJic6XG4gICAgICAgICAgICAgICAgcmVnZXggPSBuZXcgUmVnRXhwKCdbXFxcXHUwMDIwXScpO1xuICAgICAgICAgICAgICAgIGlzVmFsaWQgPSAhcmVnZXgudGVzdChpbnB1dENoYXIpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnYSc6XG4gICAgICAgICAgICAgICAgcmVnZXggPSBuZXcgUmVnRXhwKGxldHRlckRpZ2l0T3JTcGFjZVJlZ0V4KTtcbiAgICAgICAgICAgICAgICBpc1ZhbGlkID0gcmVnZXgudGVzdChpbnB1dENoYXIpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnQSc6XG4gICAgICAgICAgICAgICAgcmVnZXggPSBuZXcgUmVnRXhwKGxldHRlck9yRGlnaXRSZWdFeCk7XG4gICAgICAgICAgICAgICAgaXNWYWxpZCA9IHJlZ2V4LnRlc3QoaW5wdXRDaGFyKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJz8nOlxuICAgICAgICAgICAgICAgIHJlZ2V4ID0gbmV3IFJlZ0V4cChsZXR0ZVNwYWNlUmVnRXgpO1xuICAgICAgICAgICAgICAgIGlzVmFsaWQgPSByZWdleC50ZXN0KGlucHV0Q2hhcik7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdMJzpcbiAgICAgICAgICAgICAgICByZWdleCA9IG5ldyBSZWdFeHAobGV0dGVyUmVnRXgpO1xuICAgICAgICAgICAgICAgIGlzVmFsaWQgPSByZWdleC50ZXN0KGlucHV0Q2hhcik7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICcwJzpcbiAgICAgICAgICAgICAgICByZWdleCA9IG5ldyBSZWdFeHAoZGlnaXRSZWdFeCk7XG4gICAgICAgICAgICAgICAgaXNWYWxpZCA9IHJlZ2V4LnRlc3QoaW5wdXRDaGFyKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJzknOlxuICAgICAgICAgICAgICAgIHJlZ2V4ID0gbmV3IFJlZ0V4cChkaWdpdFNwYWNlUmVnRXgpO1xuICAgICAgICAgICAgICAgIGlzVmFsaWQgPSByZWdleC50ZXN0KGlucHV0Q2hhcik7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICcjJzpcbiAgICAgICAgICAgICAgICByZWdleCA9IG5ldyBSZWdFeHAoZGlnaXRTcGVjaWFsUmVnRXgpO1xuICAgICAgICAgICAgICAgIGlzVmFsaWQgPSByZWdleC50ZXN0KGlucHV0Q2hhcik7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OiB7XG4gICAgICAgICAgICAgICAgaXNWYWxpZCA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gaXNWYWxpZDtcbiAgICB9XG4gICAgcHJpdmF0ZSByZXBsYWNlQ2hhckF0KHN0clZhbHVlOiBzdHJpbmcsIGluZGV4OiBudW1iZXIsIGNoYXI6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgICAgIGlmIChzdHJWYWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gc3RyVmFsdWUuc3Vic3RyaW5nKDAsIGluZGV4KSArIGNoYXIgKyBzdHJWYWx1ZS5zdWJzdHJpbmcoaW5kZXggKyAxKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBwcml2YXRlIGluc2VydENoYXJBdChzdHJWYWx1ZTogc3RyaW5nLCBpbmRleDogbnVtYmVyLCBjaGFyOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICBpZiAoc3RyVmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIHN0clZhbHVlLnN1YnN0cmluZygwLCBpbmRleCkgKyBjaGFyICsgc3RyVmFsdWUuc3Vic3RyaW5nKGluZGV4KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBwcml2YXRlIGdldE1hc2tMaXRlcmFscyhtYXNrOiBzdHJpbmcpOiBNYXA8bnVtYmVyLCBzdHJpbmc+IHtcbiAgICAgICAgY29uc3QgbGl0ZXJhbHMgPSBuZXcgTWFwPG51bWJlciwgc3RyaW5nPigpO1xuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbWFzay5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgY29uc3QgY2hhciA9IG1hc2suY2hhckF0KGkpO1xuICAgICAgICAgICAgaWYgKE1BU0tfRkxBR1MuaW5kZXhPZihjaGFyKSA9PT0gLTEpIHtcbiAgICAgICAgICAgICAgICBsaXRlcmFscy5zZXQoaSwgY2hhcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbGl0ZXJhbHM7XG4gICAgfVxuICAgIHByaXZhdGUgZ2V0Tm9uTGl0ZXJhbEluZGVjZXMobWFzazogc3RyaW5nLCBsaXRlcmFsS2V5czogbnVtYmVyW10pOiBudW1iZXJbXSB7XG4gICAgICAgIGNvbnN0IG5vbkxpdGVyYWxzSW5kZWNlczogbnVtYmVyW10gPSBuZXcgQXJyYXkoKTtcblxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG1hc2subGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmIChsaXRlcmFsS2V5cy5pbmRleE9mKGkpID09PSAtMSkge1xuICAgICAgICAgICAgICAgIG5vbkxpdGVyYWxzSW5kZWNlcy5wdXNoKGkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5vbkxpdGVyYWxzSW5kZWNlcztcbiAgICB9XG4gICAgcHJpdmF0ZSBnZXROb25MaXRlcmFsVmFsdWVzKHZhbHVlOiBzdHJpbmcsIGxpdGVyYWxWYWx1ZXM6IHN0cmluZ1tdKTogc3RyaW5nW10ge1xuICAgICAgICBjb25zdCBub25MaXRlcmFsVmFsdWVzOiBzdHJpbmdbXSA9IG5ldyBBcnJheSgpO1xuXG4gICAgICAgIGZvciAoY29uc3QgdmFsIG9mIHZhbHVlKSB7XG4gICAgICAgICAgICBpZiAobGl0ZXJhbFZhbHVlcy5pbmRleE9mKHZhbCkgPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgbm9uTGl0ZXJhbFZhbHVlcy5wdXNoKHZhbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbm9uTGl0ZXJhbFZhbHVlcztcbiAgICB9XG59Il19