@alauda-fe/common
Version:
Alauda frontend team common codes.
280 lines • 47.4 kB
JavaScript
import { Injectable, IterableDiffers, } from '@angular/core';
import { cloneDeep, isEqual, set, unset } from 'lodash-es';
import * as i0 from "@angular/core";
export const DUPLICATE_ERROR_KEY = 'duplicateError';
// IDENTICAL: 检测具有互反性,传递性。a与b重复,b与c重复,a必然与c重复,此程度上可进行优化
// FULL: 不要求检测具有互反性,传递性。a与b判别重复,b与c判别重复,a未必与c判别重复
// 主要是针对一些复杂的自定义匹配重复的使用场景,FULL模式采用全检查
export var DUPLICATION_JUSTIFY_STRATEGY;
(function (DUPLICATION_JUSTIFY_STRATEGY) {
DUPLICATION_JUSTIFY_STRATEGY["IDENTICAL"] = "identical";
DUPLICATION_JUSTIFY_STRATEGY["FULL"] = "full";
})(DUPLICATION_JUSTIFY_STRATEGY || (DUPLICATION_JUSTIFY_STRATEGY = {}));
export const STRATEGY_JUDGE_MAPPER = {
[DUPLICATION_JUSTIFY_STRATEGY.IDENTICAL]: identicalStrategyCheck,
[DUPLICATION_JUSTIFY_STRATEGY.FULL]: fullStrategyCheck,
};
// use in component lifecycle
export class ValidateRowDuplicateService {
/**
* @param differFactory: used to create support differ, which can be provided by user
*/
constructor(arrayDiffers) {
this.arrayDiffers = arrayDiffers;
// used to save last value, to check whether if control changed
this.controlValueMap = new WeakMap();
// used to save errors,to solve validators concurrently work(second validator can't get error from previous validator in one turn)
this.errorMap = new WeakMap();
}
// eslint-disable-next-line sonarjs/cognitive-complexity
createFormArrayValidator({ rowKeys, formArray, valueMapFn = defaultValueMapFn, initData = [], matchesFn = matchValue, strategy = DUPLICATION_JUSTIFY_STRATEGY.IDENTICAL, }) {
const keys = formatKeys(rowKeys);
if (!this.rowsDiffer) {
this.rowsDiffer = this.arrayDiffers.find([]).create();
}
this.initFormArraySizeChange(formArray, this.rowsDiffer, keys, valueMapFn, matchesFn, strategy, initData);
return (control) => {
const { controls } = formArray;
const lastValue = this.controlValueMap.get(control);
if (control.pristine) {
return null;
}
// nothing change
const currentValue = getValueInKeys(control.value, keys, valueMapFn);
this.controlValueMap.set(control, currentValue);
if (lastValue) {
let identical = true;
Object.entries(keys).forEach(([key, props]) => {
if (!equalsValue(props, currentValue[key], lastValue[key])) {
identical = false;
}
});
if (identical) {
return this.errorMap.get(control);
}
}
const diffKeys = lastValue
? diffKeysByValue(keys, currentValue, lastValue)
: keys;
// 和上次值存在差异,可将老数据作为删除行处理
if (lastValue) {
this.handleRemoveRowValue(diffKeys, controls, lastValue, valueMapFn, control, matchesFn, strategy, initData);
}
// 更新后的状态,可能导致其他行出现新的重复
const otherControls = controls.filter(ctrl => ctrl !== control);
const ctrlError = {};
otherControls.forEach(ctrl => {
const otherValue = getValueInKeys(ctrl.value, diffKeys, valueMapFn);
const othersError = {};
// keys 中分别比较 如果 otherValue 与 currentValue 在某个key下,数据相同,则说明此 key 存在重复错误
Object.entries(diffKeys).forEach(([key, props]) => {
if (matchesFn(props, otherValue[key], currentValue[key])) {
set(othersError, [key], currentValue[key]);
set(ctrlError, key, currentValue[key]);
}
});
this.addDuplicateError(othersError, ctrl, true);
});
(initData || []).forEach(initRow => {
Object.entries(diffKeys).forEach(([key, props]) => {
if (matchesFn(props, initRow[key], currentValue[key])) {
set(ctrlError, key, currentValue[key]);
}
});
});
this.addDuplicateError(ctrlError, control);
return this.errorMap.get(control);
};
}
handleRemoveRowValue(keys, controls, staleValue, mapFn, selfControl, matchesFn, strategy, initData) {
if (selfControl) {
this.removeDuplicateError(Object.keys(keys), selfControl);
}
const toRemoveError = STRATEGY_JUDGE_MAPPER[strategy](keys, controls, staleValue, mapFn, matchesFn, initData);
(toRemoveError || []).forEach(({ key, control }) => this.removeDuplicateError([key], control, true));
}
initFormArraySizeChange(formArray, rowsDiffer, keys, mapFn, matchesFn, strategy, initData) {
if (!this.formArraySizeSub) {
this.formArraySizeSub = formArray.valueChanges.subscribe(_ => {
const { controls } = formArray;
const rowsDiff = rowsDiffer.diff(controls);
if (rowsDiff) {
// on deleting row
rowsDiff.forEachRemovedItem(record => {
const rawValue = getValueInKeys(record.item.value, keys, mapFn);
this.handleRemoveRowValue(keys, controls, rawValue, mapFn, undefined, matchesFn, strategy, initData);
});
}
});
}
}
addDuplicateError(errorInfo, control, setControl = false) {
const errors = cloneDeep(this.errorMap.get(control)) || {};
// already has error,no need to add
if (!Object.keys(errorInfo).some(key => errors?.[DUPLICATE_ERROR_KEY]?.[key] == null)) {
return;
}
Object.keys(errorInfo).forEach(key => {
set(errors, [DUPLICATE_ERROR_KEY, key], errorInfo[key]);
});
this.errorMap.set(control, errors);
if (setControl) {
// 当设置重复报错时,需要注意保留原来的报错
const controlError = cloneDeep(control.errors);
unset(controlError, [DUPLICATE_ERROR_KEY]);
const error = { ...controlError, ...this.errorMap.get(control) };
control.setErrors(Object.keys(error).length === 0 ? null : error, {
emitEvent: false,
});
// control's error should be shown,it's not pristine any more
control.markAsDirty();
}
}
removeDuplicateError(errorInfo, control, setControl = false) {
const errors = cloneDeep(this.errorMap.get(control));
// no need to remove error
if (!errorInfo.some(key => errors?.[DUPLICATE_ERROR_KEY]?.[key] != null)) {
return;
}
errorInfo.forEach(key => {
unset(errors, [DUPLICATE_ERROR_KEY, key]);
});
this.errorMap.set(control, Object.keys(errors?.[DUPLICATE_ERROR_KEY] || {}).length ? errors : null);
if (setControl) {
const controlError = cloneDeep(control.errors) || {};
unset(controlError, [DUPLICATE_ERROR_KEY]);
const error = { ...controlError, ...this.errorMap.get(control) };
control.setErrors(Object.keys(error).length === 0 ? null : error, {
emitEvent: false,
});
}
}
ngOnDestroy() {
if (this.formArraySizeSub) {
this.formArraySizeSub.unsubscribe();
}
}
static { this.ɵfac = function ValidateRowDuplicateService_Factory(t) { return new (t || ValidateRowDuplicateService)(i0.ɵɵinject(i0.IterableDiffers)); }; }
static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: ValidateRowDuplicateService, factory: ValidateRowDuplicateService.ɵfac }); }
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ValidateRowDuplicateService, [{
type: Injectable
}], () => [{ type: i0.IterableDiffers }], null); })();
// 仅返回keys规则下,currentValue与lastValue存在不同的部分key
function diffKeysByValue(keys, currentValue, lastValue) {
const obj = {};
Object.entries(keys).forEach(([key, props]) => {
if (!equalsValue(props, currentValue[key], lastValue[key])) {
obj[key] = props;
}
});
return obj;
}
// 指定属性下,value1 和 value2 对于所有的属性存在有效值,并且相同,此时可判定重复
function matchValue(props, value1, value2) {
return !props.some(prop => unCheckedValue(value1, prop) || value1[prop] !== value2[prop]);
}
// 指定属性下,value1 和 value2 对于所有的属性相同,此时可判定 value1 , value2 相等
function equalsValue(props, value1, value2) {
return !props.some(prop => !isEqual(value1[prop], value2[prop]));
}
/**
* @param keys ['protocol',{complex: ['containerPort','hostPort']}]
* @returns [{protocol: ['protocol']}, {complex: ['containerPort','hostPort']}]
*/
function formatKeys(keys = []) {
const obj = {};
keys.forEach(keyObj => {
if (typeof keyObj === 'string') {
obj[keyObj] = [keyObj];
return;
}
Object.keys(keyObj).forEach(key => {
obj[key] = keyObj[key];
});
});
return obj;
}
function unCheckedValue(value, key) {
return value?.[key] == null || value[key] === '';
}
function defaultValueMapFn(data, prop) {
return data?.[prop];
}
/**
* @param value input value,which should include all key behind keys
* @param keys formatted keys, key is error key, like [{'containerPort':['containerPort']},{'complexError':['containerPort','hostPort']}]
* @returns
*/
function getValueInKeys(value, keys, mapFn) {
const obj = {};
Object.entries(keys).forEach(([key, props]) => {
props.forEach(prop => {
set(obj, [key, prop], mapFn(value, prop));
});
});
return obj;
}
// 互反性检查
function identicalStrategyCheck(keys, controls, staleValue, mapFn, matchesFn, initData) {
const errorsCounter = {};
Object.entries(keys).forEach(([key, props]) => {
errorsCounter[key] = { controls: new Set(), count: 0 };
initData.forEach(initRow => {
if (matchValue(props, initRow[key], staleValue[key])) {
errorsCounter[key].count++;
}
});
controls.forEach(ctrl => {
const controlValue = getValueInKeys(ctrl.value, keys, mapFn);
// 互反性策略,要求和老数据相比,因此只有和老数据相同,但和任意当前其他数据不同的,才需要去掉之前的错误
if (matchesFn(props, controlValue[key], staleValue[key])) {
errorsCounter[key].count++;
errorsCounter[key].controls.add(ctrl);
}
});
});
const toRemoveError = [];
Object.entries(errorsCounter).forEach(([key, item]) => {
if (item.count === 1) {
item.controls.forEach(control => {
toRemoveError.push({ key, control });
});
}
});
return toRemoveError;
}
// 全检查
function fullStrategyCheck(keys, controls, _, mapFn, matchesFn, initData) {
const controlError = new Map();
Object.entries(keys).forEach(([key, props]) => {
controls.forEach(ctrl => {
const controlValue = getValueInKeys(ctrl.value, keys, mapFn);
// 全检查策略,最终错误 key 对应 count 为 0 的ctrl会去掉相应错误
controlError.set(ctrl, { key, count: 0 });
initData.forEach(initRow => {
if (matchValue(props, initRow[key], controlValue)) {
const rawCount = controlError.get(ctrl).count;
controlError.set(ctrl, { key, count: rawCount + 1 });
}
});
controls
.filter(otherControl => otherControl !== ctrl)
.forEach(otherControl => {
const otherValue = getValueInKeys(otherControl.value, keys, mapFn);
if (matchesFn(props, controlValue[key], otherValue[key])) {
const rawCount = controlError.get(ctrl).count;
controlError.set(ctrl, { key, count: rawCount + 1 });
}
});
});
});
const toRemoveError = [];
controlError.forEach(({ count, key }, control) => {
if (count === 0) {
toRemoveError.push({ key, control });
}
});
return toRemoveError;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9ybS1yb3ctZHVwbGljYXRlLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9saWJzL2NvbW1vbi9zcmMvY29yZS9zZXJ2aWNlcy9mb3JtLXJvdy1kdXBsaWNhdGUvZm9ybS1yb3ctZHVwbGljYXRlLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFVBQVUsRUFFVixlQUFlLEdBRWhCLE1BQU0sZUFBZSxDQUFDO0FBUXZCLE9BQU8sRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsTUFBTSxXQUFXLENBQUM7O0FBRzNELE1BQU0sQ0FBQyxNQUFNLG1CQUFtQixHQUFHLGdCQUFnQixDQUFDO0FBcUJwRCx1REFBdUQ7QUFDdkQsaURBQWlEO0FBQ2pELHFDQUFxQztBQUNyQyxNQUFNLENBQU4sSUFBWSw0QkFHWDtBQUhELFdBQVksNEJBQTRCO0lBQ3RDLHVEQUF1QixDQUFBO0lBQ3ZCLDZDQUFhLENBQUE7QUFDZixDQUFDLEVBSFcsNEJBQTRCLEtBQTVCLDRCQUE0QixRQUd2QztBQUVELE1BQU0sQ0FBQyxNQUFNLHFCQUFxQixHQUc5QjtJQUNGLENBQUMsNEJBQTRCLENBQUMsU0FBUyxDQUFDLEVBQUUsc0JBQXNCO0lBQ2hFLENBQUMsNEJBQTRCLENBQUMsSUFBSSxDQUFDLEVBQUUsaUJBQWlCO0NBQ3ZELENBQUM7QUFFRiw2QkFBNkI7QUFFN0IsTUFBTSxPQUFPLDJCQUEyQjtJQUl0Qzs7T0FFRztJQUNILFlBQTZCLFlBQTZCO1FBQTdCLGlCQUFZLEdBQVosWUFBWSxDQUFpQjtRQUUxRCwrREFBK0Q7UUFDOUMsb0JBQWUsR0FBRyxJQUFJLE9BQU8sRUFHM0MsQ0FBQztRQUVKLGtJQUFrSTtRQUNqSCxhQUFRLEdBQUcsSUFBSSxPQUFPLEVBQXFDLENBQUM7SUFUaEIsQ0FBQztJQWE5RCx3REFBd0Q7SUFDeEQsd0JBQXdCLENBQUMs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Q0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDdkQsQ0FBQztZQUNILENBQUMsQ0FBQyxDQUFDO1lBQ0gsUUFBUTtpQkFDTCxNQUFNLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQyxZQUFZLEtBQUssSUFBSSxDQUFDO2lCQUM3QyxPQUFPLENBQUMsWUFBWSxDQUFDLEVBQUU7Z0JBQ3RCLE1BQU0sVUFBVSxHQUFHLGNBQWMsQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztnQkFDbkUsSUFBSSxTQUFTLENBQUMsS0FBSyxFQUFFLFlBQVksQ0FBQyxHQUFHLENBQUMsRUFBRSxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDO29CQUN6RCxNQUFNLFFBQVEsR0FBRyxZQUFZLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLEtBQUssQ0FBQztvQkFDOUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLFFBQVEsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUN2RCxDQUFDO1lBQ0gsQ0FBQyxDQUFDLENBQUM7UUFDUCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0gsTUFBTSxhQUFhLEdBQXFELEVBQUUsQ0FBQztJQUMzRSxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLEVBQUUsT0FBTyxFQUFFLEVBQUU7UUFDL0MsSUFBSSxLQUFLLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDaEIsYUFBYSxDQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZDLENBQUM7SUFDSCxDQUFDLENBQUMsQ0FBQztJQUNILE9BQU8sYUFBYSxDQUFDO0FBQ3ZCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBJbmplY3RhYmxlLFxuICBJdGVyYWJsZURpZmZlcixcbiAgSXRlcmFibGVEaWZmZXJzLFxuICBPbkRlc3Ryb3ksXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtcbiAgQWJzdHJhY3RDb250cm9sLFxuICBGb3JtQXJyYXksXG4gIEZvcm1Hcm91cCxcbiAgVmFsaWRhdGlvbkVycm9ycyxcbiAgVmFsaWRhdG9yRm4sXG59IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IGNsb25lRGVlcCwgaXNFcXVhbCwgc2V0LCB1bnNldCB9IGZyb20gJ2xvZGFzaC1lcyc7XG5pbXBvcnQgeyBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcblxuZXhwb3J0IGNvbnN0IERVUExJQ0FURV9FUlJPUl9LRVkgPSAnZHVwbGljYXRlRXJyb3InO1xuXG50eXBlIFJvd0tleXMgPSBBcnJheTxzdHJpbmcgfCBSZWNvcmQ8c3RyaW5nLCBzdHJpbmdbXT4+O1xudHlwZSBGb3JtYXRLZXlzID0gUmVjb3JkPHN0cmluZywgc3RyaW5nW10+O1xuZXhwb3J0IHR5cGUgRm9ybWF0VmFsdWUgPSBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xuXG5leHBvcnQgdHlwZSBNYXRjaFZhbHVlRm4gPSAoXG4gIHByb3BzOiBzdHJpbmdbXSxcbiAgdmFsdWUxOiBGb3JtYXRWYWx1ZSxcbiAgdmFsdWUyOiBGb3JtYXRWYWx1ZSxcbikgPT4gYm9vbGVhbjtcblxuZXhwb3J0IHR5cGUgU3RyYXRlZ3lGbiA9IChcbiAga2V5czogRm9ybWF0S2V5cyxcbiAgY29udHJvbHM6IEFic3RyYWN0Q29udHJvbFtdLFxuICBzdGFsZVZhbHVlOiBGb3JtYXRWYWx1ZSxcbiAgbWFwRm46IFZhbHVlTWFwRm4sXG4gIG1hdGNoZXNGbjogTWF0Y2hWYWx1ZUZuLFxuICBpbml0RGF0YTogYW55W10sXG4pID0+IEFycmF5PHsga2V5OiBzdHJpbmc7IGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCB9PjtcblxuLy8gSURFTlRJQ0FMOiDmo4DmtYvlhbfmnInkupLlj43mgKfvvIzkvKDpgJLmgKfjgIJh5LiOYumHjeWkje+8jGLkuI5j6YeN5aSN77yMYeW/heeEtuS4jmPph43lpI3vvIzmraTnqIvluqbkuIrlj6/ov5vooYzkvJjljJZcbi8vIEZVTEw6IOS4jeimgeaxguajgOa1i+WFt+acieS6kuWPjeaAp++8jOS8oOmAkuaAp+OAgmHkuI5i5Yik5Yir6YeN5aSN77yMYuS4jmPliKTliKvph43lpI3vvIxh5pyq5b+F5LiOY+WIpOWIq+mHjeWkjVxuLy8g5Li76KaB5piv6ZKI5a+55LiA5Lqb5aSN5p2C55qE6Ieq5a6a5LmJ5Yy56YWN6YeN5aSN55qE5L2/55So5Zy65pmv77yMRlVMTOaooeW8j+mHh+eUqOWFqOajgOafpVxuZXhwb3J0IGVudW0gRFVQTElDQVRJT05fSlVTVElGWV9TVFJBVEVHWSB7XG4gIElERU5USUNBTCA9ICdpZGVudGljYWwnLFxuICBGVUxMID0gJ2Z1bGwnLFxufVxuXG5leHBvcnQgY29uc3QgU1RSQVRFR1lfSlVER0VfTUFQUEVSOiBSZWNvcmQ8XG4gIERVUExJQ0FUSU9OX0pVU1RJRllfU1RSQVRFR1ksXG4gIFN0cmF0ZWd5Rm5cbj4gPSB7XG4gIFtEVVBMSUNBVElPTl9KVVNUSUZZX1NUUkFURUdZLklERU5USUNBTF06IGlkZW50aWNhbFN0cmF0ZWd5Q2hlY2ssXG4gIFtEVVBMSUNBVElPTl9KVVNUSUZZX1NUUkFURUdZLkZVTExdOiBmdWxsU3RyYXRlZ3lDaGVjayxcbn07XG5cbi8vIHVzZSBpbiBjb21wb25lbnQgbGlmZWN5Y2xlXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgVmFsaWRhdGVSb3dEdXBsaWNhdGVTZXJ2aWNlIGltcGxlbWVudHMgT25EZXN0cm95IHtcbiAgLy8gdXNlZCB0byBkZXRlY3QgYWxsIGNvbnRyb2xzIGRhdGEgY2hhbmdlXG4gIHByaXZhdGUgcm93c0RpZmZlcjogSXRlcmFibGVEaWZmZXI8QWJzdHJhY3RDb250cm9sPjtcblxuICAvKipcbiAgICogQHBhcmFtIGRpZmZlckZhY3Rvcnk6IHVzZWQgdG8gY3JlYXRlIHN1cHBvcnQgZGlmZmVyLCB3aGljaCBjYW4gYmUgcHJvdmlkZWQgYnkgdXNlclxuICAgKi9cbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSBhcnJheURpZmZlcnM6IEl0ZXJhYmxlRGlmZmVycykge31cblxuICAvLyB1c2VkIHRvIHNhdmUgbGFzdCB2YWx1ZSwgdG8gY2hlY2sgd2hldGhlciBpZiBjb250cm9sIGNoYW5nZWRcbiAgcHJpdmF0ZSByZWFkb25seSBjb250cm9sVmFsdWVNYXAgPSBuZXcgV2Vha01hcDxcbiAgICBBYnN0cmFjdENvbnRyb2wsXG4gICAgRm9ybWF0VmFsdWVcbiAgPigpO1xuXG4gIC8vIHVzZWQgdG8gc2F2ZSBlcnJvcnPvvIx0byBzb2x2ZSB2YWxpZGF0b3JzIGNvbmN1cnJlbnRseSB3b3JrKHNlY29uZCB2YWxpZGF0b3IgY2FuJ3QgZ2V0IGVycm9yIGZyb20gcHJldmlvdXMgdmFsaWRhdG9yIGluIG9uZSB0dXJuKVxuICBwcml2YXRlIHJlYWRvbmx5IGVycm9yTWFwID0gbmV3IFdlYWtNYXA8QWJzdHJhY3RDb250cm9sLCBWYWxpZGF0aW9uRXJyb3JzPigpO1xuXG4gIHByaXZhdGUgZm9ybUFycmF5U2l6ZVN1YjogU3Vic2NyaXB0aW9uO1xuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBzb25hcmpzL2NvZ25pdGl2ZS1jb21wbGV4aXR5XG4gIGNyZWF0ZUZvcm1BcnJheVZhbGlkYXRvcih7XG4gICAgcm93S2V5cyxcbiAgICBmb3JtQXJyYXksXG4gICAgdmFsdWVNYXBGbiA9IGRlZmF1bHRWYWx1ZU1hcEZuLFxuICAgIGluaXREYXRhID0gW10sXG4gICAgbWF0Y2hlc0ZuID0gbWF0Y2hWYWx1ZSxcbiAgICBzdHJhdGVneSA9IERVUExJQ0FUSU9OX0pVU1RJRllfU1RSQVRFR1kuSURFTlRJQ0FMLFxuICB9OiB7XG4gICAgcm93S2V5czogUm93S2V5cztcbiAgICBmb3JtQXJyYXk6IEZvcm1BcnJheTtcbiAgICB2YWx1ZU1hcEZuPzogYW55O1xuICAgIGluaXREYXRhPzogYW55W107XG4gICAgbWF0Y2hlc0ZuPzogTWF0Y2hWYWx1ZUZuO1xuICAgIHN0cmF0ZWd5PzogRFVQTElDQVRJT05fSlVTVElGWV9TVFJBVEVHWTtcbiAgfSk6IFZhbGlkYXRvckZuIHtcbiAgICBjb25zdCBrZXlzID0gZm9ybWF0S2V5cyhyb3dLZXlzKTtcbiAgICBpZiAoIXRoaXMucm93c0RpZmZlcikge1xuICAgICAgdGhpcy5yb3dzRGlmZmVyID0gdGhpcy5hcnJheURpZmZlcnMuZmluZChbXSkuY3JlYXRlKCk7XG4gICAgfVxuXG4gICAgdGhpcy5pbml0Rm9ybUFycmF5U2l6ZUNoYW5nZShcbiAgICAgIGZvcm1BcnJheSxcbiAgICAgIHRoaXMucm93c0RpZmZlcixcbiAgICAgIGtleXMsXG4gICAgICB2YWx1ZU1hcEZuLFxuICAgICAgbWF0Y2hlc0ZuLFxuICAgICAgc3RyYXRlZ3ksXG4gICAgICBpbml0RGF0YSxcbiAgICApO1xuXG4gICAgcmV0dXJuIChjb250cm9sOiBGb3JtR3JvdXApID0+IHtcbiAgICAgIGNvbnN0IHsgY29udHJvbHMgfSA9IGZvcm1BcnJheTtcbiAgICAgIGNvbnN0IGxhc3RWYWx1ZSA9IHRoaXMuY29udHJvbFZhbHVlTWFwLmdldChjb250cm9sKTtcbiAgICAgIGlmIChjb250cm9sLnByaXN0aW5lKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICAgLy8gbm90aGluZyBjaGFuZ2VcbiAgICAgIGNvbnN0IGN1cnJlbnRWYWx1ZSA9IGdldFZhbHVlSW5LZXlzKGNvbnRyb2wudmFsdWUsIGtleXMsIHZhbHVlTWFwRm4pO1xuICAgICAgdGhpcy5jb250cm9sVmFsdWVNYXAuc2V0KGNvbnRyb2wsIGN1cnJlbnRWYWx1ZSk7XG4gICAgICBpZiAobGFzdFZhbHVlKSB7XG4gICAgICAgIGxldCBpZGVudGljYWwgPSB0cnVlO1xuICAgICAgICBPYmplY3QuZW50cmllcyhrZXlzKS5mb3JFYWNoKChba2V5LCBwcm9wc10pID0+IHtcbiAgICAgICAgICBpZiAoIWVxdWFsc1ZhbHVlKHByb3BzLCBjdXJyZW50VmFsdWVba2V5XSwgbGFzdFZhbHVlW2tleV0pKSB7XG4gICAgICAgICAgICBpZGVudGljYWwgPSBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoaWRlbnRpY2FsKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZXJyb3JNYXAuZ2V0KGNvbnRyb2wpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBjb25zdCBkaWZmS2V5cyA9IGxhc3RWYWx1ZVxuICAgICAgICA/IGRpZmZLZXlzQnlWYWx1ZShrZXlzLCBjdXJyZW50VmFsdWUsIGxhc3RWYWx1ZSlcbiAgICAgICAgOiBrZXlzO1xuICAgICAgLy8g5ZKM5LiK5qyh5YC85a2Y5Zyo5beu5byC77yM5Y+v5bCG6ICB5pWw5o2u5L2c5Li65Yig6Zmk6KGM5aSE55CGXG4gICAgICBpZiAobGFzdFZhbHVlKSB7XG4gICAgICAgIHRoaXMuaGFuZGxlUmVtb3ZlUm93VmFsdWUoXG4gICAgICAgICAgZGlmZktleXMsXG4gICAgICAgICAgY29udHJvbHMsXG4gICAgICAgICAgbGFzdFZhbHVlLFxuICAgICAgICAgIHZhbHVlTWFwRm4sXG4gICAgICAgICAgY29udHJvbCxcbiAgICAgICAgICBtYXRjaGVzRm4sXG4gICAgICAgICAgc3RyYXRlZ3ksXG4gICAgICAgICAgaW5pdERhdGEsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICAvLyDmm7TmlrDlkI7nmoTnirbmgIHvvIzlj6/og73lr7zoh7Tlhbbku5booYzlh7rnjrDmlrDnmoTph43lpI1cbiAgICAgIGNvbnN0IG90aGVyQ29udHJvbHMgPSBjb250cm9scy5maWx0ZXIoY3RybCA9PiBjdHJsICE9PSBjb250cm9sKTtcbiAgICAgIGNvbnN0IGN0cmxFcnJvcjogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9O1xuICAgICAgb3RoZXJDb250cm9scy5mb3JFYWNoKGN0cmwgPT4ge1xuICAgICAgICBjb25zdCBvdGhlclZhbHVlID0gZ2V0VmFsdWVJbktleXMoY3RybC52YWx1ZSwgZGlmZktleXMsIHZhbHVlTWFwRm4pO1xuICAgICAgICBjb25zdCBvdGhlcnNFcnJvcjogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9O1xuICAgICAgICAvLyBrZXlzIOS4reWIhuWIq+avlOi+gyDlpoLmnpwgb3RoZXJWYWx1ZSDkuI4gY3VycmVudFZhbHVlIOWcqOafkOS4qmtleeS4i++8jOaVsOaNruebuOWQjO+8jOWImeivtOaYjuatpCBrZXkg5a2Y5Zyo6YeN5aSN6ZSZ6K+vXG4gICAgICAgIE9iamVjdC5lbnRyaWVzKGRpZmZLZXlzKS5mb3JFYWNoKChba2V5LCBwcm9wc10pID0+IHtcbiAgICAgICAgICBpZiAobWF0Y2hlc0ZuKHByb3BzLCBvdGhlclZhbHVlW2tleV0sIGN1cnJlbnRWYWx1ZVtrZXldKSkge1xuICAgICAgICAgICAgc2V0KG90aGVyc0Vycm9yLCBba2V5XSwgY3VycmVudFZhbHVlW2tleV0pO1xuICAgICAgICAgICAgc2V0KGN0cmxFcnJvciwga2V5LCBjdXJyZW50VmFsdWVba2V5XSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5hZGREdXBsaWNhdGVFcnJvcihvdGhlcnNFcnJvciwgY3RybCwgdHJ1ZSk7XG4gICAgICB9KTtcbiAgICAgIChpbml0RGF0YSB8fCBbXSkuZm9yRWFjaChpbml0Um93ID0+IHtcbiAgICAgICAgT2JqZWN0LmVudHJpZXMoZGlmZktleXMpLmZvckVhY2goKFtrZXksIHByb3BzXSkgPT4ge1xuICAgICAgICAgIGlmIChtYXRjaGVzRm4ocHJvcHMsIGluaXRSb3dba2V5XSwgY3VycmVudFZhbHVlW2tleV0pKSB7XG4gICAgICAgICAgICBzZXQoY3RybEVycm9yLCBrZXksIGN1cnJlbnRWYWx1ZVtrZXldKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgICB0aGlzLmFkZER1cGxpY2F0ZUVycm9yKGN0cmxFcnJvciwgY29udHJvbCk7XG4gICAgICByZXR1cm4gdGhpcy5lcnJvck1hcC5nZXQoY29udHJvbCk7XG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlUmVtb3ZlUm93VmFsdWUoXG4gICAga2V5czogRm9ybWF0S2V5cyxcbiAgICBjb250cm9sczogQWJzdHJhY3RDb250cm9sW10sXG4gICAgc3RhbGVWYWx1ZTogRm9ybWF0VmFsdWUsXG4gICAgbWFwRm46IFZhbHVlTWFwRm4sXG4gICAgc2VsZkNvbnRyb2w/OiBBYnN0cmFjdENvbnRyb2wsXG4gICAgbWF0Y2hlc0ZuPzogTWF0Y2hWYWx1ZUZuLFxuICAgIHN0cmF0ZWd5PzogRFVQTElDQVRJT05fSlVTVElGWV9TVFJBVEVHWSxcbiAgICBpbml0RGF0YT86IGFueVtdLFxuICApIHtcbiAgICBpZiAoc2VsZkNvbnRyb2wpIHtcbiAgICAgIHRoaXMucmVtb3ZlRHVwbGljYXRlRXJyb3IoT2JqZWN0LmtleXMoa2V5cyksIHNlbGZDb250cm9sKTtcbiAgICB9XG4gICAgY29uc3QgdG9SZW1vdmVFcnJvciA9IFNUUkFURUdZX0pVREdFX01BUFBFUltzdHJhdGVneV0oXG4gICAgICBrZXlzLFxuICAgICAgY29udHJvbHMsXG4gICAgICBzdGFsZVZhbHVlLFxuICAgICAgbWFwRm4sXG4gICAgICBtYXRjaGVzRm4sXG4gICAgICBpbml0RGF0YSxcbiAgICApO1xuICAgICh0b1JlbW92ZUVycm9yIHx8IFtdKS5mb3JFYWNoKCh7IGtleSwgY29udHJvbCB9KSA9PlxuICAgICAgdGhpcy5yZW1vdmVEdXBsaWNhdGVFcnJvcihba2V5XSwgY29udHJvbCwgdHJ1ZSksXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgaW5pdEZvcm1BcnJheVNpemVDaGFuZ2UoXG4gICAgZm9ybUFycmF5OiBGb3JtQXJyYXksXG4gICAgcm93c0RpZmZlcjogSXRlcmFibGVEaWZmZXI8QWJzdHJhY3RDb250cm9sPixcbiAgICBrZXlzOiBGb3JtYXRLZXlzLFxuICAgIG1hcEZuOiBWYWx1ZU1hcEZuLFxuICAgIG1hdGNoZXNGbjogTWF0Y2hWYWx1ZUZuLFxuICAgIHN0cmF0ZWd5OiBEVVBMSUNBVElPTl9KVVNUSUZZX1NUUkFURUdZLFxuICAgIGluaXREYXRhPzogYW55W10sXG4gICkge1xuICAgIGlmICghdGhpcy5mb3JtQXJyYXlTaXplU3ViKSB7XG4gICAgICB0aGlzLmZvcm1BcnJheVNpemVTdWIgPSBmb3JtQXJyYXkudmFsdWVDaGFuZ2VzLnN1YnNjcmliZShfID0+IHtcbiAgICAgICAgY29uc3QgeyBjb250cm9scyB9ID0gZm9ybUFycmF5O1xuICAgICAgICBjb25zdCByb3dzRGlmZiA9IHJvd3NEaWZmZXIuZGlmZihjb250cm9scyk7XG4gICAgICAgIGlmIChyb3dzRGlmZikge1xuICAgICAgICAgIC8vIG9uIGRlbGV0aW5nIHJvd1xuICAgICAgICAgIHJvd3NEaWZmLmZvckVhY2hSZW1vdmVkSXRlbShyZWNvcmQgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmF3VmFsdWUgPSBnZXRWYWx1ZUluS2V5cyhyZWNvcmQuaXRlbS52YWx1ZSwga2V5cywgbWFwRm4pO1xuICAgICAgICAgICAgdGhpcy5oYW5kbGVSZW1vdmVSb3dWYWx1ZShcbiAgICAgICAgICAgICAga2V5cyxcbiAgICAgICAgICAgICAgY29udHJvbHMsXG4gICAgICAgICAgICAgIHJhd1ZhbHVlLFxuICAgICAgICAgICAgICBtYXBGbixcbiAgICAgICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgICAgICBtYXRjaGVzRm4sXG4gICAgICAgICAgICAgIHN0cmF0ZWd5LFxuICAgICAgICAgICAgICBpbml0RGF0YSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYWRkRHVwbGljYXRlRXJyb3IoXG4gICAgZXJyb3JJbmZvOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxuICAgIGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCxcbiAgICBzZXRDb250cm9sID0gZmFsc2UsXG4gICkge1xuICAgIGNvbnN0IGVycm9ycyA9IGNsb25lRGVlcCh0aGlzLmVycm9yTWFwLmdldChjb250cm9sKSkgfHwge307XG4gICAgLy8gYWxyZWFkeSBoYXMgZXJyb3Isbm8gbmVlZCB0byBhZGRcbiAgICBpZiAoXG4gICAgICAhT2JqZWN0LmtleXMoZXJyb3JJbmZvKS5zb21lKFxuICAgICAgICBrZXkgPT4gZXJyb3JzPy5bRFVQTElDQVRFX0VSUk9SX0tFWV0/LltrZXldID09IG51bGwsXG4gICAgICApXG4gICAgKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgT2JqZWN0LmtleXMoZXJyb3JJbmZvKS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICBzZXQoZXJyb3JzLCBbRFVQTElDQVRFX0VSUk9SX0tFWSwga2V5XSwgZXJyb3JJbmZvW2tleV0pO1xuICAgIH0pO1xuICAgIHRoaXMuZXJyb3JNYXAuc2V0KGNvbnRyb2wsIGVycm9ycyk7XG4gICAgaWYgKHNldENvbnRyb2wpIHtcbiAgICAgIC8vIOW9k+iuvue9rumHjeWkjeaKpemUmeaXtizpnIDopoHms6jmhI/kv53nlZnljp/mnaXnmoTmiqXplJlcbiAgICAgIGNvbnN0IGNvbnRyb2xFcnJvciA9IGNsb25lRGVlcChjb250cm9sLmVycm9ycyk7XG4gICAgICB1bnNldChjb250cm9sRXJyb3IsIFtEVVBMSUNBVEVfRVJST1JfS0VZXSk7XG4gICAgICBjb25zdCBlcnJvciA9IHsgLi4uY29udHJvbEVycm9yLCAuLi50aGlzLmVycm9yTWFwLmdldChjb250cm9sKSB9O1xuICAgICAgY29udHJvbC5zZXRFcnJvcnMoT2JqZWN0LmtleXMoZXJyb3IpLmxlbmd0aCA9PT0gMCA/IG51bGwgOiBlcnJvciwge1xuICAgICAgICBlbWl0RXZlbnQ6IGZhbHNlLFxuICAgICAgfSk7XG5cbiAgICAgIC8vIGNvbnRyb2wncyBlcnJvciBzaG91bGQgYmUgc2hvd24saXQncyBub3QgcHJpc3RpbmUgYW55IG1vcmVcbiAgICAgIGNvbnRyb2wubWFya0FzRGlydHkoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHJlbW92ZUR1cGxpY2F0ZUVycm9yKFxuICAgIGVycm9ySW5mbzogc3RyaW5nW10sXG4gICAgY29udHJvbDogQWJzdHJhY3RDb250cm9sLFxuICAgIHNldENvbnRyb2wgPSBmYWxzZSxcbiAgKSB7XG4gICAgY29uc3QgZXJyb3JzID0gY2xvbmVEZWVwKHRoaXMuZXJyb3JNYXAuZ2V0KGNvbnRyb2wpKTtcbiAgICAvLyBubyBuZWVkIHRvIHJlbW92ZSBlcnJvclxuICAgIGlmICghZXJyb3JJbmZvLnNvbWUoa2V5ID0+IGVycm9ycz8uW0RVUExJQ0FURV9FUlJPUl9LRVldPy5ba2V5XSAhPSBudWxsKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBlcnJvckluZm8uZm9yRWFjaChrZXkgPT4ge1xuICAgICAgdW5zZXQoZXJyb3JzLCBbRFVQTElDQVRFX0VSUk9SX0tFWSwga2V5XSk7XG4gICAgfSk7XG4gICAgdGhpcy5lcnJvck1hcC5zZXQoXG4gICAgICBjb250cm9sLFxuICAgICAgT2JqZWN0LmtleXMoZXJyb3JzPy5bRFVQTElDQVRFX0VSUk9SX0tFWV0gfHwge30pLmxlbmd0aCA/IGVycm9ycyA6IG51bGwsXG4gICAgKTtcbiAgICBpZiAoc2V0Q29udHJvbCkge1xuICAgICAgY29uc3QgY29udHJvbEVycm9yOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0gY2xvbmVEZWVwKGNvbnRyb2wuZXJyb3JzKSB8fCB7fTtcbiAgICAgIHVuc2V0KGNvbnRyb2xFcnJvciwgW0RVUExJQ0FURV9FUlJPUl9LRVldKTtcblxuICAgICAgY29uc3QgZXJyb3IgPSB7IC4uLmNvbnRyb2xFcnJvciwgLi4udGhpcy5lcnJvck1hcC5nZXQoY29udHJvbCkgfTtcbiAgICAgIGNvbnRyb2wuc2V0RXJyb3JzKE9iamVjdC5rZXlzKGVycm9yKS5sZW5ndGggPT09IDAgPyBudWxsIDogZXJyb3IsIHtcbiAgICAgICAgZW1pdEV2ZW50OiBmYWxzZSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIGlmICh0aGlzLmZvcm1BcnJheVNpemVTdWIpIHtcbiAgICAgIHRoaXMuZm9ybUFycmF5U2l6ZVN1Yi51bnN1YnNjcmliZSgpO1xuICAgIH1cbiAgfVxufVxuXG4vLyDku4Xov5Tlm55rZXlz6KeE5YiZ5LiL77yMY3VycmVudFZhbHVl5LiObGFzdFZhbHVl5a2Y5Zyo5LiN5ZCM55qE6YOo5YiGa2V5XG5mdW5jdGlvbiBkaWZmS2V5c0J5VmFsdWUoXG4gIGtleXM6IEZvcm1hdEtleXMsXG4gIGN1cnJlbnRWYWx1ZTogRm9ybWF0VmFsdWUsXG4gIGxhc3RWYWx1ZTogRm9ybWF0VmFsdWUsXG4pIHtcbiAgY29uc3Qgb2JqOiBGb3JtYXRLZXlzID0ge307XG4gIE9iamVjdC5lbnRyaWVzKGtleXMpLmZvckVhY2goKFtrZXksIHByb3BzXSkgPT4ge1xuICAgIGlmICghZXF1YWxzVmFsdWUocHJvcHMsIGN1cnJlbnRWYWx1ZVtrZXldLCBsYXN0VmFsdWVba2V5XSkpIHtcbiAgICAgIG9ialtrZXldID0gcHJvcHM7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIG9iajtcbn1cblxuLy8g5oyH5a6a5bGe5oCn5LiL77yMdmFsdWUxIOWSjCB2YWx1ZTIg5a+55LqO5omA5pyJ55qE5bGe5oCn5a2Y5Zyo5pyJ5pWI5YC877yM5bm25LiU55u45ZCM77yM5q2k5pe25Y+v5Yik5a6a6YeN5aSNXG5mdW5jdGlvbiBtYXRjaFZhbHVlKHByb3BzOiBzdHJpbmdbXSwgdmFsdWUxOiBGb3JtYXRWYWx1ZSwgdmFsdWUyOiBGb3JtYXRWYWx1ZSkge1xuICByZXR1cm4gIXByb3BzLnNvbWUoXG4gICAgcHJvcCA9PiB1bkNoZWNrZWRWYWx1ZSh2YWx1ZTEsIHByb3ApIHx8IHZhbHVlMVtwcm9wXSAhPT0gdmFsdWUyW3Byb3BdLFxuICApO1xufVxuXG4vLyDmjIflrprlsZ7mgKfkuIvvvIx2YWx1ZTEg5ZKMIHZhbHVlMiDlr7nkuo7miYDmnInnmoTlsZ7mgKfnm7jlkIzvvIzmraTml7blj6/liKTlrpogdmFsdWUxICwgdmFsdWUyIOebuOetiVxuZnVuY3Rpb24gZXF1YWxzVmFsdWUoXG4gIHByb3BzOiBzdHJpbmdbXSxcbiAgdmFsdWUxOiBGb3JtYXRWYWx1ZSxcbiAgdmFsdWUyOiBGb3JtYXRWYWx1ZSxcbikge1xuICByZXR1cm4gIXByb3BzLnNvbWUocHJvcCA9PiAhaXNFcXVhbCh2YWx1ZTFbcHJvcF0sIHZhbHVlMltwcm9wXSkpO1xufVxuXG4vKipcbiAqIEBwYXJhbSBrZXlzIFsncHJvdG9jb2wnLHtjb21wbGV4OiBbJ2NvbnRhaW5lclBvcnQnLCdob3N0UG9ydCddfV1cbiAqIEByZXR1cm5zIFt7cHJvdG9jb2w6IFsncHJvdG9jb2wnXX0sIHtjb21wbGV4OiBbJ2NvbnRhaW5lclBvcnQnLCdob3N0UG9ydCddfV1cbiAqL1xuZnVuY3Rpb24gZm9ybWF0S2V5cyhrZXlzOiBSb3dLZXlzID0gW10pOiBGb3JtYXRLZXlzIHtcbiAgY29uc3Qgb2JqOiBGb3JtYXRLZXlzID0ge307XG4gIGtleXMuZm9yRWFjaChrZXlPYmogPT4ge1xuICAgIGlmICh0eXBlb2Yga2V5T2JqID09PSAnc3RyaW5nJykge1xuICAgICAgb2JqW2tleU9ial0gPSBba2V5T2JqXTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgT2JqZWN0LmtleXMoa2V5T2JqKS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICBvYmpba2V5XSA9IGtleU9ialtrZXldO1xuICAgIH0pO1xuICB9KTtcbiAgcmV0dXJuIG9iajtcbn1cblxuZnVuY3Rpb24gdW5DaGVja2VkVmFsdWUodmFsdWU6IEZvcm1hdFZhbHVlLCBrZXk6IHN0cmluZykge1xuICByZXR1cm4gdmFsdWU/LltrZXldID09IG51bGwgfHwgdmFsdWVba2V5XSA9PT0gJyc7XG59XG5cbmZ1bmN0aW9uIGRlZmF1bHRWYWx1ZU1hcEZuKGRhdGE6IGFueSwgcHJvcDogc3RyaW5nKSB7XG4gIHJldHVybiBkYXRhPy5bcHJvcF07XG59XG5cbnR5cGUgVmFsdWVNYXBGbiA9IChkYXRhOiBhbnksIHByb3A/OiBzdHJpbmcpID0+IGFueTtcblxuLyoqXG4gKiBAcGFyYW0gdmFsdWUgaW5wdXQgdmFsdWUsd2hpY2ggc2hvdWxkIGluY2x1ZGUgYWxsIGtleSBiZWhpbmQga2V5c1xuICogQHBhcmFtIGtleXMgZm9ybWF0dGVkIGtleXMsIGtleSBpcyBlcnJvciBrZXksIGxpa2UgW3snY29udGFpbmVyUG9ydCc6Wydjb250YWluZXJQb3J0J119LHsnY29tcGxleEVycm9yJzpbJ2NvbnRhaW5lclBvcnQnLCdob3N0UG9ydCddfV1cbiAqIEByZXR1cm5zXG4gKi9cbmZ1bmN0aW9uIGdldFZhbHVlSW5LZXlzKFxuICB2YWx1ZTogYW55LFxuICBrZXlzOiBGb3JtYXRLZXlzLFxuICBtYXBGbjogVmFsdWVNYXBGbixcbik6IEZvcm1hdFZhbHVlIHtcbiAgY29uc3Qgb2JqID0ge307XG4gIE9iamVjdC5lbnRyaWVzKGtleXMpLmZvckVhY2goKFtrZXksIHByb3BzXSkgPT4ge1xuICAgIHByb3BzLmZvckVhY2gocHJvcCA9PiB7XG4gICAgICBzZXQob2JqLCBba2V5LCBwcm9wXSwgbWFwRm4odmFsdWUsIHByb3ApKTtcbiAgICB9KTtcbiAgfSk7XG4gIHJldHVybiBvYmo7XG59XG5cbi8vIOS6kuWPjeaAp+ajgOafpVxuZnVuY3Rpb24gaWRlbnRpY2FsU3RyYXRlZ3lDaGVjayhcbiAga2V5czogRm9ybWF0S2V5cyxcbiAgY29udHJvbHM6IEFic3RyYWN0Q29udHJvbFtdLFxuICBzdGFsZVZhbHVlOiBGb3JtYXRWYWx1ZSxcbiAgbWFwRm46IFZhbHVlTWFwRm4sXG4gIG1hdGNoZXNGbjogTWF0Y2hWYWx1ZUZuLFxuICBpbml0RGF0YTogYW55W10sXG4pIHtcbiAgY29uc3QgZXJyb3JzQ291bnRlcjogUmVjb3JkPFxuICAgIHN0cmluZyxcbiAgICB7IGNvbnRyb2xzOiBTZXQ8QWJzdHJhY3RDb250cm9sPjsgY291bnQ6IG51bWJlciB9XG4gID4gPSB7fTtcblxuICBPYmplY3QuZW50cmllcyhrZXlzKS5mb3JFYWNoKChba2V5LCBwcm9wc10pID0+IHtcbiAgICBlcnJvcnNDb3VudGVyW2tleV0gPSB7IGNvbnRyb2xzOiBuZXcgU2V0KCksIGNvdW50OiAwIH07XG4gICAgaW5pdERhdGEuZm9yRWFjaChpbml0Um93ID0+IHtcbiAgICAgIGlmIChtYXRjaFZhbHVlKHByb3BzLCBpbml0Um93W2tleV0sIHN0YWxlVmFsdWVba2V5XSkpIHtcbiAgICAgICAgZXJyb3JzQ291bnRlcltrZXldLmNvdW50Kys7XG4gICAgICB9XG4gICAgfSk7XG4gICAgY29udHJvbHMuZm9yRWFjaChjdHJsID0+IHtcbiAgICAgIGNvbnN0IGNvbnRyb2xWYWx1ZSA9IGdldFZhbHVlSW5LZXlzKGN0cmwudmFsdWUsIGtleXMsIG1hcEZuKTtcbiAgICAgIC8vIOS6kuWPjeaAp+etlueVpe+8jOimgeaxguWSjOiAgeaVsOaNruebuOavlO+8jOWboOatpOWPquacieWSjOiAgeaVsOaNruebuOWQjO+8jOS9huWSjOS7u+aEj+W9k+WJjeWFtuS7luaVsOaNruS4jeWQjOeahO+8jOaJjemcgOimgeWOu+aOieS5i+WJjeeahOmUmeivr1xuICAgICAgaWYgKG1hdGNoZXNGbihwcm9wcywgY29udHJvbFZhbHVlW2tleV0sIHN0YWxlVmFsdWVba2V5XSkpIHtcbiAgICAgICAgZXJyb3JzQ291bnRlcltrZXldLmNvdW50Kys7XG4gICAgICAgIGVycm9yc0NvdW50ZXJba2V5XS5jb250cm9scy5hZGQoY3RybCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xuICBjb25zdCB0b1JlbW92ZUVycm9yOiBBcnJheTx7IGtleTogc3RyaW5nOyBjb250cm9sOiBBYnN0cmFjdENvbnRyb2wgfT4gPSBbXTtcbiAgT2JqZWN0LmVudHJpZXMoZXJyb3JzQ291bnRlcikuZm9yRWFjaCgoW2tleSwgaXRlbV0pID0+IHtcbiAgICBpZiAoaXRlbS5jb3VudCA9PT0gMSkge1xuICAgICAgaXRlbS5jb250cm9scy5mb3JFYWNoKGNvbnRyb2wgPT4ge1xuICAgICAgICB0b1JlbW92ZUVycm9yLnB1c2goeyBrZXksIGNvbnRyb2wgfSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gdG9SZW1vdmVFcnJvcjtcbn1cblxuLy8g5YWo5qOA5p+lXG5mdW5jdGlvbiBmdWxsU3RyYXRlZ3lDaGVjayhcbiAga2V5czogRm9ybWF0S2V5cyxcbiAgY29udHJvbHM6IEFic3RyYWN0Q29udHJvbFtdLFxuICBfOiBGb3JtYXRWYWx1ZSxcbiAgbWFwRm46IFZhbHVlTWFwRm4sXG4gIG1hdGNoZXNGbjogTWF0Y2hWYWx1ZUZuLFxuICBpbml0RGF0YTogYW55W10sXG4pIHtcbiAgY29uc3QgY29udHJvbEVycm9yOiBNYXA8QWJzdHJhY3RDb250cm9sLCB7IGtleTogc3RyaW5nOyBjb3VudDogbnVtYmVyIH0+ID1cbiAgICBuZXcgTWFwKCk7XG5cbiAgT2JqZWN0LmVudHJpZXMoa2V5cykuZm9yRWFjaCgoW2tleSwgcHJvcHNdKSA9PiB7XG4gICAgY29udHJvbHMuZm9yRWFjaChjdHJsID0+IHtcbiAgICAgIGNvbnN0IGNvbnRyb2xWYWx1ZSA9IGdldFZhbHVlSW5LZXlzKGN0cmwudmFsdWUsIGtleXMsIG1hcEZuKTtcbiAgICAgIC8vIOWFqOajgOafpeetlueVpe+8jOacgOe7iOmUmeivryBrZXkg5a+55bqUIGNvdW50IOS4uiAwIOeahGN0cmzkvJrljrvmjonnm7jlupTplJnor69cbiAgICAgIGNvbnRyb2xFcnJvci5zZXQoY3RybCwgeyBrZXksIGNvdW50OiAwIH0pO1xuICAgICAgaW5pdERhdGEuZm9yRWFjaChpbml0Um93ID0+IHtcbiAgICAgICAgaWYgKG1hdGNoVmFsdWUocHJvcHMsIGluaXRSb3dba2V5XSwgY29udHJvbFZhbHVlKSkge1xuICAgICAgICAgIGNvbnN0IHJhd0NvdW50ID0gY29udHJvbEVycm9yLmdldChjdHJsKS5jb3VudDtcbiAgICAgICAgICBjb250cm9sRXJyb3Iuc2V0KGN0cmwsIHsga2V5LCBjb3VudDogcmF3Q291bnQgKyAxIH0pO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIGNvbnRyb2xzXG4gICAgICAgIC5maWx0ZXIob3RoZXJDb250cm9sID0+IG90aGVyQ29udHJvbCAhPT0gY3RybClcbiAgICAgICAgLmZvckVhY2gob3RoZXJDb250cm9sID0+IHtcbiAgICAgICAgICBjb25zdCBvdGhlclZhbHVlID0gZ2V0VmFsdWVJbktleXMob3RoZXJDb250cm9sLnZhbHVlLCBrZXlzLCBtYXBGbik7XG4gICAgICAgICAgaWYgKG1hdGNoZXNGbihwcm9wcywgY29udHJvbFZhbHVlW2tleV0sIG90aGVyVmFsdWVba2V5XSkpIHtcbiAgICAgICAgICAgIGNvbnN0IHJhd0NvdW50ID0gY29udHJvbEVycm9yLmdldChjdHJsKS5jb3VudDtcbiAgICAgICAgICAgIGNvbnRyb2xFcnJvci5zZXQoY3RybCwgeyBrZXksIGNvdW50OiByYXdDb3VudCArIDEgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG4gIGNvbnN0IHRvUmVtb3ZlRXJyb3I6IEFycmF5PHsga2V5OiBzdHJpbmc7IGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCB9PiA9IFtdO1xuICBjb250cm9sRXJyb3IuZm9yRWFjaCgoeyBjb3VudCwga2V5IH0sIGNvbnRyb2wpID0+IHtcbiAgICBpZiAoY291bnQgPT09IDApIHtcbiAgICAgIHRvUmVtb3ZlRXJyb3IucHVzaCh7IGtleSwgY29udHJvbCB9KTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gdG9SZW1vdmVFcnJvcjtcbn1cbiJdfQ==