UNPKG

@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
/**
 * 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