@linid-dm/directory-manager-client-core
Version:
Core package by providing a set of angular components for the Directory Manager app.
583 lines • 91 kB
JavaScript
/**
* Copyright (C) 2020-2024 Linagora
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version, provided you comply with the Additional Terms applicable for
* LinID Directory Manager software by LINAGORA pursuant to Section 7 of the GNU
* Affero General Public License, subsections (b), (c), and (e), pursuant to
* which these Appropriate Legal Notices must notably (i) retain the display of
* the "LinID™" trademark/logo at the top of the interface window, the display
* of the “You are using the Open Source and free version of LinID™, powered by
* Linagora © 2009–2013. Contribute to LinID R&D by subscribing to an Enterprise
* offer!” infobox and in the e-mails sent with the Program, notice appended to
* any type of outbound messages (e.g. e-mail and meeting requests) as well as
* in the LinID Directory Manager user interface, (ii) retain all hypertext
* links between LinID Directory Manager and https://linid.org/, as well as
* between LINAGORA and LINAGORA.com, and (iii) refrain from infringing LINAGORA
* intellectual property rights over its trademarks and commercial brands. Other
* Additional Terms apply, see <http://www.linagora.com/licenses/> for more
* details.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License and
* its applicable Additional Terms for LinID Directory Manager along with this
* program. If not, see <http://www.gnu.org/licenses/> for the GNU Affero
* General Public License version 3 and <http://www.linagora.com/licenses/> for
* the Additional Terms applicable to the LinID Directory Manager software.
*/
import _ from 'lodash';
import moment from 'moment';
import { EComponentName, } from '../interfaces/data.interface';
import { isArrayOfLinkObjects, isLinkObject } from './data-table.helper';
export function getAdvancedSearchChipsFromFormData(formData) {
let advancedSearchChips = [];
formData
.filter((field) => !!field.dataValue)
.forEach((field) => {
const label = field.value.label.value.short;
const booleanDisplayedValue = field.value?.field.props.displayedValue?.true;
const displayedValue = booleanDisplayedValue ??
(field.dataValue.label || field.dataValue.toString());
let chip = {
modelRef: field.modelRef,
displayedContent: label + ': ' + displayedValue,
value: field.dataValue,
};
if (field.value.field.componentName === EComponentName.select) {
const convertedField = convertSelectOptionForAdvancedSearch(field);
chip = {
...chip,
modelRef: convertedField.modelRef,
associatedFieldId: field.modelRef,
};
}
advancedSearchChips.push(chip);
});
return advancedSearchChips;
}
function convertSelectOptionForAdvancedSearch(field) {
const fieldValue = isLinkObject(field.dataValue)
? field.dataValue.id
: field.dataValue;
const selectedOption = field.value.field.selectOption.props.options.find((option) => getSelectionOptionValue(option).toLocaleUpperCase() ===
fieldValue.toLocaleUpperCase());
return {
...field,
modelRef: selectedOption.attributeId ?? field.modelRef,
};
}
export function getSelectionOptionValue(option) {
return isLinkObject(option.value)
? option.value.id
: option.value;
}
export function setFormFieldDataValue(formData, dataValue, dateDisplayFormat) {
let formDataValue;
if (formData.value.field.componentName === EComponentName.datepicker &&
!!dataValue) {
formDataValue = moment(dataValue, dateDisplayFormat).format('YYYY-MM-DD');
}
else if (formData.value.field.componentName === EComponentName.slideToggle) {
formDataValue = dataValue;
}
else {
formDataValue = dataValue;
}
formData.dataValue = formDataValue;
}
export function getFormFieldError(formFieldControl, attributeConfig) {
let formFieldErrorMessage;
if (formFieldControl && formFieldControl.invalid && formFieldControl.dirty) {
const errorMessages = attributeConfig.value.error.value;
for (const key in formFieldControl.errors) {
formFieldErrorMessage = errorMessages[key];
}
}
return formFieldErrorMessage;
}
export function setDataAttribute(data, attributeConfig, dateDisplayFormat) {
return {
id: attributeConfig.modelRef,
isVisible: attributeConfig.props.isNotVisibleWhenFalse
? data
: attributeConfig.props.isVisible,
isBackendLinkObject: !!attributeConfig.props.isBackendLinkObject
? attributeConfig.props.isBackendLinkObject
: false,
isExternalLink: !!attributeConfig.props.isExternalLink
? attributeConfig.props.isExternalLink
: false,
isMultiple: !!attributeConfig.props.isMultiple
? attributeConfig.props.isMultiple
: false,
icon: attributeConfig.value.icon.value,
componentName: attributeConfig.value.field.componentName,
label: {
long: attributeConfig.value.label.value.long,
short: attributeConfig.value.label.value.short,
},
dataValue: getConvertedDataValue(data, attributeConfig, dateDisplayFormat),
booleanDisplayedValue: getConvertedBooleanToString(data, attributeConfig),
};
}
function getConvertedDataValue(data, attributeConfig, dateDisplayFormat) {
if (Array.isArray(data) &&
!attributeConfig.props.isBackendLinkObject &&
attributeConfig.value.field.componentName === EComponentName.input) {
return data.join(', ');
}
else if (attributeConfig.value.field.componentName === EComponentName.datepicker) {
return moment(data, dateDisplayFormat).format(dateDisplayFormat);
}
else if (attributeConfig.value.field.componentName === EComponentName.slideToggle) {
return convertDataToBoolean(data, attributeConfig.value.field.props?.convertToString, attributeConfig.value.field.props?.displayedValue.false);
}
else {
return data;
}
}
function getConvertedBooleanToString(data, attributeConfig) {
if (attributeConfig.value.field.componentName === EComponentName.slideToggle) {
return convertDataToBoolean(data, attributeConfig.value.field.props?.convertToString, attributeConfig.value.field.props?.displayedValue.false)
? attributeConfig.value.field.props.displayedValue.true
: attributeConfig.value.field.props.displayedValue.false;
}
else
return null;
}
function convertDataToBoolean(data, convertToString, falseConditionValue) {
if (convertToString) {
return data !== falseConditionValue;
}
else {
return data;
}
}
export class FormErrorStateMatcher {
isErrorState(control, _form) {
return control?.invalid && control?.dirty;
}
}
export function concatOldValuesToNewValue(valuesForm, formData, prefix) {
formData.forEach((field) => {
if (valuesForm[field.modelRef] && field.props.isConcatWithPreviousValue) {
const oldValue = field.dataValue;
const newValue = prefix + valuesForm[field.modelRef];
valuesForm[field.modelRef] = concatTextAreaContent(newValue, oldValue);
}
});
return valuesForm;
}
export function concatTextAreaContent(addedText, currentText) {
const addedTextCompressedNewLineEscape = addedText.replace(/\n+/g, '\n');
if (currentText) {
return currentText + '\n\n' + addedTextCompressedNewLineEscape;
}
else {
return addedTextCompressedNewLineEscape;
}
}
export function convertAutocompleteInputValueForRequestBody(checkoutFormValues, autocompleteOptions, formPreviousState, loadedAutocompletesModelRef) {
const autocompleteFieldsModelRefs = Object.keys(autocompleteOptions);
const checkoutFormModelRefs = Object.keys(checkoutFormValues);
return checkoutFormModelRefs.reduce((acc, curr) => ({
...acc,
[curr]: autocompleteFieldsModelRefs.includes(curr) &&
loadedAutocompletesModelRef.includes(curr)
? convertAutocompleteOptionToBodyValue(autocompleteOptions[curr], checkoutFormValues[curr], formPreviousState[curr].value)
: checkoutFormValues[curr],
}), {});
}
function convertAutocompleteOptionToBodyValue(autocompleteOptions, checkoutFormFieldValue, formPreviousStateFieldValue) {
let valueForRequestBody = null;
const allCurrentFieldOptions = autocompleteOptions.map((option) => option.option.toLocaleUpperCase());
if (Array.isArray(formPreviousStateFieldValue)) {
valueForRequestBody = [
...formPreviousStateFieldValue.map((fieldOption) => fieldOption.value),
];
}
else if (!!checkoutFormFieldValue) {
const currentFieldValue = checkoutFormFieldValue;
if (typeof currentFieldValue === 'string') {
if (allCurrentFieldOptions.includes(currentFieldValue.toLocaleUpperCase())) {
valueForRequestBody = convertInputValueToAutocompleteOption(currentFieldValue, autocompleteOptions).value;
}
}
else {
valueForRequestBody = currentFieldValue.value;
}
}
return valueForRequestBody;
}
export function convertInputValueToAutocompleteOption(inputValue, autocompleteOptions) {
return autocompleteOptions.find((option) => option.option.toLocaleUpperCase() === inputValue.toLocaleUpperCase());
}
export function convertBooleanToString(valuesForm, formConfig) {
formConfig.forEach((config) => {
if (config.value.field.props.convertToString &&
Object.prototype.hasOwnProperty.call(valuesForm, config.modelRef)) {
valuesForm = {
...valuesForm,
[config.modelRef]: valuesForm[config.modelRef]
? config.value.field.props.trueConditionValue
: config.value.field.props.falseConditionValue,
};
}
});
return valuesForm;
}
export function convertToScimObject(valuesForm, formConfig, entryId, dataElementExternalId, schemas) {
valuesForm = {
schemas,
id: entryId,
externalId: dataElementExternalId || 'new entry',
...valuesForm,
};
formConfig.forEach((config) => {
if (config.props.scimParentAttribute != null &&
config.modelRef in valuesForm) {
const scimParentId = config.props.scimParentAttribute;
valuesForm = {
...valuesForm,
[scimParentId]: {
...valuesForm[scimParentId],
[config.modelRef]: valuesForm[config.modelRef],
},
};
delete valuesForm[config.modelRef];
}
if (config.props?.isNotVisibleWhenFalse &&
valuesForm[config.modelRef] === false) {
delete valuesForm[config.modelRef];
}
});
return valuesForm;
}
export function formatDatepickerForm(valuesForm, formConfig, dateDisplayFormat) {
formConfig.forEach((config) => {
if (Object.prototype.hasOwnProperty.call(valuesForm, config.modelRef)) {
valuesForm = {
...valuesForm,
[config.modelRef]: config.value.field.componentName === EComponentName.datepicker &&
valuesForm[config.modelRef]
? moment(valuesForm[config.modelRef]).creationData().format ===
'YYYY-MM-DD'
? moment(valuesForm[config.modelRef], 'YYYY-MM-DD').format(dateDisplayFormat)
: moment(valuesForm[config.modelRef], dateDisplayFormat).format(dateDisplayFormat)
: valuesForm[config.modelRef],
};
}
});
return valuesForm;
}
export function getAuthorWithDate(displayName, language) {
moment.locale(language);
return displayName + ', ' + moment().format('LLL');
}
export function getFilteredOptionsOnInitialState(isInputChipsAutocomplete, autoCompleteOptions, formPreviousStateField) {
if (!isInputChipsAutocomplete) {
return autoCompleteOptions;
}
else {
return autoCompleteOptions.filter((option) => formPreviousStateField.every((inputDisplayedValue) => inputDisplayedValue.option
.getRidOfDiacritics()
.toLocaleUpperCase() !==
option.option.getRidOfDiacritics().toLocaleUpperCase()));
}
}
export function getFormAutocompleteFieldInitialValue(fieldValue, currentObject, formInitialStateFieldValue, formPreviousStateFieldValue) {
let isValidOptionValue;
let autocompleteFieldInitialValue;
if (Array.isArray(fieldValue)) {
isValidOptionValue = fieldValue.some((value) => currentObject.value.id.toLocaleUpperCase() ===
value.id.toLocaleUpperCase());
}
else {
isValidOptionValue =
currentObject.value.id.toLocaleUpperCase() ===
fieldValue.id.toLocaleUpperCase();
}
if (isValidOptionValue) {
if (Array.isArray(fieldValue)) {
autocompleteFieldInitialValue = {
controlValue: null,
initialStateValue: [
...formInitialStateFieldValue,
{ ...currentObject },
],
previousStateValue: [
...formPreviousStateFieldValue,
{ ...currentObject },
],
};
}
else {
autocompleteFieldInitialValue = {
controlValue: { ...currentObject },
initialStateValue: { ...currentObject },
previousStateValue: { ...currentObject },
};
}
}
return autocompleteFieldInitialValue;
}
export function getFormErrors(form, formData, formFields) {
const formFieldsCopy = {
...formFields,
};
for (const modelRef in formFieldsCopy) {
if (Object.prototype.hasOwnProperty.call(formFieldsCopy, modelRef)) {
formFieldsCopy[modelRef] = '';
const control = form.get(modelRef);
if (control?.invalid && control?.dirty) {
const field = formData.find((form) => form.modelRef === modelRef);
const currValueError = field
? field.value.error.value
: null;
for (const key in control.errors) {
if (Object.prototype.hasOwnProperty.call(control.errors, key)) {
formFieldsCopy[modelRef] = currValueError[key];
break;
}
}
}
}
}
return formFieldsCopy;
}
export function getLinkedFieldsValues(linkedFieldsModelRefs, formPreviousState) {
return linkedFieldsModelRefs.reduce((acc, modelRef) => {
if (!!formPreviousState[modelRef].value) {
if (isAutocompleteOption(formPreviousState[modelRef].value)) {
acc.push(formPreviousState[modelRef].value.value.id.toLocaleUpperCase());
}
else if (isAutocompleteOptionArray(formPreviousState[modelRef].value)) {
acc.push(...formPreviousState[modelRef].value.map((autocompleteOption) => autocompleteOption.value.id.toLocaleUpperCase()));
}
}
return acc;
}, []);
}
export function isAutocompleteOption(fieldValue) {
return (typeof fieldValue === 'object' &&
Object.keys(fieldValue).length === 2 &&
'value' in fieldValue &&
isLinkObject(fieldValue.value) &&
'option' in fieldValue);
}
export function isAutocompleteOptionArray(fieldValue) {
return (Array.isArray(fieldValue) &&
fieldValue.length > 0 &&
fieldValue.every((value) => isAutocompleteOption(value)));
}
export function getOptionsFilteringCondition(inputValue, isInputChipsAutocomplete, formPreviousStateFieldValue) {
let inputValueAsString = '';
let checkNotBelongToChips = () => true;
let optionMatchInputValue = () => true;
if (isInputChipsAutocomplete) {
checkNotBelongToChips = (valueToCompare) => formPreviousStateFieldValue.every((inputDisplayedValue) => valueToCompare.getRidOfDiacritics().toLocaleUpperCase() !==
inputDisplayedValue.option.getRidOfDiacritics().toLocaleUpperCase());
}
if (inputValue !== null) {
if (typeof inputValue === 'string') {
inputValueAsString = inputValue;
}
else if (!isInputChipsAutocomplete) {
inputValueAsString = inputValue.option;
}
optionMatchInputValue = (valueToCompare) => valueToCompare
.toLocaleUpperCase()
.getRidOfDiacritics()
.includes(inputValueAsString.getRidOfDiacritics().toLocaleUpperCase()) || inputValueAsString === '';
}
return (valueToCompare) => checkNotBelongToChips(valueToCompare) &&
optionMatchInputValue(valueToCompare);
}
export function inputValueIsNotAnOption(filteredOptions, modelRef) {
return (control) => {
if (control.value !== null &&
typeof control.value === 'string' &&
control.value !== '' &&
filteredOptions[modelRef].length === 0) {
return { incorrect: true };
}
else {
return null;
}
};
}
export function inputValueIsNotAnOptionSimpleAutocomplete(filteredOptions, modelRef) {
return (control) => {
if (control.value !== null &&
typeof control.value === 'string' &&
control.value !== '' &&
!filteredOptions[modelRef]
.map((element) => element.option)
.includes(control.value)) {
return { incorrect: true };
}
else {
return null;
}
};
}
export function isAutocompleteInitialState(inputValue, isInputChipsAutocomplete, formPreviousStateField, formInitialStateField) {
if (isInputChipsAutocomplete) {
return (JSON.stringify(formPreviousStateField) ===
JSON.stringify(formInitialStateField) &&
(inputValue === null || inputValue === undefined || inputValue === ''));
}
else {
return Array.isArray(inputValue)
? JSON.stringify(inputValue) === JSON.stringify(formInitialStateField)
: inputValue === formInitialStateField;
}
}
export function isFormFieldDisabled(checkedField, crudAction = null) {
return (checkedField.value.field.props.disabled &&
!(crudAction === 'search' && checkedField.props.isSearchable));
}
export function isFormFieldDisplayed(field, crudAction) {
return (field.value.field.componentName !== EComponentName.array &&
(!field.value.field.props.disabled ||
(crudAction === 'search' && field.props.isSearchable)));
}
export function keepFieldInRequestBody(fieldComponentName, fieldValue, initialValue, autocompleteOptionsLoaded, crudAction) {
if (crudAction === 'search') {
return true;
}
let hasValueChanged = false;
switch (fieldComponentName) {
case EComponentName.inputChipsAutocomplete:
hasValueChanged = hasInputChipsValueChanged(fieldValue, autocompleteOptionsLoaded, initialValue);
break;
case EComponentName.autocomplete:
hasValueChanged = hasAutocompleteValueChanged(fieldValue, autocompleteOptionsLoaded, initialValue);
break;
default:
hasValueChanged = fieldValue !== initialValue.value;
break;
}
return hasValueChanged;
}
function hasInputChipsValueChanged(inputChipsFieldValue, autocompleteOptionsLoaded, initialValue) {
let hasChanged = false;
if (inputChipsFieldValue != null && initialValue?.value != null) {
const chipsIds = inputChipsFieldValue.map((link) => link.id);
const initialChipsIds = autocompleteOptionsLoaded
? initialValue.value.map((option) => option.value.id)
: initialValue.value;
hasChanged = _.xor(chipsIds, initialChipsIds).length > 0;
}
return hasChanged;
}
function hasAutocompleteValueChanged(autocompleteFieldValue, autocompleteOptionsLoaded, initialValue) {
let hasChanged;
if (autocompleteFieldValue != null && initialValue?.value != null) {
hasChanged =
(autocompleteOptionsLoaded &&
autocompleteFieldValue.id !==
initialValue.value.value.id) ||
(!autocompleteOptionsLoaded &&
autocompleteFieldValue.id !== initialValue.value);
}
else {
hasChanged =
(autocompleteFieldValue == null && initialValue?.value != null) ||
(autocompleteFieldValue != null && initialValue?.value == null);
}
return hasChanged;
}
export function resizeImage(width, height, maxWidth, maxHeight) {
if (width > maxWidth && height <= maxHeight) {
height *= maxWidth / width;
width = maxWidth;
}
else if (width <= maxWidth && height > maxHeight) {
width *= maxHeight / height;
height = maxHeight;
}
else if (width > maxWidth && height > maxHeight) {
const minRatio = Math.min(maxWidth / width, maxHeight / height);
width *= minRatio;
height *= minRatio;
}
return { width, height };
}
export function saveCheckoutFormState(checkoutFormValues, formData, crudAction) {
let formState = {};
for (const modelRef in checkoutFormValues) {
if (Object.prototype.hasOwnProperty.call(checkoutFormValues, modelRef)) {
const currentFormField = formData.find((field) => field.modelRef === modelRef);
let enabled = null;
let value;
if (Array.isArray(checkoutFormValues[modelRef]) &&
currentFormField.value.field.componentName ===
EComponentName.inputChipsAutocomplete) {
if (checkoutFormValues[modelRef] &&
isArrayOfLinkObjects(checkoutFormValues[modelRef])) {
value = checkoutFormValues[modelRef].map((link) => link.id);
enabled = false;
}
}
else {
if (Array.isArray(checkoutFormValues[modelRef])) {
value = [...checkoutFormValues[modelRef]];
}
else if (checkoutFormValues[modelRef] &&
isLinkObject(checkoutFormValues[modelRef])) {
value = checkoutFormValues[modelRef].id;
enabled = false;
}
else {
value = checkoutFormValues[modelRef];
}
}
if (enabled !== null) {
enabled = !isFormFieldDisabled(currentFormField, crudAction);
}
formState = {
...formState,
[modelRef]: {
value,
enabled,
},
};
}
}
return formState;
}
export function setFormControlValue(field) {
if (Array.isArray(field.dataValue)) {
return [...field.dataValue];
}
else if (field.props.isConcatWithPreviousValue) {
return '';
}
else {
return field.dataValue;
}
}
export function trimFormFieldsValues(formFieldsValues) {
return Object.keys(formFieldsValues).reduce((acc, curr) => {
const isString = typeof formFieldsValues[curr] === 'string';
const isStringArray = Array.isArray(formFieldsValues[curr]) &&
formFieldsValues[curr]?.length > 0 &&
typeof formFieldsValues[curr][0] === 'string';
let fieldValue = formFieldsValues[curr];
if (isString) {
fieldValue = fieldValue.trim();
}
else if (isStringArray) {
fieldValue = fieldValue.map((s) => s.trim());
}
return { ...acc, [curr]: fieldValue };
}, {});
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9ybS5oZWxwZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9saWJzL2NsaWVudC1jb3JlL3NyYy9saWIvc2hhcmVkL2hlbHBlcnMvZm9ybS5oZWxwZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBZ0NHO0FBV0gsT0FBTyxDQUFDLE1BQU0sUUFBUSxDQUFDO0FBQ3ZCLE9BQU8sTUFBTSxNQUFNLFFBQVEsQ0FBQztBQUU1QixPQUFPLEVBQ0wsY0FBYyxHQU1mLE1BQU0sOEJBQThCLENBQUM7QUFVdEMsT0FBTyxFQUFFLG9CQUFvQixFQUFFLFlBQVksRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRXpFLE1BQU0sVUFBVSxrQ0FBa0MsQ0FDaEQsUUFBcUI7SUFFckIsSUFBSSxtQkFBbUIsR0FBMEIsRUFBRSxDQUFDO0lBQ3BELFFBQVE7U0FDTCxNQUFNLENBQUMsQ0FBQyxLQUFnQixFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQztTQUMvQyxPQUFPLENBQUMsQ0FBQyxLQUFnQixFQUFFLEVBQUU7UUFDNUIsTUFBTSxLQUFLLEdBQVcsS0FBSyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQztRQUNwRCxNQUFNLHFCQUFxQixHQUN6QixLQUFLLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxLQUFLLENBQUMsY0FBYyxFQUFFLElBQUksQ0FBQztRQUNoRCxNQUFNLGNBQWMsR0FDbEIscUJBQXFCO1lBQ3JCLENBQUUsS0FBSyxDQUFDLFNBQW1CLENBQUMsS0FBSyxJQUFJLEtBQUssQ0FBQyxTQUFTLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQztRQUVuRSxJQUFJLElBQUksR0FBd0I7WUFDOUIsUUFBUSxFQUFFLEtBQUssQ0FBQyxRQUFRO1lBQ3hCLGdCQUFnQixF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QUFDLENBQUMsS0FBSyxRQUFRLENBQUM7UUFDaEQsSUFBSSxVQUFVLEdBQXVCLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzVELElBQUksUUFBUSxFQUFFLENBQUM7WUFDYixVQUFVLEdBQUksVUFBcUIsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUM3QyxDQUFDO2FBQU0sSUFBSSxhQUFhLEVBQUUsQ0FBQztZQUN6QixVQUFVLEdBQUksVUFBdUIsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFTLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQ3JFLENBQUM7UUFDRCxPQUFPLEVBQUUsR0FBRyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxVQUFVLEVBQUUsQ0FBQztJQUN4QyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDVCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDb3B5cmlnaHQgKEMpIDIwMjAtMjAyNCBMaW5hZ29yYVxuICpcbiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0IHVuZGVyXG4gKiB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWVcbiAqIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55XG4gKiBsYXRlciB2ZXJzaW9uLCBwcm92aWRlZCB5b3UgY29tcGx5IHdpdGggdGhlIEFkZGl0aW9uYWwgVGVybXMgYXBwbGljYWJsZSBmb3JcbiAqIExpbklEIERpcmVjdG9yeSBNYW5hZ2VyIHNvZnR3YXJlIGJ5IExJTkFHT1JBIHB1cnN1YW50IHRvIFNlY3Rpb24gNyBvZiB0aGUgR05VXG4gKiBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwgc3Vic2VjdGlvbnMgKGIpLCAoYyksIGFuZCAoZSksIHB1cnN1YW50IHRvXG4gKiB3aGljaCB0aGVzZSBBcHByb3ByaWF0ZSBMZWdhbCBOb3RpY2VzIG11c3Qgbm90YWJseSAoaSkgcmV0YWluIHRoZSBkaXNwbGF5IG9mXG4gKiB0aGUgXCJMaW5JROKEolwiIHRyYWRlbWFyay9sb2dvIGF0IHRoZSB0b3Agb2YgdGhlIGludGVyZmFjZSB3aW5kb3csIHRoZSBkaXNwbGF5XG4gKiBvZiB0aGUg4oCcWW91IGFyZSB1c2luZyB0aGUgT3BlbiBTb3VyY2UgYW5kIGZyZWUgdmVyc2lvbiBvZiBMaW5JROKEoiwgcG93ZXJlZCBieVxuICogTGluYWdvcmEgwqkgMjAwOeKAkzIwMTMuIENvbnRyaWJ1dGUgdG8gTGluSUQgUiZEIGJ5IHN1YnNjcmliaW5nIHRvIGFuIEVudGVycHJpc2VcbiAqIG9mZmVyIeKAnSBpbmZvYm94IGFuZCBpbiB0aGUgZS1tYWlscyBzZW50IHdpdGggdGhlIFByb2dyYW0sIG5vdGljZSBhcHBlbmRlZCB0b1xuICogYW55IHR5cGUgb2Ygb3V0Ym91bmQgbWVzc2FnZXMgKGUuZy4gZS1tYWlsIGFuZCBtZWV0aW5nIHJlcXVlc3RzKSBhcyB3ZWxsIGFzXG4gKiBpbiB0aGUgTGluSUQgRGlyZWN0b3J5IE1hbmFnZXIgdXNlciBpbnRlcmZhY2UsIChpaSkgcmV0YWluIGFsbCBoeXBlcnRleHRcbiAqIGxpbmtzIGJldHdlZW4gTGluSUQgRGlyZWN0b3J5IE1hbmFnZXIgYW5kIGh0dHBzOi8vbGluaWQub3JnLywgYXMgd2VsbCBhc1xuICogYmV0d2VlbiBMSU5BR09SQSBhbmQgTElOQUdPUkEuY29tLCBhbmQgKGlpaSkgcmVmcmFpbiBmcm9tIGluZnJpbmdpbmcgTElOQUdPUkFcbiAqIGludGVsbGVjdHVhbCBwcm9wZXJ0eSByaWdodHMgb3ZlciBpdHMgdHJhZGVtYXJrcyBhbmQgY29tbWVyY2lhbCBicmFuZHMuIE90aGVyXG4gKiBBZGRpdGlvbmFsIFRlcm1zIGFwcGx5LCBzZWUgPGh0dHA6Ly93d3cubGluYWdvcmEuY29tL2xpY2Vuc2VzLz4gZm9yIG1vcmVcbiAqIGRldGFpbHMuXG4gKlxuICogVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUXG4gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTU1xuICogRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiBTZWUgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZVxuICogZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYW5kXG4gKiBpdHMgYXBwbGljYWJsZSBBZGRpdGlvbmFsIFRlcm1zIGZvciBMaW5JRCBEaXJlY3RvcnkgTWFuYWdlciBhbG9uZyB3aXRoIHRoaXNcbiAqIHByb2dyYW0uIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPiBmb3IgdGhlIEdOVSBBZmZlcm9cbiAqIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAzIGFuZCA8aHR0cDovL3d3dy5saW5hZ29yYS5jb20vbGljZW5zZXMvPiBmb3JcbiAqIHRoZSBBZGRpdGlvbmFsIFRlcm1zIGFwcGxpY2FibGUgdG8gdGhlIExpbklEIERpcmVjdG9yeSBNYW5hZ2VyIHNvZnR3YXJlLlxuICovXG5cbmltcG9ydCB7XG4gIEFic3RyYWN0Q29udHJvbCxcbiAgRm9ybUdyb3VwLFxuICBGb3JtR3JvdXBEaXJlY3RpdmUsXG4gIE5nRm9ybSxcbiAgVmFsaWRhdGlvbkVycm9ycyxcbiAgVmFsaWRhdG9yRm4sXG59IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IEVycm9yU3RhdGVNYXRjaGVyIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvY29yZSc7XG5pbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IG1vbWVudCBmcm9tICdtb21lbnQnO1xuaW1wb3J0IHsgSUF0dHJpYnV0ZSB9IGZyb20gJy4uL2ludGVyZmFjZXMvY29uZmlncy5pbnRlcmZhY2UnO1xuaW1wb3J0IHtcbiAgRUNvbXBvbmVudE5hbWUsXG4gIEZvcm1EYXRhVmFsdWVUeXBlcyxcbiAgSURhdGFEZXRhaWwsXG4gIElEYXRhRGV0YWlsUmVzb3VyY2UsXG4gIElGb3JtRGF0YSxcbiAgSUxpbmssXG59IGZyb20gJy4uL2ludGVyZmFjZXMvZGF0YS5pbnRlcmZhY2UnO1xuaW1wb3J0IHtcbiAgRm9ybUZpZWxkc0FsbFR5cGVzLFxuICBGb3JtRmllbGRzRXh0ZW5kZWRTaW5nbGVUeXBlcyxcbiAgSUF1dG9jb21wbGV0ZU9wdGlvbixcbiAgSUZvcm1GaWVsZENvbnRyb2wsXG4gIElJbml0Rm9ybXNBdXRvY29tcGxldGVGaWVsZCxcbiAgSVNlbGVjdE9wdGlvbixcbn0gZnJvbSAnLi4vaW50ZXJmYWNlcy9mb3JtLmludGVyZmFjZSc7XG5pbXBvcnQgeyBJQWR2YW5jZWRTZWFyY2hDaGlwIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy91aS5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgaXNBcnJheU9mTGlua09iamVjdHMsIGlzTGlua09iamVjdCB9IGZyb20gJy4vZGF0YS10YWJsZS5oZWxwZXInO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0QWR2YW5jZWRTZWFyY2hDaGlwc0Zyb21Gb3JtRGF0YShcbiAgZm9ybURhdGE6IElGb3JtRGF0YVtdXG4pOiBJQWR2YW5jZWRTZWFyY2hDaGlwW10ge1xuICBsZXQgYWR2YW5jZWRTZWFyY2hDaGlwczogSUFkdmFuY2VkU2VhcmNoQ2hpcFtdID0gW107XG4gIGZvcm1EYXRhXG4gICAgLmZpbHRlcigoZmllbGQ6IElGb3JtRGF0YSkgPT4gISFmaWVsZC5kYXRhVmFsdWUpXG4gICAgLmZvckVhY2goKGZpZWxkOiBJRm9ybURhdGEpID0+IHtcbiAgICAgIGNvbnN0IGxhYmVsOiBzdHJpbmcgPSBmaWVsZC52YWx1ZS5sYWJlbC52YWx1ZS5zaG9ydDtcbiAgICAgIGNvbnN0IGJvb2xlYW5EaXNwbGF5ZWRWYWx1ZTogc3RyaW5nID1cbiAgICAgICAgZmllbGQudmFsdWU/LmZpZWxkLnByb3BzLmRpc3BsYXllZFZhbHVlPy50cnVlO1xuICAgICAgY29uc3QgZGlzcGxheWVkVmFsdWU6IHN0cmluZyA9XG4gICAgICAgIGJvb2xlYW5EaXNwbGF5ZWRWYWx1ZSA/P1xuICAgICAgICAoKGZpZWxkLmRhdGFWYWx1ZSBhcyBJTGluaykubGFiZWwgfHwgZmllbGQuZGF0YVZhbHVlLnRvU3RyaW5nKCkpO1xuXG4gICAgICBsZXQgY2hpcDogSUFkdmFuY2VkU2VhcmNoQ2hpcCA9IHtcbiAgICAgICAgbW9kZWxSZWY6IGZpZWxkLm1vZGVsUmVmLFxuICAgICAgICBkaXNwbGF5ZWRDb250ZW50OiBsYWJlbCArICc6ICcgKyBkaXNwbGF5ZWRWYWx1ZSxcbiAgICAgICAgdmFsdWU6IGZpZWxkLmRhdGFWYWx1ZSBhcyBzdHJpbmcgfCBib29sZWFuIHwgSUxpbmssXG4gICAgICB9O1xuICAgICAgaWYgKGZpZWxkLnZhbHVlLmZpZWxkLmNvbXBvbmVudE5hbWUgPT09IEVDb21wb25lbnROYW1lLnNlbGVjdCkge1xuICAgICAgICBjb25zdCBjb252ZXJ0ZWRGaWVsZDogSUZvcm1EYXRhID1cbiAgICAgICAgICBjb252ZXJ0U2VsZWN0T3B0aW9uRm9yQWR2YW5jZWRTZWFyY2goZmllbGQpO1xuICAgICAgICBjaGlwID0ge1xuICAgICAgICAgIC4uLmNoaXAsXG4gICAgICAgICAgbW9kZWxSZWY6IGNvbnZlcnRlZEZpZWxkLm1vZGVsUmVmLFxuICAgICAgICAgIGFzc29jaWF0ZWRGaWVsZElkOiBmaWVsZC5tb2RlbFJlZixcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIGFkdmFuY2VkU2VhcmNoQ2hpcHMucHVzaChjaGlwKTtcbiAgICB9KTtcbiAgcmV0dXJuIGFkdmFuY2VkU2VhcmNoQ2hpcHM7XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRTZWxlY3RPcHRpb25Gb3JBZHZhbmNlZFNlYXJjaChmaWVsZDogSUZvcm1EYXRhKTogSUZvcm1EYXRhIHtcbiAgY29uc3QgZmllbGRWYWx1ZTogc3RyaW5nID0gaXNMaW5rT2JqZWN0KGZpZWxkLmRhdGFWYWx1ZSlcbiAgICA/IChmaWVsZC5kYXRhVmFsdWUgYXMgSUxpbmspLmlkXG4gICAgOiAoZmllbGQuZGF0YVZhbHVlIGFzIHN0cmluZyk7XG4gIGNvbnN0IHNlbGVjdGVkT3B0aW9uOiBJU2VsZWN0T3B0aW9uID1cbiAgICBmaWVsZC52YWx1ZS5maWVsZC5zZWxlY3RPcHRpb24ucHJvcHMub3B0aW9ucy5maW5kKFxuICAgICAgKG9wdGlvbjogSVNlbGVjdE9wdGlvbikgPT5cbiAgICAgICAgZ2V0U2VsZWN0aW9uT3B0aW9uVmFsdWUob3B0aW9uKS50b0xvY2FsZVVwcGVyQ2FzZSgpID09PVxuICAgICAgICBmaWVsZFZhbHVlLnRvTG9jYWxlVXBwZXJDYXNlKClcbiAgICApO1xuICByZXR1cm4ge1xuICAgIC4uLmZpZWxkLFxuICAgIG1vZGVsUmVmOiBzZWxlY3RlZE9wdGlvbi5hdHRyaWJ1dGVJZCA/PyBmaWVsZC5tb2RlbFJlZixcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFNlbGVjdGlvbk9wdGlvblZhbHVlKG9wdGlvbjogSVNlbGVjdE9wdGlvbik6IHN0cmluZyB7XG4gIHJldHVybiBpc0xpbmtPYmplY3Qob3B0aW9uLnZhbHVlKVxuICAgID8gKG9wdGlvbi52YWx1ZSBhcyBJTGluaykuaWRcbiAgICA6IChvcHRpb24udmFsdWUgYXMgc3RyaW5nKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNldEZvcm1GaWVsZERhdGFWYWx1ZShcbiAgZm9ybURhdGE6IElGb3JtRGF0YSxcbiAgZGF0YVZhbHVlOiBGb3JtRGF0YVZhbHVlVHlwZXMsXG4gIGRhdGVEaXNwbGF5Rm9ybWF0OiBzdHJpbmdcbik6IHZvaWQge1xuICBsZXQgZm9ybURhdGFWYWx1ZTogRm9ybURhdGFWYWx1ZVR5cGVzO1xuICBpZiAoXG4gICAgZm9ybURhdGEudmFsdWUuZmllbGQuY29tcG9uZW50TmFtZSA9PT0gRUNvbXBvbmVudE5hbWUuZGF0ZXBpY2tlciAmJlxuICAgICEhZGF0YVZhbHVlXG4gICkge1xuICAgIGZvcm1EYXRhVmFsdWUgPSBtb21lbnQoZGF0YVZhbHVlIGFzIHN0cmluZywgZGF0ZURpc3BsYXlGb3JtYXQpLmZvcm1hdChcbiAgICAgICdZWVlZLU1NLUREJ1xuICAgICk7XG4gIH0gZWxzZSBpZiAoXG4gICAgZm9ybURhdGEudmFsdWUuZmllbGQuY29tcG9uZW50TmFtZSA9PT0gRUNvbXBvbmVudE5hbWUuc2xpZGVUb2dnbGVcbiAgKSB7XG4gICAgZm9ybURhdGFWYWx1ZSA9IGRhdGFWYWx1ZSBhcyBib29sZWFuO1xuICB9IGVsc2Uge1xuICAgIGZvcm1EYXRhVmFsdWUgPSBkYXRhVmFsdWUgYXMgc3RyaW5nIHwgYm9vbGVhbiB8IElMaW5rIHwgSUxpbmtbXTtcbiAgfVxuXG4gIGZvcm1EYXRhLmRhdGFWYWx1ZSA9IGZvcm1EYXRhVmFsdWU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRGb3JtRmllbGRFcnJvcihcbiAgZm9ybUZpZWxkQ29udHJvbDogQWJzdHJhY3RDb250cm9sLFxuICBhdHRyaWJ1dGVDb25maWc6IElBdHRyaWJ1dGVcbik6IHN0cmluZyB7XG4gIGxldCBmb3JtRmllbGRFcnJvck1lc3NhZ2U6IHN0cmluZztcbiAgaWYgKGZvcm1GaWVsZENvbnRyb2wgJiYgZm9ybUZpZWxkQ29udHJvbC5pbnZhbGlkICYmIGZvcm1GaWVsZENvbnRyb2wuZGlydHkpIHtcbiAgICBjb25zdCBlcnJvck1lc3NhZ2VzOiB7IFtlcnJvcklkOiBzdHJpbmddOiBzdHJpbmcgfSA9XG4gICAgICBhdHRyaWJ1dGVDb25maWcudmFsdWUuZXJyb3IudmFsdWU7XG4gICAgZm9yIChjb25zdCBrZXkgaW4gZm9ybUZpZWxkQ29udHJvbC5lcnJvcnMpIHtcbiAgICAgIGZvcm1GaWVsZEVycm9yTWVzc2FnZSA9IGVycm9yTWVzc2FnZXNba2V5XTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZvcm1GaWVsZEVycm9yTWVzc2FnZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNldERhdGFBdHRyaWJ1dGUoXG4gIGRhdGE6XG4gICAgfCBzdHJpbmdcbiAgICB8IHN0cmluZ1tdXG4gICAgfCBib29sZWFuXG4gICAgfCBJRGF0YURldGFpbFJlc291cmNlXG4gICAgfCBJRGF0YURldGFpbFJlc291cmNlW10sXG4gIGF0dHJpYnV0ZUNvbmZpZzogSUF0dHJpYnV0ZSxcbiAgZGF0ZURpc3BsYXlGb3JtYXQ6IHN0cmluZ1xuKTogSURhdGFEZXRhaWwge1xuICByZXR1cm4ge1xuICAgIGlkOiBhdHRyaWJ1dGVDb25maWcubW9kZWxSZWYsXG4gICAgaXNWaXNpYmxlOiBhdHRyaWJ1dGVDb25maWcucHJvcHMuaXNOb3RWaXNpYmxlV2hlbkZhbHNlXG4gICAgICA/IChkYXRhIGFzIGJvb2xlYW4pXG4gICAgICA6IGF0dHJpYnV0ZUNvbmZpZy5wcm9wcy5pc1Zpc2libGUsXG4gICAgaXNCYWNrZW5kTGlua09iamVjdDogISFhdHRyaWJ1dGVDb25maWcucHJvcHMuaXNCYWNrZW5kTGlua09iamVjdFxuICAgICAgPyBhdHRyaWJ1dGVDb25maWcucHJvcHMuaXNCYWNrZW5kTGlua09iamVjdFxuICAgICAgOiBmYWxzZSxcbiAgICBpc0V4dGVybmFsTGluazogISFhdHRyaWJ1dGVDb25maWcucHJvcHMuaXNFeHRlcm5hbExpbmtcbiAgICAgID8gYXR0cmlidXRlQ29uZmlnLnByb3BzLmlzRXh0ZXJuYWxMaW5rXG4gICAgICA6IGZhbHNlLFxuICAgIGlzTXVsdGlwbGU6ICEhYXR0cmlidXRlQ29uZmlnLnByb3BzLmlzTXVsdGlwbGVcbiAgICAgID8gYXR0cmlidXRlQ29uZmlnLnByb3BzLmlzTXVsdGlwbGVcbiAgICAgIDogZmFsc2UsXG4gICAgaWNvbjogYXR0cmlidXRlQ29uZmlnLnZhbHVlLmljb24udmFsdWUsXG4gICAgY29tcG9uZW50TmFtZTogYXR0cmlidXRlQ29uZmlnLnZhbHVlLmZpZWxkLmNvbXBvbmVudE5hbWUsXG4gICAgbGFiZWw6IHtcbiAgICAgIGxvbmc6IGF0dHJpYnV0ZUNvbmZpZy52YWx1ZS5sYWJlbC52YWx1ZS5sb25nLFxuICAgICAgc2hvcnQ6IGF0dHJpYnV0ZUNvbmZpZy52YWx1ZS5sYWJlbC52YWx1ZS5zaG9ydCxcbiAgICB9LFxuICAgIGRhdGFWYWx1ZTogZ2V0Q29udmVydGVkRGF0YVZhbHVlKGRhdGEsIGF0dHJpYnV0ZUNvbmZpZywgZGF0ZURpc3BsYXlGb3JtYXQpLFxuICAgIGJvb2xlYW5EaXNwbGF5ZWRWYWx1ZTogZ2V0Q29udmVydGVkQm9vbGVhblRvU3RyaW5nKGRhdGEsIGF0dHJpYnV0ZUNvbmZpZyksXG4gIH07XG59XG5cbmZ1bmN0aW9uIGdldENvbnZlcnRlZERhdGFWYWx1ZShcbiAgZGF0YTpcbiAgICB8IHN0cmluZ1xuICAgIHwgc3RyaW5nW11cbiAgICB8IGJvb2xlYW5cbiAgICB8IElEYXRhRGV0YWlsUmVzb3VyY2VcbiAgICB8IElEYXRhRGV0YWlsUmVzb3VyY2VbXSxcbiAgYXR0cmlidXRlQ29uZmlnOiBJQXR0cmlidXRlLFxuICBkYXRlRGlzcGxheUZvcm1hdDogc3RyaW5nXG4pOiBzdHJpbmcgfCBzdHJpbmdbXSB8IGJvb2xlYW4gfCBJRGF0YURldGFpbFJlc291cmNlIHwgSURhdGFEZXRhaWxSZXNvdXJjZVtdIHtcbiAgaWYgKFxuICAgIEFycmF5LmlzQXJyYXkoZGF0YSkgJiZcbiAgICAhYXR0cmlidXRlQ29uZmlnLnByb3BzLmlzQmFja2VuZExpbmtPYmplY3QgJiZcbiAgICBhdHRyaWJ1dGVDb25maWcudmFsdWUuZmllbGQuY29tcG9uZW50TmFtZSA9PT0gRUNvbXBvbmVudE5hbWUuaW5wdXRcbiAgKSB7XG4gICAgcmV0dXJuIChkYXRhIGFzIHN0cmluZ1tdKS5qb2luKCcsICcpO1xuICB9IGVsc2UgaWYgKFxuICAgIGF0dHJpYnV0ZUNvbmZpZy52YWx1ZS5maWVsZC5jb21wb25lbnROYW1lID09PSBFQ29tcG9uZW50TmFtZS5kYXRlcGlja2VyXG4gICkge1xuICAgIHJldHVybiBtb21lbnQoZGF0YSBhcyBzdHJpbmcsIGRhdGVEaXNwbGF5Rm9ybWF0KS5mb3JtYXQoZGF0ZURpc3BsYXlGb3JtYXQpO1xuICB9IGVsc2UgaWYgKFxuICAgIGF0dHJpYnV0ZUNvbmZpZy52YWx1ZS5maWVsZC5jb21wb25lbnROYW1lID09PSBFQ29tcG9uZW50TmFtZS5zbGlkZVRvZ2dsZVxuICApIHtcbiAgICByZXR1cm4gY29udmVydERhdGFUb0Jvb2xlYW4oXG4gICAgICBkYXRhLFxuICAgICAgYXR0cmlidXRlQ29uZmlnLnZhbHVlLmZpZWxkLnByb3BzPy5jb252ZXJ0VG9TdHJpbmcsXG4gICAgICBhdHRyaWJ1dGVDb25maWcudmFsdWUuZmllbGQucHJvcHM/LmRpc3BsYXllZFZhbHVlLmZhbHNlXG4gICAgKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gZGF0YTtcbiAgfVxufVxuXG5mdW5jdGlvbiBnZXRDb252ZXJ0ZWRCb29sZWFuVG9TdHJpbmcoXG4gIGRhdGE6XG4gICAgfCBzdHJpbmdcbiAgICB8IHN0cmluZ1tdXG4gICAgfCBib29sZWFuXG4gICAgfCBJRGF0YURldGFpbFJlc291cmNlXG4gICAgfCBJRGF0YURldGFpbFJlc291cmNlW10sXG4gIGF0dHJpYnV0ZUNvbmZpZzogSUF0dHJpYnV0ZVxuKTogc3RyaW5nIHtcbiAgaWYgKFxuICAgIGF0dHJpYnV0ZUNvbmZpZy52YWx1ZS5maWVsZC5jb21wb25lbnROYW1lID09PSBFQ29tcG9uZW50TmFtZS5zbGlkZVRvZ2dsZVxuICApIHtcbiAgICByZXR1cm4gY29udmVydERhdGFUb0Jvb2xlYW4oXG4gICAgICBkYXRhLFxuICAgICAgYXR0cmlidXRlQ29uZmlnLnZhbHVlLmZpZWxkLnByb3BzPy5jb252ZXJ0VG9TdHJpbmcsXG4gICAgICBhdHRyaWJ1dGVDb25maWcudmFsdWUuZmllbGQucHJvcHM/LmRpc3BsYXllZFZhbHVlLmZhbHNlXG4gICAgKVxuICAgICAgPyBhdHRyaWJ1dGVDb25maWcudmFsdWUuZmllbGQucHJvcHMuZGlzcGxheWVkVmFsdWUudHJ1ZVxuICAgICAgOiBhdHRyaWJ1dGVDb25maWcudmFsdWUuZmllbGQucHJvcHMuZGlzcGxheWVkVmFsdWUuZmFsc2U7XG4gIH0gZWxzZSByZXR1cm4gbnVsbDtcbn1cblxuZnVuY3Rpb24gY29udmVydERhdGFUb0Jvb2xlYW4oXG4gIGRhdGE6IGFueSxcbiAgY29udmVydFRvU3RyaW5nOiBib29sZWFuLFxuICBmYWxzZUNvbmRpdGlvblZhbHVlOiBzdHJpbmdcbik6IGJvb2xlYW4ge1xuICBpZiAoY29udmVydFRvU3RyaW5nKSB7XG4gICAgcmV0dXJuIGRhdGEgIT09IGZhbHNlQ29uZGl0aW9uVmFsdWU7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGRhdGE7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIEZvcm1FcnJvclN0YXRlTWF0Y2hlciBpbXBsZW1lbnRzIEVycm9yU3RhdGVNYXRjaGVyIHtcbiAgaXNFcnJvclN0YXRlKFxuICAgIGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCB8IG51bGwsXG4gICAgX2Zvcm06IEZvcm1Hcm91cERpcmVjdGl2ZSB8IE5nRm9ybSB8IG51bGxcbiAgKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGNvbnRyb2w/LmludmFsaWQgJiYgY29udHJvbD8uZGlydHk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNvbmNhdE9sZFZhbHVlc1RvTmV3VmFsdWUoXG4gIHZhbHVlc0Zvcm06IGFueSxcbiAgZm9ybURhdGE6IElGb3JtRGF0YVtdLFxuICBwcmVmaXg/OiBzdHJpbmdcbik6IGFueSB7XG4gIGZvcm1EYXRhLmZvckVhY2goKGZpZWxkOiBJRm9ybURhdGEpID0+IHtcbiAgICBpZiAodmFsdWVzRm9ybVtmaWVsZC5tb2RlbFJlZl0gJiYgZmllbGQucHJvcHMuaXNDb25jYXRXaXRoUHJldmlvdXNWYWx1ZSkge1xuICAgICAgY29uc3Qgb2xkVmFsdWU6IHN0cmluZyA9IGZpZWxkLmRhdGFWYWx1ZSBhcyBzdHJpbmc7XG4gICAgICBjb25zdCBuZXdWYWx1ZTogc3RyaW5nID0gcHJlZml4ICsgdmFsdWVzRm9ybVtmaWVsZC5tb2RlbFJlZl07XG4gICAgICB2YWx1ZXNGb3JtW2ZpZWxkLm1vZGVsUmVmXSA9IGNvbmNhdFRleHRBcmVhQ29udGVudChuZXdWYWx1ZSwgb2xkVmFsdWUpO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiB2YWx1ZXNGb3JtO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY29uY2F0VGV4dEFyZWFDb250ZW50KFxuICBhZGRlZFRleHQ6IHN0cmluZyxcbiAgY3VycmVudFRleHQ/OiBzdHJpbmdcbik6IHN0cmluZyB7XG4gIGNvbnN0IGFkZGVkVGV4dENvbXByZXNzZWROZXdMaW5lRXNjYXBlOiBzdHJpbmcgPSBhZGRlZFRleHQucmVwbGFjZShcbiAgICAvXFxuKy9nLFxuICAgICdcXG4nXG4gICk7XG4gIGlmIChjdXJyZW50VGV4dCkge1xuICAgIHJldHVybiBjdXJyZW50VGV4dCArICdcXG5cXG4nICsgYWRkZWRUZXh0Q29tcHJlc3NlZE5ld0xpbmVFc2NhcGU7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGFkZGVkVGV4dENvbXByZXNzZWROZXdMaW5lRXNjYXBlO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjb252ZXJ0QXV0b2NvbXBsZXRlSW5wdXRWYWx1ZUZvclJlcXVlc3RCb2R5KFxuICBjaGVja291dEZvcm1WYWx1ZXM6IHtcbiAgICBbaWQ6IHN0cmluZ106IEZvcm1GaWVsZHNFeHRlbmRlZFNpbmdsZVR5cGVzO1xuICB9LFxuICBhdXRvY29tcGxldGVPcHRpb25zOiB7XG4gICAgW21vZGVsUmVmOiBzdHJpbmddOiBJQXV0b2NvbXBsZXRlT3B0aW9uW107XG4gIH0sXG4gIGZvcm1QcmV2aW91c1N0YXRlOiB7XG4gICAgW2tleTogc3RyaW5nXTogSUZvcm1GaWVsZENvbnRyb2w7XG4gIH0sXG4gIGxvYWRlZEF1dG9jb21wbGV0ZXNNb2RlbFJlZjogc3RyaW5nW11cbik6IHtcbiAgW2lkOiBzdHJpbmddOiBGb3JtRGF0YVZhbHVlVHlwZXM7XG59IHtcbiAgY29uc3QgYXV0b2NvbXBsZXRlRmllbGRzTW9kZWxSZWZzOiBzdHJpbmdbXSA9XG4gICAgT2JqZWN0LmtleXMoYXV0b2NvbXBsZXRlT3B0aW9ucyk7XG4gIGNvbnN0IGNoZWNrb3V0Rm9ybU1vZGVsUmVmczogc3RyaW5nW10gPSBPYmplY3Qua2V5cyhjaGVja291dEZvcm1WYWx1ZXMpO1xuXG4gIHJldHVybiBjaGVja291dEZvcm1Nb2RlbFJlZnMucmVkdWNlKFxuICAgIChhY2MsIGN1cnIpID0+ICh7XG4gICAgICAuLi5hY2MsXG4gICAgICBbY3Vycl06XG4gICAgICAgIGF1dG9jb21wbGV0ZUZpZWxkc01vZGVsUmVmcy5pbmNsdWRlcyhjdXJyKSAmJlxuICAgICAgICBsb2FkZWRBdXRvY29tcGxldGVzTW9kZWxSZWYuaW5jbHVkZXMoY3VycilcbiAgICAgICAgICA/IGNvbnZlcnRBdXRvY29tcGxldGVPcHRpb25Ub0JvZHlWYWx1ZShcbiAgICAgICAgICAgICAgYXV0b2NvbXBsZXRlT3B0aW9uc1tjdXJyXSxcbiAgICAgICAgICAgICAgY2hlY2tvdXRGb3JtVmFsdWVzW2N1cnJdIGFzIHN0cmluZyB8IElBdXRvY29tcGxldGVPcHRpb24sXG4gICAgICAgICAgICAgIGZvcm1QcmV2aW91c1N0YXRlW2N1cnJdLnZhbHVlIGFzIElBdXRvY29tcGxldGVPcHRpb25bXVxuICAgICAgICAgICAgKVxuICAgICAgICAgIDogKGNoZWNrb3V0Rm9ybVZhbHVlc1tjdXJyXSBhcyBGb3JtRGF0YVZhbHVlVHlwZXMpLFxuICAgIH0pLFxuICAgIHt9XG4gICk7XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRBdXRvY29tcGxldGVPcHRpb25Ub0JvZHlWYWx1ZShcbiAgYXV0b2NvbXBsZXRlT3B0aW9uczogSUF1dG9jb21wbGV0ZU9wdGlvbltdLFxuICBjaGVja291dEZvcm1GaWVsZFZhbHVlOiBzdHJpbmcgfCBJQXV0b2NvbXBsZXRlT3B0aW9uLFxuICBmb3JtUHJldmlvdXNTdGF0ZUZpZWxkVmFsdWU6IElBdXRvY29tcGxldGVPcHRpb24gfCBJQXV0b2NvbXBsZXRlT3B0aW9uW11cbik6IElMaW5rIHwgSUxpbmtbXSB7XG4gIGxldCB2YWx1ZUZvclJlcXVlc3RCb2R5OiBJTGluayB8IElMaW5rW10gPSBudWxsO1xuICBjb25zdCBhbGxDdXJyZW50RmllbGRPcHRpb25zOiBzdHJpbmdbXSA9IGF1dG9jb21wbGV0ZU9wdGlvbnMubWFwKFxuICAgIChvcHRpb246IElBdXRvY29tcGxldGVPcHRpb24pID0+IG9wdGlvbi5vcHRpb24udG9Mb2NhbGVVcHBlckNhc2UoKVxuICApO1xuICBpZiAoQXJyYXkuaXNBcnJheShmb3JtUHJldmlvdXNTdGF0ZUZpZWxkVmFsdWUpKSB7XG4gICAgdmFsdWVGb3JSZXF1ZXN0Qm9keSA9IFtcbiAgICAgIC4uLihmb3JtUHJldmlvdXNTdGF0ZUZpZWxkVmFsdWUgYXMgSUF1dG9jb21wbGV0ZU9wdGlvbltdKS5tYXAoXG4gICAgICAgIChmaWVsZE9wdGlvbjogSUF1dG9jb21wbGV0ZU9wdGlvbikgPT4gZmllbGRPcHRpb24udmFsdWVcbiAgICAgICksXG4gICAgXTtcbiAgfSBlbHNlIGlmICghIWNoZWNrb3V0Rm9ybUZpZWxkVmFsdWUpIHtcbiAgICBjb25zdCBjdXJyZW50RmllbGRWYWx1ZTogc3RyaW5nIHwgSUF1dG9jb21wbGV0ZU9wdGlvbiA9XG4gICAgICBjaGVja291dEZvcm1GaWVsZFZhbHVlO1xuICAgIGlmICh0eXBlb2YgY3VycmVudEZpZWxkVmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICBpZiAoXG4gICAgICAgIGFsbEN1cnJlbnRGaWVsZE9wdGlvbnMuaW5jbHVkZXMoY3VycmVudEZpZWxkVmFsdWUudG9Mb2NhbGVVcHBlckNhc2UoKSlcbiAgICAgICkge1xuICAgICAgICB2YWx1ZUZvclJlcXVlc3RCb2R5ID0gY29udmVydElucHV0VmFsdWVUb0F1dG9jb21wbGV0ZU9wdGlvbihcbiAgICAgICAgICBjdXJyZW50RmllbGRWYWx1ZSxcbiAgICAgICAgICBhdXRvY29tcGxldGVPcHRpb25zXG4gICAgICAgICkudmFsdWU7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhbHVlRm9yUmVxdWVzdEJvZHkgPSBjdXJyZW50RmllbGRWYWx1ZS52YWx1ZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHZhbHVlRm9yUmVxdWVzdEJvZHk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjb252ZXJ0SW5wdXRWYWx1ZVRvQXV0b2NvbXBsZXRlT3B0aW9uKFxuICBpbnB1dFZhbHVlOiBzdHJpbmcsXG4gIGF1dG9jb21wbGV0ZU9wdGlvbnM6IElBdXRvY29tcGxldGVPcHRpb25bXVxuKTogSUF1dG9jb21wbGV0ZU9wdGlvbiB7XG4gIHJldHVybiBhdXRvY29tcGxldGVPcHRpb25zLmZpbmQoXG4gICAgKG9wdGlvbjogSUF1dG9jb21wbGV0ZU9wdGlvbikgPT5cbiAgICAgIG9wdGlvbi5vcHRpb24udG9Mb2NhbGVVcHBlckNhc2UoKSA9PT0gaW5wdXRWYWx1ZS50b0xvY2FsZVVwcGVyQ2FzZSgpXG4gICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjb252ZXJ0Qm9vbGVhblRvU3RyaW5nKFxuICB2YWx1ZXNGb3JtOiBhbnksXG4gIGZvcm1Db25maWc6IElGb3JtRGF0YVtdXG4pOiBhbnkge1xuICBmb3JtQ29uZmlnLmZvckVhY2goKGNvbmZpZykgPT4ge1xuICAgIGlmIChcbiAgICAgIGNvbmZpZy52YWx1ZS5maWVsZC5wcm9wcy5jb252ZXJ0VG9TdHJpbmcgJiZcbiAgICAgIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh2YWx1ZXNGb3JtLCBjb25maWcubW9kZWxSZWYpXG4gICAgKSB7XG4gICAgICB2YWx1ZXNGb3JtID0ge1xuICAgICAgICAuLi52YWx1ZXNGb3JtLFxuICAgICAgICBbY29uZmlnLm1vZGVsUmVmXTogdmFsdWVzRm9ybVtjb25maWcubW9kZWxSZWZdXG4gICAgICAgICAgPyBjb25maWcudmFsdWUuZmllbGQucHJvcHMudHJ1ZUNvbmRpdGlvblZhbHVlXG4gICAgICAgICAgOiBjb25maWcudmFsdWUuZmllbGQucHJvcHMuZmFsc2VDb25kaXRpb25WYWx1ZSxcbiAgICAgIH07XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIHZhbHVlc0Zvcm07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjb252ZXJ0VG9TY2ltT2JqZWN0KFxuICB2YWx1ZXNGb3JtOiBhbnksXG4gIGZvcm1Db25maWc6IElGb3JtRGF0YVtdLFxuICBlbnRyeUlkOiBzdHJpbmcsXG4gIGRhdGFFbGVtZW50RXh0ZXJuYWxJZDogc3RyaW5nLFxuICBzY2hlbWFzOiBzdHJpbmdbXVxuKTogYW55IHtcbiAgdmFsdWVzRm9ybSA9IHtcbiAgICBzY2hlbWFzLFxuICAgIGlkOiBlbnRyeUlkLFxuICAgIGV4dGVybmFsSWQ6IGRhdGFFbGVtZW50RXh0ZXJuYWxJZCB8fCAnbmV3IGVudHJ5JyxcbiAgICAuLi52YWx1ZXNGb3JtLFxuICB9O1xuICBmb3JtQ29uZmlnLmZvckVhY2goKGNvbmZpZykgPT4ge1xuICAgIGlmIChcbiAgICAgIGNvbmZpZy5wcm9wcy5zY2ltUGFyZW50QXR0cmlidXRlICE9IG51bGwgJiZcbiAgICAgIGNvbmZpZy5tb2RlbFJlZiBpbiB2YWx1ZXNGb3JtXG4gICAgKSB7XG4gICAgICBjb25zdCBzY2ltUGFyZW50SWQ6IHN0cmluZyA9IGNvbmZpZy5wcm9wcy5zY2ltUGFyZW50QXR0cmlidXRlO1xuICAgICAgdmFsdWVzRm9ybSA9IHtcbiAgICAgICAgLi4udmFsdWVzRm9ybSxcbiAgICAgICAgW3NjaW1QYXJlbnRJZF06IHtcbiAgICAgICAgICAuLi52YWx1ZXNGb3JtW3NjaW1QYXJlbnRJZF0sXG4gICAgICAgICAgW2NvbmZpZy5tb2RlbFJlZl06IHZhbHVlc0Zvcm1bY29uZmlnLm1vZGVsUmVmXSxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgICBkZWxldGUgdmFsdWVzRm9ybVtjb25maWcubW9kZWxSZWZdO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgIGNvbmZpZy5wcm9wcz8uaXNOb3RWaXNpYmxlV2hlbkZhbHNlICYmXG4gICAgICB2YWx1ZXNGb3JtW2NvbmZpZy5tb2RlbFJlZl0gPT09IGZhbHNlXG4gICAgKSB7XG4gICAgICBkZWxldGUgdmFsdWVzRm9ybVtjb25maWcubW9kZWxSZWZdO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiB2YWx1ZXNGb3JtO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZm9ybWF0RGF0ZXBpY2tlckZvcm0oXG4gIHZhbHVlc0Zvcm06IGFueSxcbiAgZm9ybUNvbmZpZzogSUZvcm1EYXRhW10sXG4gIGRhdGVEaXNwbGF5Rm9ybWF0OiBzdHJpbmdcbik6IGFueSB7XG4gIGZvcm1Db25maWcuZm9yRWFjaCgoY29uZmlnKSA9PiB7XG4gICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh2YWx1ZXNGb3JtLCBjb25maWcubW9kZWxSZWYpKSB7XG4gICAgICB2YWx1ZXNGb3JtID0ge1xuICAgICAgICAuLi52YWx1ZXNGb3JtLFxuICAgICAgICBbY29uZmlnLm1vZGVsUmVmXTpcbiAgICAgICAgICBjb25maWcudmFsdWUuZmllbGQuY29tcG9uZW50TmFtZSA9PT0gRUNvbXBvbmVudE5hbWUuZGF0ZXBpY2tlciAmJlxuICAgICAgICAgIHZhbHVlc0Zvcm1bY29uZmlnLm1vZGVsUmVmXVxuICAgICAgICAgICAgPyBtb21lbnQodmFsdWVzRm9ybVtjb25maWcubW9kZWxSZWZdKS5jcmVhdGlvbkRhdGEoKS5mb3JtYXQgPT09XG4gICAgICAgICAgICAgICdZWVlZLU1NLUREJ1xuICAgICAgICAgICAgICA/IG1vbWVudCh2YWx1ZXNGb3JtW2NvbmZpZy5tb2RlbFJlZl0sICdZWVlZLU1NLUREJykuZm9ybWF0KFxuICAgICAgICAgICAgICAgICAgZGF0ZURpc3BsYXlGb3JtYXRcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgIDogbW9tZW50KHZhbHVlc0Zvcm1bY29uZmlnLm1vZGVsUmVmXSwgZGF0ZURpc3BsYXlGb3JtYXQpLmZvcm1hdChcbiAgICAgICAgICAgICAgICAgIGRhdGVEaXNwbGF5Rm9ybWF0XG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgOiB2YWx1ZXNGb3JtW2NvbmZpZy5tb2RlbFJlZl0sXG4gICAgICB9O1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiB2YWx1ZXNGb3JtO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0QXV0aG9yV2l0aERhdGUoXG4gIGRpc3BsYXlOYW1lOiBzdHJpbmcsXG4gIGxhbmd1YWdlOiBzdHJpbmdcbik6IHN0cmluZyB7XG4gIG1vbWVudC5sb2NhbGUobGFuZ3VhZ2UpO1xuICByZXR1cm4gZGlzcGxheU5hbWUgKyAnLCAnICsgbW9tZW50KCkuZm9ybWF0KCdMTEwnKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEZpbHRlcmVkT3B0aW9uc09uSW5pdGlhbFN0YXRlKFxuICBpc0lucHV0Q2hpcHNBdXRvY29tcGxldGU6IGJvb2xlYW4sXG4gIGF1dG9Db21wbGV0ZU9wdGlvbnM6IElBdXRvY29tcGxldGVPcHRpb25bXSxcbiAgZm9ybVByZXZpb3VzU3RhdGVGaWVsZDogSUF1dG9jb21wbGV0ZU9wdGlvbiB8IElBdXRvY29tcGxldGVPcHRpb25bXVxuKTogSUF1dG9jb21wbGV0ZU9wdGlvbltdIHtcbiAgaWYgKCFpc0lucHV0Q2hpcHNBdXRvY29tcGxldGUpIHtcbiAgICByZXR1cm4gYXV0b0NvbXBsZXRlT3B0aW9ucztcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gYXV0b0NvbXBsZXRlT3B0aW9ucy5maWx0ZXIoKG9wdGlvbjogSUF1dG9jb21wbGV0ZU9wdGlvbikgPT5cbiAgICAgIChmb3JtUHJldmlvdXNTdGF0ZUZpZWxkIGFzIElBdXRvY29tcGxldGVPcHRpb25bXSkuZXZlcnkoXG4gICAgICAgIChpbnB1dERpc3BsYXllZFZhbHVlOiBJQXV0b2NvbXBsZXRlT3B0aW9uKSA9PlxuICAgICAgICAgIGlucHV0RGlzcGxheWVkVmFsdWUub3B0aW9uXG4gICAgICAgICAgICAuZ2V0UmlkT2ZEaWFjcml0aWNzKClcbiAgICAgICAgICAgIC50b0xvY2FsZVVwcGVyQ2FzZSgpICE9PVxuICAgICAgICAgIG9wdGlvbi5vcHRpb24uZ2V0UmlkT2ZEaWFjcml0aWNzKCkudG9Mb2NhbGVVcHBlckNhc2UoKVxuICAgICAgKVxuICAgICk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEZvcm1BdXRvY29tcGxldGVGaWVsZEluaXRpYWxWYWx1ZShcbiAgZmllbGRWYWx1ZTogSUxpbmsgfCBJTGlua1tdLFxuICBjdXJyZW50T2JqZWN0OiBJQXV0b2NvbXBsZXRlT3B0aW9uLFxuICBmb3JtSW5pdGlhbFN0YXRlRmllbGRWYWx1ZTogRm9ybUZpZWxkc0FsbFR5cGVzLFxuICBmb3JtUHJldmlvdXNTdGF0ZUZpZWxkVmFsdWU6IEZvcm1GaWVsZHNBbGxUeXBlc1xuKTogSUluaXRGb3Jtc0F1dG9jb21wbGV0ZUZpZWxkIHtcbiAgbGV0IGlzVmFsaWRPcHRpb25WYWx1ZTogYm9vbGVhbjtcbiAgbGV0IGF1dG9jb21wbGV0ZUZpZWxkSW5pdGlhbFZhbHVlOiBJSW5pdEZvcm1zQXV0b2NvbXBsZXRlRmllbGQ7XG4gIGlmIChBcnJheS5pc0FycmF5KGZpZWxkVmFsdWUpKSB7XG4gICAgaXNWYWxpZE9wdGlvblZhbHVlID0gZmllbGRWYWx1ZS5zb21lKFxuICAgICAgKHZhbHVlOiBJTGluaykgPT5cbiAgICAgICAgY3VycmVudE9iamVjdC52YWx1ZS5pZC50b0xvY2FsZVVwcGVyQ2FzZSgpID09PVxuICAgICAgICB2YWx1ZS5pZC50b0xvY2FsZVVwcGVyQ2FzZSgpXG4gICAgKTtcbiAgfSBlbHNlIHtcbiAgICBpc1ZhbGlkT3B0aW9uVmFsdWUgPVxuICAgICAgY3VycmVudE9iamVjdC52YWx1ZS5pZC50b0xvY2FsZVVwcGVyQ2FzZSgpID09PVxuICAgICAgZmllbGRWYWx1ZS5pZC50b0xvY2FsZVVwcGVyQ2FzZSgpO1xuICB9XG4gIGlmIChpc1ZhbGlkT3B0aW9uVmFsdWUpIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShmaWVsZFZhbHVlKSkge1xuICAgICAgYXV0b2NvbXBsZXRlRmllbGRJbml0aWFsVmFsdWUgPSB7XG4gICAgICAgIGNvbnRyb2xWYWx1ZTogbnVsbCxcbiAgICAgICAgaW5pdGlhbFN0YXRlVmFsdWU6IFtcbiAgICAgICAgICAuLi4oZm9ybUluaXRpYWxTdGF0ZUZpZWxkVmFsdWUgYXMgSUF1dG9jb21wbGV0ZU9wdGlvbltdKSxcbiAgICAgICAgICB7IC4uLmN1cnJlbnRPYmplY3QgfSxcbiAgICAgICAgXSxcbiAgICAgICAgcHJldmlvdXNTdGF0ZVZhbHVlOiBbXG4gICAgICAgICAgLi4uKGZvcm1QcmV2aW91c1N0YXRlRmllbGRWYWx1ZSBhcyBJQXV0b2NvbXBsZXRlT3B0aW9uW10pLFxuICAgICAgICAgIHsgLi4uY3VycmVudE9iamVjdCB9LFxuICAgICAgICBdLFxuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgYXV0b2NvbXBsZXRlRmllbGRJbml0aWFsVmFsdWUgPSB7XG4gICAgICAgIGNvbnRyb2xWYWx1ZTogeyAuLi5jdXJyZW50T2JqZWN0IH0sXG4gICAgICAgIGluaXRpYWxTdGF0ZVZhbHVlOiB7IC4uLmN1cnJlbnRPYmplY3QgfSxcbiAgICAgICAgcHJldmlvdXNTdGF0ZVZhbHVlOiB7IC4uLmN1cnJlbnRPYmplY3QgfSxcbiAgICAgIH07XG4gICAgfVxuICB9XG4gIHJldHVybiBhdXRvY29tcGxldGVGaWVsZEluaXRpYWxWYWx1ZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEZvcm1FcnJvcnMoXG4gIGZvcm06IEZvcm1Hcm91cCxcbiAgZm9ybURhdGE6IElGb3JtRGF0YVtdLFxuICBmb3JtRmllbGRzOiB7IFttb2RlbFJlZjogc3RyaW5nXTogc3RyaW5nIH1cbik6IGFueSB7XG4gIGNvbnN0IGZvcm1GaWVsZHNDb3B5OiB7IFttb2RlbFJlZjogc3RyaW5nXTogc3RyaW5nIH0gPSB7XG4gICAgLi4uZm9ybUZpZWxkcyxcbiAgfTtcblxuICBmb3IgKGNvbnN0IG1vZGVsUmVmIGluIGZvcm1GaWVsZHNDb3B5KSB7XG4gICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChmb3JtRmllbGRzQ29weSwgbW9kZWxSZWYpKSB7XG4gICAgICBmb3JtRmllbGRzQ29weVttb2RlbFJlZl0gPSAnJztcblxuICAgICAgY29uc3QgY29udHJvbDogQWJzdHJhY3RDb250cm9sID0gZm9ybS5nZXQobW9kZWxSZWYpO1xuICAgICAgaWYgKGNvbnRyb2w/LmludmFsaWQgJiYgY29udHJvbD8uZGlydHkpIHtcbiAgICAgICAgY29uc3QgZmllbGQ6IElGb3JtRGF0YSA9IGZvcm1EYXRhLmZpbmQoXG4gICAgICAgICAgKGZvcm06IElGb3JtRGF0YSkgPT4gZm9ybS5tb2RlbFJlZiA9PT0gbW9kZWxSZWZcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3QgY3VyclZhbHVlRXJyb3I6IHsgW2Vycm9ySWQ6IHN0cmluZ106IHN0cmluZyB9ID0gZmllbGRcbiAgICAgICAgICA/IGZpZWxkLnZhbHVlLmVycm9yLnZhbHVlXG4gICAgICAgICAgOiBudWxsO1xuICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBjb250cm9sLmVycm9ycykge1xuICAgICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoY29udHJvbC5lcnJvcnMsIGtleSkpIHtcbiAgICAgICAgICAgIGZvcm1GaWVsZHNDb3B5W21vZGVsUmVmXSA9IGN1cnJWYWx1ZUVycm9yW2tleV07XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gZm9ybUZpZWxkc0NvcHk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRMaW5rZWRGaWVsZHNWYWx1ZXMoXG4gIGxpbmtlZEZpZWxkc01vZGVsUmVmczogc3RyaW5nW10sXG4gIGZvcm1QcmV2aW91c1N0YXRlOiB7XG4gICAgW2tleTogc3RyaW5nXTogSUZvcm1GaWVsZENvbnRyb2w7XG4gIH1cbik6IHN0cmluZ1tdIHtcbiAgcmV0dXJuIGxpbmtlZEZpZWxkc01vZGVsUmVmcy5yZWR1Y2UoKGFjYywgbW9kZWxSZWYpID0+IHtcbiAgICBpZiAoISFmb3JtUHJldmlvdXNTdGF0ZVttb2RlbFJlZl0udmFsdWUpIHtcbiAgICAgIGlmIChpc0F1dG9jb21wbGV0ZU9wdGlvbihmb3JtUHJldmlvdXNTdGF0ZVttb2RlbFJlZl0udmFsdWUpKSB7XG4gICAgICAgIGFjYy5wdXNoKFxuICAgICAgICAgIChcbiAgICAgICAgICAgIGZvcm1QcmV2aW91c1N0YXRlW21vZGVsUmVmXS52YWx1ZSBhcyBJQXV0b2NvbXBsZXRlT3B0aW9uXG4gICAgICAgICAgKS52YWx1ZS5pZC50b0xvY2FsZVVwcGVyQ2FzZSgpXG4gICAgICAgICk7XG4gICAgICB9IGVsc2UgaWYgKGlzQXV0b2NvbXBsZXRlT3B0aW9uQXJyYXkoZm9ybVByZXZpb3VzU3RhdGVbbW9kZWxSZWZdLnZhbHVlKSkge1xuICAgICAgICBhY2MucHVzaChcbiAgICAgICAgICAuLi4oZm9ybVByZXZpb3VzU3RhdGVbbW9kZWxSZWZdLnZhbHVlIGFzIElBdXRvY29tcGxldGVPcHRpb25bXSkubWFwKFxuICAgICAgICAgICAgKGF1dG9jb21wbGV0ZU9wdGlvbjogSUF1dG9jb21wbGV0ZU9wdGlvbikgPT5cbiAgICAgICAgICAgICAgYXV0b2NvbXBsZXRlT3B0aW9uLnZhbHVlLmlkLnRvTG9jYWxlVXBwZXJDYXNlKClcbiAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBhY2M7XG4gIH0sIFtdKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzQXV0b2NvbXBsZXRlT3B0aW9uKGZpZWxkVmFsdWU6IEZvcm1GaWVsZHNBbGxUeXBlcyk6IGJvb2xlYW4ge1xuICByZXR1cm4gKFxuICAgIHR5cGVvZiBmaWVsZFZhbHVlID09PSAnb2JqZWN0JyAmJlxuICAgIE9iamVjdC5rZXlzKGZpZWxkVmFsdWUpLmxlbmd0aCA9PT0gMiAmJlxuICAgICd2YWx1ZScgaW4gZmllbGRWYWx1ZSAmJlxuICAgIGlzTGlua09iamVjdChmaWVsZFZhbHVlLnZhbHVlKSAmJlxuICAgICdvcHRpb24nIGluIGZpZWxkVmFsdWVcbiAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzQXV0b2NvbXBsZXRlT3B0aW9uQXJyYXkoXG4gIGZpZWxkVmFsdWU6IEZvcm1GaWVsZHNBbGxUeXBlc1xuKTogYm9vbGVhbiB7XG4gIHJldHVybiAoXG4gICAgQXJyYXkuaXNBcnJheShmaWVsZFZhbHVlKSAmJlxuICAgIGZpZWxkVmFsdWUubGVuZ3RoID4gMCAmJlxuICAgIChmaWVsZFZhbHVlIGFzIChzdHJpbmcgfCBJQXV0b2NvbXBsZXRlT3B0aW9uIHwgSVNlbGVjdE9wdGlvbilbXSkuZXZlcnkoXG4gICAgICAodmFsdWU6IHN0cmluZyB8IElBdXRvY29tcGxldGVPcHRpb24gfCBJU2VsZWN0T3B0aW9uKSA9PlxuICAgICAgICBpc0F1dG9jb21wbGV0ZU9wdGlvbih2YWx1ZSlcbiAgICApXG4gICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRPcHRpb25zRmlsdGVyaW5nQ29uZGl0aW9uKFxuICBpbnB1dFZhbHVlOiBzdHJpbmcgfCBJQXV0b2NvbXBsZXRlT3B0aW9uLFxuICBpc0lucHV0Q2hpcHNBdXRvY29tcGxldGU6IGJvb2xlYW4sXG4gIGZvcm1QcmV2aW91c1N0YXRlRmllbGRWYWx1ZTogSUF1dG9jb21wbGV0ZU9wdGlvbiB8IElBdXRvY29tcGxldGVPcHRpb25bXVxuKTogKHBhcmFtOiBzdHJpbmcpID0+IGJvb2xlYW4ge1xuICBsZXQgaW5wdXRWYWx1ZUFzU3RyaW5nID0gJyc7XG4gIGxldCBjaGVja05vdEJlbG9uZ1RvQ2hpcHM6IChwYXJhbTogc3RyaW5nKSA9PiBib29sZWFuID0gKCkgPT4gdHJ1ZTtcbiAgbGV0IG9wdGlvbk1hdGNoSW5wdXRWYWx1ZTogKHBhcmFtOiBzdHJpbmcpID0+IGJvb2xlYW4gPSAoKSA9PiB0cnVlO1xuICBpZiAoaXNJbnB1dENoaXBzQXV0b2NvbXBsZXRlKSB7XG4gICAgY2hlY2tOb3RCZWxvbmdUb0NoaXBzID0gKHZhbHVlVG9Db21wYXJlOiBzdHJpbmcpID0+XG4gICAgICAoZm9ybVByZXZpb3VzU3RhdGVGaWVsZFZhbHVlIGFzIElBdXRvY29tcGxldGVPcHRpb25bXSkuZXZlcnkoXG4gICAgICAgIChpbnB1dERpc3BsYXllZFZhbHVlOiBJQXV0b2NvbXBsZXRlT3B0aW9uKSA9PlxuICAgICAgICAgIHZhbHVlVG9Db21wYXJlLmdldFJpZE9mRGlhY3JpdGljcygpLnRvTG9jYWxlVXBwZXJDYXNlKCkgIT09XG4gICAgICAgICAgaW5wdXREaXNwbGF5ZWRWYWx1ZS5vcHRpb24uZ2V0UmlkT2ZEaWFjcml0aWNzKCkudG9Mb2NhbGVVcHBlckNhc2UoKVxuICAgICAgKTtcbiAgfVxuICBpZiAoaW5wdXRWYWx1ZSAhPT0gbnVsbCkge1xuICAgIGlmICh0eXBlb2YgaW5wdXRWYWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGlucHV0VmFsdWVBc1N0cmluZyA9IGlucHV0VmFsdWUgYXMgc3RyaW5nO1xuICAgIH0gZWxzZSBpZiAoIWlzSW5wdXRDaGlwc0F1dG9jb21wbGV0ZSkge1xuICAgICAgaW5wdXRWYWx1ZUFzU3RyaW5nID0gKGlucHV0VmFsdWUgYXMgSUF1dG9jb21wbGV0ZU9wdGlvbikub3B0aW9uO1xuICAgIH1cbiAgICBvcHRpb25NYXRjaElucHV0VmFsdWUgPSAodmFsdWVUb0NvbXBhcmU6IHN0cmluZykgPT5cbiAgICAgIHZhbHVlVG9Db21wYXJlXG4gICAgICAgIC50b0xvY2FsZVVwcGVyQ2FzZSgpXG4gICAgICAgIC5nZXRSaWRPZkRpYWNyaXRpY3MoKVxuICAgICAgICAuaW5jbHVkZXMoXG4gICAgICAgICAgaW5wdXRWYWx1ZUFzU3RyaW5nLmdldFJpZE9mRGlhY3JpdGljcygpLnRvTG9jYWxlVXBwZXJDYXNlKClcbiAgICAgICAgKSB8fCBpbnB1dFZhbHVlQXNTdHJpbmcgPT09ICcnO1xuICB9XG4gIHJldHVybiAodmFsdWVUb0NvbXBhcmU6IHN0cmluZykgPT5cbiAgICBjaGVja05vdEJlbG9uZ1RvQ2hpcHModmFsdWVUb0NvbXBhcmUpICYmXG4gICAgb3B0aW9uTWF0Y2hJbnB1dFZhbHVlKHZhbHVlVG9Db21wYXJlKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlucHV0VmFsdWVJc05vdEFuT3B0aW9uKFxuICBmaWx0ZXJlZE9wdGlvbnM6IHsgW21vZGVsUmVmOiBzdHJpbmddOiBJQXV0b2NvbXBsZXRlT3B0aW9uW10gfSxcbiAgbW9kZWxSZWY6IHN0cmluZ1xuKTogVmFsaWRhdG9yRm4ge1xuICByZXR1cm4gKGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCk6IFZhbGlkYXRpb25FcnJvcnMgfCBudWxsID0+IHtcbiAgICBpZiAoXG4gICAgICBjb250cm9sLnZhbHVlICE9PSBudWxsICYmXG4gICAgICB0eXBlb2YgY29udHJvbC52YWx1ZSA9PT0gJ3N0cmluZycgJiZcbiAgICAgIGNvbnRyb2wudmFsdWUgIT09ICcnICYmXG4gICAgICBmaWx0ZXJlZE9wdGlvbnNbbW9kZWxSZWZdLmxlbmd0aCA9PT0gMFxuICAgICkge1xuICAgICAgcmV0dXJuIHsgaW5jb3JyZWN0OiB0cnVlIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlucHV0VmFsdWVJc05vdEFuT3B0aW9uU2ltcGxlQXV0b2NvbXBsZXRlKFxuICBmaWx0ZXJlZE9wdGlvbnM6IHsgW21vZGVsUmVmOiBzdHJpbmddOiBJQXV0b2NvbXBsZXRlT3B0aW9uW10gfSxcbiAgbW9kZWxSZWY6IHN0cmluZ1xuKTogVmFsaWRhdG9yRm4ge1xuICByZXR1cm4gKGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCk6IFZhbGlkYXRpb25FcnJvcnMgfCBudWxsID0+IHtcbiAgICBpZiAoXG4gICAgICBjb250cm9sLnZhbHVlICE9PSBudWxsICYmXG4gICAgICB0eXBlb2YgY29udHJvbC52YWx1ZSA9PT0gJ3N0cmluZycgJiZcbiAgICAgIGNvbnRyb2wudmFsdWUgIT09ICcnICYmXG4gICAgICAhZmlsdGVyZWRPcHRpb25zW21vZGVsUmVmXVxuICAgICAgICAubWFwKChlbGVtZW50OiBJQXV0b2NvbXBsZXRlT3B0aW9uKSA9PiBlbGVtZW50Lm9wdGlvbilcbiAgICAgICAgLmluY2x1ZGVzKGNvbnRyb2wudmFsdWUpXG4gICAgKSB7XG4gICAgICByZXR1cm4geyBpbmNvcnJlY3Q6IHRydWUgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNBdXRvY29tcGxldGVJbml0aWFsU3RhdGUoXG4gIGlucHV0VmFsdWU6IHN0cmluZyB8IElBdXRvY29tcGxldGVPcHRpb24sXG4gIGlzSW5wdXRDaGlwc0F1dG9jb21wbGV0ZTogYm9vbGVhbixcbiAgZm9ybVByZXZpb3VzU3RhdGVGaWVsZDogSUF1dG9jb21wbGV0ZU9wdGlvbiB8IElBdXRvY29tcGxldGVPcHRpb25bXSxcbiAgZm9ybUluaXRpYWxTdGF0ZUZpZWxkOiBJQXV0b2NvbXBsZXRlT3B0aW9uIHwgSUF1dG9jb21wbGV0ZU9wdGlvbltdXG4pOiBib29sZWFuIHtcbiAgaWYgKGlzSW5wdXRDaGlwc0F1dG9jb21wbGV0ZSkge1xuICAgIHJldHVybiAoXG4gICAgICBKU09OLnN0cmluZ2lmeShmb3JtUHJldmlvdXNTdGF0ZUZpZWxkIGFzIElBdXRvY29tcGxldGVPcHRpb25bXSkgPT09XG4gICAgICAgIEpTT04uc3RyaW5naWZ5KGZvcm1Jbml0aWFsU3RhdGVGaWVsZCkgJiZcbiAgICAgIChpbnB1dFZhbHVlID09PSBudWxsIHx8IGlucHV0VmFsdWUgPT09IHVuZGVmaW5lZCB8fCBpbnB1dFZhbHVlID09PSAnJylcbiAgICApO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBBcnJheS5pc0FycmF5KGlucHV0VmFsdWUpXG4gICAgICA/IEpTT04uc3RyaW5naWZ5KGlucHV0VmFsdWUpID09PSBKU09OLnN0cmluZ2lmeShmb3JtSW5pdGlhbFN0YXRlRmllbGQpXG4gICAgICA6IGlucHV0VmFsdWUgPT09IGZvcm1Jbml0aWFsU3RhdGVGaWVsZDtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNGb3JtRmllbGREaXNhYmxlZChcbiAgY2hlY2tlZEZpZWxkOiBJRm9ybURhdGEgfCBJQXR0cmlidXRlLFxuICBjcnVkQWN0aW9uOiBzdHJpbmcgPSBudWxsXG4pOiBib29sZWFuIHtcbiAgcmV0dXJuIChcbiAgICBjaGVja2VkRmllbGQudmFsdWUuZmllbGQucHJvcHMuZGlzYWJsZWQgJiZcbiAgICAhKGNydWRBY3Rpb24gPT09ICdzZWFyY2gnICYmIGNoZWNrZWRGaWVsZC5wcm9wcy5pc1NlYXJjaGFibGUpXG4gICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0Zvcm1GaWVsZERpc3BsYXllZChcbiAgZmllbGQ6IElGb3JtRGF0YSxcbiAgY3J1ZEFjdGlvbjogc3RyaW5nXG4pOiBib29sZWFuIHtcbiAgcmV0dXJuIChcbiAgICBmaWVsZC52YWx1ZS5maWVsZC5jb21wb25lbnROYW1lICE9PSBFQ29tcG9uZW50TmFtZS5hcnJheSAmJlxuICAgICgoIWZpZWxkLnZhbHVlLmZpZWxkLnByb3BzLmRpc2FibGVkIGFzIGJvb2xlYW4pIHx8XG4gICAgICAoY3J1ZEFjdGlvbiA9PT0gJ3NlYXJjaCcgJiYgZmllbGQucHJvcHMuaXNTZWFyY2hhYmxlKSlcbiAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGtlZXBGaWVsZEluUmVxdWVzdEJvZHkoXG4gIGZpZWxkQ29tcG9uZW50TmFtZTogc3RyaW5nLFxuICBmaWVsZFZhbHVlOiBGb3JtRGF0YVZhbHVlVHlwZXMsXG4gIGluaXRpYWxWYWx1ZTogSUZvcm1GaWVsZENvbnRyb2wsXG4gIGF1dG9jb21wbGV0ZU9wdGlvbnNMb2FkZWQ6IGJvb2xlYW4sXG4gIGNydWRBY3Rpb246IHN0cmluZ1xuKTogYm9vbGVhbiB7XG4gIGlmIChjcnVkQWN0aW9uID09PSAnc2VhcmNoJykge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgbGV0IGhhc1ZhbHVlQ2hhbmdlZCA9IGZhbHNlO1xuICBzd2l0Y2ggKGZpZWxkQ29tcG9uZW50TmFtZSkge1xuICAgIGNhc2UgRUNvbXBvbmVudE5hbWUuaW5wdXRDaGlwc0F1dG9jb21wbGV0ZTpcbiAgICAgIGhhc1ZhbHVlQ2hhbmdlZCA9IGhhc0lucHV0Q2hpcHNWYWx1ZUNoYW5nZWQoXG4gICAgICAgIGZpZWxkVmFsdWUgYXMgSUxpbmtbXSxcbiAgICAgICAgYXV0b2NvbXBsZXRlT3B0aW9uc0xvYWRlZCxcbiAgICAgICAgaW5pdGlhbFZhbHVlXG4gICAgICApO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSBFQ29tcG9uZW50TmFtZS5hdXRvY29tcGxldGU6XG4gICAgICBoYXNWYWx1ZUNoYW5nZWQgPSBoYXNBdXRvY29tcGxldGVWYWx1ZUNoYW5nZWQoXG4gICAgICAgIGZpZWxkVmFsdWUgYXMgSUxpbmssXG4gICAgICAgIGF1dG9jb21wbGV0ZU9wdGlvbnNMb2FkZWQsXG4gICAgICAgIGluaXRpYWxWYWx1ZVxuICAgICAgKTtcbiAgICAgIGJyZWFrO1xuICAgIGRlZmF1bHQ6XG4gICAgICBoYXNWYWx1ZUNoYW5nZWQgPSBmaWVsZFZhbHVlICE9PSBpbml0aWFsVmFsdWUudmFsdWU7XG4gICAgICBicmVhaztcbiAgfVxuICByZXR1cm4gaGFzVmFsdWVDaGFuZ2VkO1xufVxuXG5mdW5jdGlvbiBoYXNJbnB1dENoaXBzVmFsdWVDaGFuZ2VkKFxuICBpbnB1dENoaXBzRmllbGRWYWx1ZTogSUxpbmtbXSxcbiAgYXV0b2NvbXBsZXRlT3B0aW9uc0xvYWRlZDogYm9vbGVhbixcbiAgaW5pdGlhbFZhbHVlOiBJRm9ybUZpZWxkQ29udHJvbFxuKTogYm9vbGVhbiB7XG4gIGxldCBoYXNDaGFuZ2VkID0gZmFsc2U7XG4gIGlmIChpbnB1dENoaXBzRmllbGRWYWx1ZSAhPSBudWxsICYmIGluaXRpYWxWYWx1ZT8udmFsdWUgIT0gbnVsbCkge1xuICAgIGNvbnN0IGNoaXBzSWRzOiBzdHJpbmdbXSA9IChpbnB1dENoaXBzRmllbGRWYWx1ZSBhcyBJTGlua1tdKS5tYXAoXG4gICAgICAobGluazogSUxpbmspID0+IGxpbmsuaWRcbiAgICApO1xuICAgIGNvbnN0IGluaXRpYWxDaGlwc0lkczogc3RyaW5nW10gPSBhdXRvY29tcGxldGVPcHRpb25zTG9hZGVkXG4gICAgICA/IChpbml0aWFsVmFsdWUudmFsdWUgYXMgSUF1dG9jb21wbGV0ZU9wdGlvbltdKS5tYXAoXG4gICAgICAgICAgKG9wdGlvbjogSUF1dG9jb21wbGV0ZU9wdGlvbikgPT4gb3B0aW9uLnZhbHVlLmlkXG4gICAgICAgIClcbiAgICAgIDogKGluaXRpYWxWYWx1ZS52YWx1ZSBhcyBzdHJpbmdbXSk7XG5cbiAgICBoYXNDaGFuZ2VkID0gXy54b3IoY2hpcHNJZHMsIGluaXRpYWxDaGlwc0lkcykubGVuZ3RoID4gMDtcbiAgfVxuICByZXR1cm4gaGFzQ2hhbmdlZDtcbn1cblxuZnVuY3Rpb24gaGFzQXV0b2NvbXBsZXRlVmFsdWVDaGFuZ2VkKFxuICBhdXRvY29tcGxldGVGaWVsZFZhbHVlOiBJTGluayxcbiAgYXV0b2NvbXBsZXRlT3B0aW9uc0xvYWRlZDogYm9vbGVhbixcbiAgaW5pdGlhbFZhbHVlOiBJRm9ybUZpZWxkQ29udHJvbFxuKTogYm9vbGVhbiB7XG4gIGxldCBoYXNDaGFuZ2VkO1xuICBpZiAoYXV0b2NvbXBsZXRlRmllbGRWYWx1ZSAhPSBudWxsICYmIGluaXRpYWxWYWx1ZT8udmFsdWUgIT0gbnVsbCkge1xuICAgIGhhc0NoYW5nZWQgPVxuICAgICAgKGF1dG9jb21wbGV0ZU9wdGlvbnNMb2FkZWQgJiZcbiAgICAgICAgYXV0b2NvbXBsZXRlRmllbGRWYWx1ZS5pZCAhPT1cbiAgICAgICAgICAoaW5pdGlhbFZhbHVlLnZhbHVlIGFzIElBdXRvY29tcGxldGVPcHRpb24pLnZhbHVlLmlkKSB8fFxuICAgICAgKCFhdXRvY29tcGxldGVPcHRpb25zTG9hZGVkICYmXG4gICAgICAgIGF1dG9jb21wbGV0ZUZpZWxkVmFsdWUuaWQgIT09IGluaXRpYWxWYWx1ZS52YWx1ZSk7XG4gIH0gZWxzZSB7XG4gICAgaGFzQ2hhbmdlZCA9XG4gICAgICAoYXV0b2NvbXBsZXRlRmllbGRWYWx1ZSA9PSBudWxsICYmIGluaXRpYWxWYWx1ZT8udmFsdWUgIT0gbnVsbCkgfHxcbiAgICAgIChhdXRvY29tcGxldGVGaWVsZFZhbHVlICE9IG51bGwgJiYgaW5pdGlhbFZhbHVlPy52YWx1ZSA9PSBudWxsKTtcbiAgfVxuICByZXR1cm4gaGFzQ2hhbmdlZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlc2l6ZUltYWdlKFxuICB3aWR0aDogbnVtYmVyLFxuICBoZWlnaHQ6IG51bWJlcixcbiAgbWF4V2lkdGg6IG51bWJlcixcbiAgbWF4SGVpZ2h0OiBudW1iZXJcbik6IHsgd2lkdGg6IG51bWJlcjsgaGVpZ2h0OiBudW1iZXIgfSB7XG4gIGlmICh3aWR0aCA+IG1heFdpZHRoICYmIGhlaWdodCA8PSBtYXhIZWlnaHQpIHtcbiAgICBoZWlnaHQgKj0gbWF4V2lkdGggLyB3aWR0aDtcbiAgICB3aWR0aCA9IG1heFdpZHRoO1xuICB9IGVsc2UgaWYgKHdpZHRoIDw9IG1heFdpZHRoICYmIGhlaWdodCA+IG1heEhlaWdodCkge1xuICAgIHdpZHRoICo9IG1heEhlaWdodCAvIGhlaWdodDtcbiAgICBoZWlnaHQgPSBtYXhIZWlnaHQ7XG4gIH0gZWxzZSBpZiAod2lkdGggPiBtYXhXaWR0aCAmJiBoZWlnaHQgPiBtYXhIZWlnaHQpIHtcbiAgICBjb25zdCBtaW5SYXRpbyA9IE1hdGgubWluKG1heFdpZHRoIC8gd2lkdGgsIG1heEhlaWdodCAvIGhlaWdodCk7XG4gICAgd2lkdGggKj0gbWluUmF0aW87XG4gICAgaGVpZ2h0ICo9IG1pblJhdGlvO1xuICB9XG5cbiAgcmV0dXJuIHsgd2lkdGgsIGhlaWdodCB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2F2ZUNoZWNrb3V0Rm9ybVN0YXRlKFxuICBjaGVja291dEZvcm1WYWx1ZXM6IHtcbiAgICBbbW9kZWxSZWY6IHN0cmluZ106IEZvcm1GaWVsZHNFeHRlbmRlZFNpbmdsZVR5cGVzIHwgSUxpbmsgfCBJTGlua1tdO1xuICB9LFxuICBmb3JtRGF0YTogSUZvcm1EYXRhW10sXG4gIGNydWRBY3Rpb246IHN0cmluZ1xuKTogeyBba2V5OiBzdHJpbmddOiBJRm9ybUZpZWxkQ29udHJvbCB9IHtcbiAgbGV0IGZvcm1TdGF0ZSA9IHt9O1xuICBmb3IgKGNvbnN0IG1vZGVsUmVmIGluIGNoZWNrb3V0Rm9ybVZhbHVlcykge1xuICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoY2hlY2tvdXRGb3JtVmFsdWVzLCBtb2RlbFJlZikpIHtcbiAgICAgIGNvbnN0IGN1cnJlbnRGb3JtRmllbGQ6IElGb3JtRGF0YSA9IGZvcm1EYXRhLmZpbmQoXG4gICAgICAgIChmaWVsZDogSUZvcm1EYXRhKSA9PiBmaWVsZC5tb2RlbFJlZiA9PT0gbW9kZWxSZWZcbiAgICAgICk7XG4gICAgICBsZXQgZW5hYmxlZDogYm9vbGVhbiA9IG51bGw7XG4gICAgICBsZXQgdmFsdWU6IEZvcm1GaWVsZHNBbGxUeXBlcztcbiAgICAgIGlmIChcbiAgICAgICAgQXJyYXkuaXNBcnJheShjaGVja291dEZvcm1WYWx1ZXNbbW9kZWxSZWZdKSAmJlxuICAgICAgICBjdXJyZW50Rm9ybUZpZWxkLnZhbHVlLmZpZWxkLmNvbXBvbmVudE5hbWUgPT09XG4gICAgICAgICAgRUNvbXBvbmVudE5hbWUuaW5wdXRDaGlwc0F1dG9jb21wbGV0ZVxuICAgICAgKSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBjaGVja291dEZvcm1WYWx1ZXNbbW9kZWxSZWZdICYmXG4gICAgICAgICAgaXNBcnJheU9mTGlua09iamVjdHMoY2hlY2tvdXRGb3JtVmFsdWVzW21vZGVsUmVmXSlcbiAgICAgICAgKSB7XG4gICAgICAgICAgdmFsdWUgPSAoY2hlY2tvdXRGb3JtVmFsdWVzW21vZGVsUmVmXSBhcyBJTGlua1tdKS5tYXAoXG4gICAgICAgICAgICAobGluazogSUxpbmspID0+IGxpbmsuaWRcbiAgICAgICAgICApO1xuICAgICAgICAgIGVuYWJsZWQgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoY2hlY2tvdXRGb3JtVmFsdWVzW21vZGVsUmVmXSkpIHtcbiAgICAgICAgICB2YWx1ZSA9IFsuLi4oY2hlY2tvdXRGb3JtVmFsdWVzW21vZGVsUmVmXSBhcyBzdHJpbmdbXSldO1xuICAgICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAgIGNoZWNrb3V0Rm9ybVZhbHVlc1ttb2RlbFJlZl0gJiZcbiAgICAgICAgICBpc0xpbmtPYmplY3QoY2hlY2tvdXRGb3JtVmFsdWVzW21vZGVsUmVmXSlcbiAgICAgICAgKSB7XG4gICAgICAgICAgdmFsdWUgPSAoY2hlY2tvdXRGb3JtVmFsdWVzW21vZGVsUmVmXSBhcyBJTGluaykuaWQ7XG4gICAgICAgICAgZW5hYmxlZCA9IGZhbHNlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhbHVlID0gY2hlY2tvdXRGb3JtVmFsdWVzW21vZGVsUmVmXSBhcyBGb3JtRmllbGRzQWxsVHlwZXM7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChlbmFibGVkICE9PSBudWxsKSB7XG4gICAgICAgIGVuYWJsZWQgPSAhaXNGb3JtRmllbGREaXNhYmxlZChjdXJyZW50Rm9ybUZpZWxkLCBjcnVkQWN0aW9uKTtcbiAgICAgIH1cbiAgICAgIGZvcm1TdGF0ZSA9IHtcbiAgICAgICAgLi4uZm9ybVN0YXRlLFxuICAgICAgICBbbW9kZWxSZWZdOiB7XG4gICAgICAgICAgdmFsdWUsXG4gICAgICAgICAgZW5hYmxlZCxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfVxuICB9XG4gIHJldHVybiBmb3JtU3RhdGU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzZXRGb3JtQ29udHJvbFZhbHVlKGZpZWxkOiBJRm9ybURhdGEpOiBGb3JtRGF0YVZhbHVlVHlwZXMge1xuICBpZiAoQXJyYXkuaXNBcnJheShmaWVsZC5kYXRhVmFsdWUpKSB7XG4gICAgcmV0dXJuIFsuLi5maWVsZC5kYXRhVmFsdWVdIGFzIHN0cmluZ1tdIHwgSUxpbmtbXTtcbiAgfSBlbHNlIGlmIChmaWVsZC5wcm9wcy5pc0NvbmNhdFdpdGhQcmV2aW91c1ZhbHVlKSB7XG4gICAgcmV0dXJuICcnO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBmaWVsZC5kYXRhVmFsdWU7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHRyaW1Gb3JtRmllbGRzVmFsdWVzKGZvcm1GaWVsZHNWYWx1ZXM6IHtcbiAgW2lkOiBzdHJpbmddOiBGb3JtRGF0YVZhbHVlVHlwZXM7XG59KToge1xuICBbaWQ6IHN0cmluZ106IEZvcm1EYXRhVmFsdWVUeXBlcztcbn0ge1xuICByZXR1cm4gT2JqZWN0LmtleXMoZm9ybUZpZWxkc1ZhbHVlcykucmVkdWNlKChhY2MsIGN1cnIpID0+IHtcbiAgICBjb25zdCBpc1N0cmluZzogYm9vbGVhbiA9IHR5cGVvZiBmb3JtRmllbGRzVmFsdWVzW2N1cnJdID09PSAnc3RyaW5nJztcbiAgICBjb25zdCBpc1N0cmluZ0FycmF5OiBib29sZWFuID1cbiAgICAgIEFycmF5LmlzQXJyYXkoZm9ybUZpZWxkc1ZhbHVlc1tjdXJyXSkgJiZcbiAgICAgIChmb3JtRmllbGRzVmFsdWVzW2N1cnJdIGFzIHN0cmluZ1tdIHwgSUxpbmtbXSk/Lmxlbmd0aCA+IDAgJiZcbiAgICAgIHR5cGVvZiBmb3JtRmllbGRzVmFsdWVzW2N1cnJdWzBdID09PSAnc3RyaW5nJztcbiAgICBsZXQgZmllbGRWYWx1ZTogRm9ybURhdGFWYWx1ZVR5cGVzID0gZm9ybUZpZWxkc1ZhbHVlc1tjdXJyXTtcbiAgICBpZiAoaXNTdHJpbmcpIHtcbiAgICAgIGZpZWxkVmFsdWUgPSAoZmllbGRWYWx1ZSBhcyBzdHJpbmcpLnRyaW0oKTtcbiAgICB9IGVsc2UgaWYgKGlzU3RyaW5nQXJyYXkpIHtcbiAgICAgIGZpZWxkVmFsdWUgPSAoZmllbGRWYWx1ZSBhcyBzdHJpbmdbXSkubWFwKChzOiBzdHJpbmcpID0+IHMudHJpbSgpKTtcbiAgICB9XG4gICAgcmV0dXJuIHsgLi4uYWNjLCBbY3Vycl06IGZpZWxkVmFsdWUgfTtcbiAgfSwge30pO1xufVxuIl19