UNPKG

@microsoft/windows-admin-center-sdk

Version:

Microsoft - Windows Admin Center Shell

273 lines 41.4 kB
import { FormArray, FormGroup } from '@angular/forms'; import { LogLevel } from '@microsoft/windows-admin-center-sdk/core/diagnostics/log-level'; import { Logging } from '@microsoft/windows-admin-center-sdk/core/diagnostics/logging'; import { debounceTime, map, mergeMap, take } from 'rxjs/operators'; /** * A base class for an Angular component containing a form. * * @classdesc A base class for an Angular component containing a form that is pre-populated with fetched data. * The deriving class should call init() when setup is complete (sometime after calling super()) to begin the fetch * and initialize the form. * * @version 1.0.0 */ export class BasePropertiesForm { /** * Initializes a new instance of the BasePropertiesForm class. * * @param [loggingSource] - The source of log messages. */ constructor(loggingSource = 'BasePropertiesForm', appContextService) { this.loggingSource = loggingSource; this.appContextService = appContextService; this.confirmationStrings = MsftSme.getStrings().MsftSmeShell.Angular.Form.ConfirmationDialog; /** * Indicates data is being fetched. */ this.loading = true; } /** * Gets the current value of the form. */ get formCurrentValue() { return this.form.value; } /** * Discards the current form edits. */ onDiscard() { // TODO: The empty form should be created synchronously so angular // can bind to it. The values can be updated once the real data is available this.formData = this.createFormDataFromDataModel(); this.resetForm(); } /** * Saves the content of the form. The newest version of data for the form * will be fetched before performing the save operation. */ onSave() { if (this.saving) { return; } this.saving = true; MsftSme.deepAssign(this.formData, this.form.value); // Move disable after deepAssign since once disable form.value becomes empty this.form.disable(); let updatedModel; this.fetchData() .pipe(mergeMap((freshModel) => { this.formData.applyUpdatesToModel(freshModel); updatedModel = freshModel; return this.saveForm(freshModel); }), take(1)).subscribe({ next: (freshModel) => { this.form.enable(); this.saving = false; if (freshModel) { this.dataModel = freshModel; } else { this.dataModel = updatedModel; } this.formData = this.createFormDataFromDataModel(); this.resetForm(); this.onSaveSuccess(); }, error: (error) => { this.saving = false; this.form.enable(); this.onSaveError(error); } }); } canDeactivate(component, route, state) { if (this.appContextService && this.form && this.form.dirty) { return this.appContextService.frame.showDialogConfirmation(this.confirmContinueEditingDialogOptions(this.form, null)) .pipe(map((result) => { // The default is to continue editing const continueNavigation = !result.confirmed; if (continueNavigation) { this.form.reset(); } return continueNavigation; })); } return true; } confirmContinueEditingDialogOptions(dirtyForm, allForms) { return { cancelButtonText: this.confirmationStrings.unsavedChangesCancelText, confirmButtonText: this.confirmationStrings.unsavedChangesConfirmText, message: this.confirmationStrings.unsavedChangesMessage, title: this.confirmationStrings.unsavedChangesTitle }; } /** * The method to initialize the form with data. */ init() { this.loading = true; this.fetchData().pipe(take(1)).subscribe({ next: (data) => { this.dataModel = data; this.resetFormData(); this.initializeValidation(); }, error: (error) => { this.onFetchError(error); this.form.disable(); // TODO: Have a mechanism to refresh the data }, complete: () => { this.loading = false; } }); } /** * Resets the form and displays the original values while marking the form as pristine and untouched. */ resetForm() { this.form.reset(this.formData); } /** * Processes a control for validation. * * @param control - The control to validate. * @param formErrors - The errors of the form. * @param validationMessages - The validation messages of the form. * @param formErrorsIndex - The form errors index. */ processControlForValidation(control, formErrors, validationMessages, formErrorsIndex) { const isFormGroup = control instanceof FormGroup; let isFormArray = false; if (!isFormGroup) { isFormArray = control instanceof FormArray; } if (isFormGroup) { // iterate this.updateFormErrors(control, formErrors[formErrorsIndex], (validationMessages)); } else if (isFormArray) { this.updateFormErrorsForArray(control, formErrors[formErrorsIndex], (validationMessages)); } else { // for controls, clear the previous error messages formErrors[formErrorsIndex] = ''; } if (!control.valid && control.dirty) { if (isFormGroup || isFormArray) { // form groups and arrays are processed outside this for loop once all children have been processed return; } const messages = validationMessages; if (!messages) { return; } for (const key in control.errors) { if (control.errors.hasOwnProperty(key)) { let message = messages[key]; if (MsftSme.isFunction(message)) { message = message(); } formErrors[formErrorsIndex] = message; // Only one error message per control break; } } } } /** * Updates the form errors. * * @param form - The form to update. * @param formErrors - The form errors to apply. * @param validationMessages - The validation messages to apply. */ updateFormErrors(form, formErrors, validationMessages) { for (const field in formErrors) { if (formErrors.hasOwnProperty(field)) { const control = form.get(field); if (control) { this.processControlForValidation(control, formErrors, validationMessages.controls[field], field); } } } if (!form.valid && validationMessages.formGroup) { validationMessages.formGroup(form.errors); } } /** * Updates the form array errors. * * @param formArray - The form array to update. * @param formErrors - The form errors to apply. * @param validationMessages - The validation messages to apply. */ updateFormErrorsForArray(formArray, formErrors, validationMessages) { let processItems = true; if (!Array.isArray(formErrors)) { // form errors for form arrays should be an array of logSource processItems = false; Logging.log({ source: this.loggingSource, level: LogLevel.Warning, message: `Unexpected form errors type for form array. ` + `It should be an array but it is ${typeof formErrors}. Skipping validation` }); } const errorsArray = formErrors; if (errorsArray.length !== formArray.length) { processItems = false; Logging.log({ source: this.loggingSource, level: LogLevel.Warning, message: `Unexpected count of errors type for form array. ` + `It should be ${formArray.length} but it is ${errorsArray.length}. Skipping validation` }); } if (processItems) { for (let i = 0; i < formArray.length; i++) { const stringIndex = '' + i; const control = formArray.get(stringIndex); if (control) { this.processControlForValidation(control, formErrors, validationMessages, stringIndex); } } } if (!formArray.valid && validationMessages.formArray) { validationMessages.formArray(formArray.errors); } } /** * Initializes the form validation. */ initializeValidation() { this.form.valueChanges .pipe(debounceTime(500)) .subscribe((data) => { this.onValueChanged(data); }); this.onValueChanged(); } /** * The method to call when the form value changes. */ onValueChanged(data) { // TODO: Validate that the data? paramter was not needed if (!this.form) { return; } const form = this.form; this.updateFormErrors(form, this.formErrors, this.validationMessages); } /** * Resets the data backing the form without updating the display. * * @param existingForm - The existing form group of the display. */ resetFormData(existingForm) { this.formData = this.createFormDataFromDataModel(); this.form = this.createForm(); } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS1wcm9wZXJ0aWVzLWZvcm0uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9hbmd1bGFyL3NyYy9kYXRhL2Zvcm1zL2Jhc2UtcHJvcGVydGllcy1mb3JtLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBbUIsU0FBUyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRXZFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxnRUFBZ0UsQ0FBQztBQUMxRixPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sOERBQThELENBQUM7QUFFdkYsT0FBTyxFQUFFLFlBQVksRUFBRSxHQUFHLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBbUVuRTs7Ozs7Ozs7R0FRRztBQUNILE1BQU0sT0FBZ0Isa0JBQWtCO0lBNEJwQzs7OztPQUlHO0lBQ0gsWUFBc0IsZ0JBQXdCLG9CQUFvQixFQUFZLGlCQUFxQztRQUE3RixrQkFBYSxHQUFiLGFBQWEsQ0FBK0I7UUFBWSxzQkFBaUIsR0FBakIsaUJBQWlCLENBQW9CO1FBaEMzRyx3QkFBbUIsR0FBRyxPQUFPLENBQUMsVUFBVSxFQUFXLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUM7UUFPekc7O1dBRUc7UUFDSSxZQUFPLEdBQUcsSUFBSSxDQUFDO0lBc0JpRyxDQUFDO0lBNER4SDs7T0FFRztJQUNILElBQWMsZ0JBQWdCO1FBQzFCLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUM7SUFDM0IsQ0FBQztJQUVEOztPQUVHO0lBQ0ksU0FBUztRQUNaLGtFQUFrRTtRQUNsRSw0RUFBNEU7UUFFNUUsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsMkJBQTJCLEVBQUUsQ0FBQztRQUNuRCxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7SUFDckIsQ0FBQztJQUVEOzs7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QUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsa0JBQWtCLENBQUMsQ0FBQztJQUMxRSxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNLLGFBQWEsQ0FBQyxZQUF3QjtRQUMxQyxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQywyQkFBMkIsRUFBRSxDQUFDO1FBQ25ELElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO0lBQ2xDLENBQUM7Q0FDSiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFic3RyYWN0Q29udHJvbCwgRm9ybUFycmF5LCBGb3JtR3JvdXAgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XHJcbmltcG9ydCB7IEFjdGl2YXRlZFJvdXRlU25hcHNob3QsIFJvdXRlclN0YXRlU25hcHNob3QgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xyXG5pbXBvcnQgeyBMb2dMZXZlbCB9IGZyb20gJ0BtaWNyb3NvZnQvd2luZG93cy1hZG1pbi1jZW50ZXItc2RrL2NvcmUvZGlhZ25vc3RpY3MvbG9nLWxldmVsJztcclxuaW1wb3J0IHsgTG9nZ2luZyB9IGZyb20gJ0BtaWNyb3NvZnQvd2luZG93cy1hZG1pbi1jZW50ZXItc2RrL2NvcmUvZGlhZ25vc3RpY3MvbG9nZ2luZyc7XHJcbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgZGVib3VuY2VUaW1lLCBtYXAsIG1lcmdlTWFwLCB0YWtlIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xyXG5pbXBvcnQgeyBDb25maXJtYXRpb25EaWFsb2dPcHRpb25zIH0gZnJvbSAnLi4vLi4vY29udHJvbHMvZGlhbG9nL2NvbmZpcm1hdGlvbi1kaWFsb2cvY29uZmlybWF0aW9uLWRpYWxvZy5jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBDYW5Db21wb25lbnREZWFjdGl2YXRlIH0gZnJvbSAnLi4vLi4vY29udHJvbHMvc2V0dGluZ3Mvc2V0dGluZ3MtY2FuLWRlYWN0aXZhdGUtZ3VhcmQuc2VydmljZSc7XHJcbmltcG9ydCB7IFN0cmluZ3MgfSBmcm9tICcuLi8uLi9nZW5lcmF0ZWQvc3RyaW5ncyc7XHJcbmltcG9ydCB7IEFwcENvbnRleHRTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZS9hcHAtY29udGV4dC5zZXJ2aWNlJztcclxuaW1wb3J0IHsgQmFzZUZvcm1EYXRhIH0gZnJvbSAnLi9iYXNlLWZvcm0tZGF0YSc7XHJcblxyXG4vKipcclxuICogVGhlIGludGVyZmFjZSBmb3IgZXhwb3NpbmcgZm9ybSBjb250cm9sIHZhbGlkYXRpb24gbWVzc2FnZXMuXHJcbiAqXHJcbiAqIEV4YW1wbGU6XHJcbiAqIHtcclxuICogICAgICBmb3JtQ29udHJvbEE6IHtcclxuICogICAgICAgICAgcmVxdWlyZWQ6ICdOYW1lIGZpZWxkIGNhbm5vdCBiZSBlbXB0eS4nLFxyXG4gKiAgICAgICAgICBtYXhMZW5ndGg6ICdOYW1lIGNhbm5vdCBiZSBncmVhdGVyIHRoYW4gMTAwIGNoYXJhY3RlcnMgbG9uZy4nXHJcbiAqICAgICAgICAgIC4uLlxyXG4gKiAgICAgIH0sXHJcbiAqICAgICAgZnJvbUdyb3VwQToge1xyXG4gKiAgICAgICAgICBmb3JtQ29udHJvbEFBOiB7XHJcbiAqICAgICAgICAgICAgICByZXF1aXJlZDogJ2NpdHkgcmVxdWlyZWQnLFxyXG4gKiAgICAgICAgICB9LFxyXG4gKiAgICAgICAgICBmb3JtQ29udHJvbEFCOiB7XHJcbiAqICAgICAgICAgICAgICB6aXBWYWxpZGF0b3I6ICdaSVAgY29kZSBzaG91bGQgYmUgNSBudW1iZXJzJ1xyXG4gKiAgICAgICAgICB9LFxyXG4gKiAgICAgICAgICBmb3JtR3JvdXA6IChlcnJvcjogYW55KSA9PiB7XHJcbiAqICAgICAgICAgICAgICB0aGlzLnByb2Nlc3NGb3JtR3JvdXBBRXJyb3JzKGVycm9yKTsgLy8gWW91IG5lZWQgdG8gaW1wbGVtZW50IHRoaXMgZnVuY3Rpb24gaW4geW91ciBzdXBlciBjbGFzcy5cclxuICogICAgICAgICAgfVxyXG4gKiAgICAgIH0sXHJcbiAqICAgICAgZm9ybUFycmF5QToge1xyXG4gKiAgICAgICAgICBmb3JtQ29udHJvbEFBOiB7XHJcbiAqICAgICAgICAgICAgICAuLi5cclxuICogICAgICAgICAgfSxcclxuICogICAgICAgICAgZm9ybUNvbnRyb2xBQjoge1xyXG4gKiAgICAgICAgICAgICAgLi4uXHJcbiAqICAgICAgICAgIH0sXHJcbiAqICAgICAgICAgIGZvcm1BcnJheTogKGVycm9yOiBhbnkpID0+IHtcclxuICogICAgICAgICAgICAgIGlmIChlcnJvci5kdXBsaWNhdGVOYW1lKSB7XHJcbiAqICAgICAgICAgICAgICAgICAgdGhpcy5wcm9jZXNzRHVwbGljYXRlTmFtZUVycm9yKGVycm9yKTtcclxuICogICAgICAgICAgICAgIH1cclxuICogICAgICAgICAgfVxyXG4gKiAgICAgIH1cclxuICogfVxyXG4gKi9cclxuZXhwb3J0IGludGVyZmFjZSBGb3JtQ29udHJvbENvbnRhaW5lclZhbGlkYXRpb25NZXNzYWdlcyB7XHJcbiAgICBjb250cm9sczogeyBba2V5OiBzdHJpbmddOiAoeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfCAoKCkgPT4gc3RyaW5nKSB9IHwgRm9ybUdyb3VwVmFsaWRhdGlvbk1lc3NhZ2VzIHwgRm9ybUFycmF5VmFsaWRhdGlvbk1lc3NhZ2VzKSB9O1xyXG59XHJcblxyXG4vKipcclxuICogVGhlIGludGVyZmFjZSBmb3IgZXhwb3NpbmcgdmFsaWRhdGlvbiBtZXNzYWdlcyBmb3IgZm9ybSBhcnJheXMuXHJcbiAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIEZvcm1BcnJheVZhbGlkYXRpb25NZXNzYWdlcyBleHRlbmRzIEZvcm1Db250cm9sQ29udGFpbmVyVmFsaWRhdGlvbk1lc3NhZ2VzIHtcclxuICAgIC8qKlxyXG4gICAgICogQSBjYWxsYmFjayB0aGF0IHRha2VzIHRoZSBmb3JtIGFycmF5IHZhbGlkYXRpb24gZXJyb3JzIGFuZCBwcm9jZXNzZXMgdGhlbSBhY2NvcmRpbmdseS5cclxuICAgICAqL1xyXG4gICAgZm9ybUFycmF5PzogKGVycm9yOiBhbnkpID0+IHZvaWQ7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBUaGUgaW50ZXJmYWNlIGZvciBleHBvc2luZyB2YWxpZGF0aW9uIG1lc3NhZ2VzIGZvciBmb3JtIGdyb3Vwcy5cclxuICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgRm9ybUdyb3VwVmFsaWRhdGlvbk1lc3NhZ2VzIGV4dGVuZHMgRm9ybUNvbnRyb2xDb250YWluZXJWYWxpZGF0aW9uTWVzc2FnZXMge1xyXG4gICAgLyoqXHJcbiAgICAgKiBBIGNhbGxiYWNrIHRoYXQgdGFrZXMgdGhlIGZvcm0gZ3JvdXAgdmFsaWRhdGlvbiBlcnJvcnMgYW5kIHByb2Nlc3NlcyB0aGVtIGFjY29yZGluZ2x5LlxyXG4gICAgICovXHJcbiAgICBmb3JtR3JvdXA/OiAoZXJyb3I6IGFueSkgPT4gdm9pZDtcclxufVxyXG5cclxuLyoqXHJcbiAqIEEgYmFzZSBjbGFzcyBmb3IgYW4gQW5ndWxhciBjb21wb25lbnQgY29udGFpbmluZyBhIGZvcm0uXHJcbiAqXHJcbiAqIEBjbGFzc2Rlc2MgQSBiYXNlIGNsYXNzIGZvciBhbiBBbmd1bGFyIGNvbXBvbmVudCBjb250YWluaW5nIGEgZm9ybSB0aGF0IGlzIHByZS1wb3B1bGF0ZWQgd2l0aCBmZXRjaGVkIGRhdGEuXHJcbiAqIFRoZSBkZXJpdmluZyBjbGFzcyBzaG91bGQgY2FsbCBpbml0KCkgd2hlbiBzZXR1cCBpcyBjb21wbGV0ZSAoc29tZXRpbWUgYWZ0ZXIgY2FsbGluZyBzdXBlcigpKSB0byBiZWdpbiB0aGUgZmV0Y2hcclxuICogYW5kIGluaXRpYWxpemUgdGhlIGZvcm0uXHJcbiAqXHJcbiAqIEB2ZXJzaW9uIDEuMC4wXHJcbiAqL1xyXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQmFzZVByb3BlcnRpZXNGb3JtPFREYXRhTW9kZWwsIFRGb3JtRGF0YSBleHRlbmRzIEJhc2VGb3JtRGF0YTxURGF0YU1vZGVsPj4ge1xyXG4gICAgcHJpdmF0ZSBjb25maXJtYXRpb25TdHJpbmdzID0gTXNmdFNtZS5nZXRTdHJpbmdzPFN0cmluZ3M+KCkuTXNmdFNtZVNoZWxsLkFuZ3VsYXIuRm9ybS5Db25maXJtYXRpb25EaWFsb2c7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgcmVhY3RpdmUgZm9ybSBjb250YWluaW5nIGFsbCBmb3JtIGNvbnRyb2xzLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZm9ybTogRm9ybUdyb3VwO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogSW5kaWNhdGVzIGRhdGEgaXMgYmVpbmcgZmV0Y2hlZC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGxvYWRpbmcgPSB0cnVlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogSW5kaWNhdGVkIGRhdGEgaXMgYmVpbmcgc2F2ZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzYXZpbmc6IGJvb2xlYW47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgZGF0YSBtb2RlbCB0aGF0IGNvbnRhaW5zIGRhdGEgZnJvbSB0aGUgc2VydmljZS5cclxuICAgICAqL1xyXG4gICAgcHJvdGVjdGVkIGRhdGFNb2RlbDogVERhdGFNb2RlbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBkYXRhIG1vZGVsIHN1cHBseWluZyB0aGUgZm9ybSBmaWVsZCB2YWx1ZXMuXHJcbiAgICAgKi9cclxuICAgIHByb3RlY3RlZCBmb3JtRGF0YTogVEZvcm1EYXRhO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogSW5pdGlhbGl6ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIEJhc2VQcm9wZXJ0aWVzRm9ybSBjbGFzcy5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0gW2xvZ2dpbmdTb3VyY2VdIC0gVGhlIHNvdXJjZSBvZiBsb2cgbWVzc2FnZXMuXHJcbiAgICAgKi9cclxuICAgIGNvbnN0cnVjdG9yKHByb3RlY3RlZCBsb2dnaW5nU291cmNlOiBzdHJpbmcgPSAnQmFzZVByb3BlcnRpZXNGb3JtJywgcHJvdGVjdGVkIGFwcENvbnRleHRTZXJ2aWNlPzogQXBwQ29udGV4dFNlcnZpY2UpIHsgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB0aGUgZm9ybSBlcnJvcnMuXHJcbiAgICAgKi9cclxuICAgIHByb3RlY3RlZCBhYnN0cmFjdCBnZXQgZm9ybUVycm9ycygpOiBhbnk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSB2YWxpZGF0aW9uIG1lc3NhZ2VzLlxyXG4gICAgICovXHJcbiAgICBwcm90ZWN0ZWQgYWJzdHJhY3QgZ2V0IHZhbGlkYXRpb25NZXNzYWdlcygpOiBGb3JtR3JvdXBWYWxpZGF0aW9uTWVzc2FnZXM7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBGZXRjaGVzIGRhdGEgZm9yIHRoZSBmb3JtLlxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIFRoZSBsYXRlc3QgdmVyc2lvbiBvZiB0aGUgZm9ybSBkYXRhLlxyXG4gICAgICovXHJcbiAgICBwcm90ZWN0ZWQgYWJzdHJhY3QgZmV0Y2hEYXRhKCk6IE9ic2VydmFibGU8VERhdGFNb2RlbD47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIHRoZSBmb3JtLlxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIFRoZSBmb3JtIGdyb3VwIG9iamVjdC5cclxuICAgICAqL1xyXG4gICAgcHJvdGVjdGVkIGFic3RyYWN0IGNyZWF0ZUZvcm0oKTogRm9ybUdyb3VwO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ3JlYXRlcyBmb3JtIGRhdGEgZnJvbSB0aGUgYmFja2luZyBkYXRhIG1vZGVsLlxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIFRoZSBmb3JtIGRhdGEgb2JqZWN0LlxyXG4gICAgICovXHJcbiAgICBwcm90ZWN0ZWQgYWJzdHJhY3QgY3JlYXRlRm9ybURhdGFGcm9tRGF0YU1vZGVsKCk6IFRGb3JtRGF0YTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBtZXRob2QgdG8gcnVuIHdoZW4gdGhlIGRhdGEgZmV0Y2ggZmFpbHMuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIGVycm9yIC0gVGhlIGVycm9yIG9iamVjdC5cclxuICAgICAqL1xyXG4gICAgcHJvdGVjdGVkIGFic3RyYWN0IG9uRmV0Y2hFcnJvcihlcnJvcjogYW55KTogdm9pZDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBtZXRob2QgdG8gcnVuIHdoZW4gdGhlIGZvcm0gc2F2ZSBmYWlscy5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0gZXJyb3IgLSBUaGUgZXJyb3Igb2JqZWN0LlxyXG4gICAgICovXHJcbiAgICBwcm90ZWN0ZWQgYWJzdHJhY3Qgb25TYXZlRXJyb3IoZXJyb3I6IGFueSk6IHZvaWQ7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgbWV0aG9kIHRvIHJ1biB3aGVuIHRoZSBmb3JtIHNhdmUgc3VjY2VlZHMuXHJcbiAgICAgKi9cclxuICAgIHByb3RlY3RlZCBhYnN0cmFjdCBvblNhdmVTdWNjZXNzKCk6IHZvaWQ7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTYXZlcyB0aGUgZm9ybSBhY2NvcmRpbmcgdG8gdGhlIG5ldyBkYXRhIG1vZGVsLlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSBuZXdEYXRhTW9kZWwgLSBUaGUgbmV3IGRhdGEgbW9kZWwgdG8gc2F2ZS5cclxuICAgICAqIEByZXR1cm5zIFRoZSBuZXdlc3QgdmVyc2lvbiBvZiB0aGUgZGF0YSBtb2RlbC5cclxuICAgICAqL1xyXG4gICAgcHJvdGVjdGVkIGFic3RyYWN0IHNhdmVGb3JtKG5ld0RhdGFNb2RlbDogVERhdGFNb2RlbCk6IE9ic2VydmFibGU8VERhdGFNb2RlbD47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBmb3JtLlxyXG4gICAgICovXHJcbiAgICBwcm90ZWN0ZWQgZ2V0IGZvcm1DdXJyZW50VmFsdWUoKTogVEZvcm1EYXRhIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5mb3JtLnZhbHVlO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGlzY2FyZHMgdGhlIGN1cnJlbnQgZm9ybSBlZGl0cy5cclxuICAgICAqL1xyXG4gICAgcHVibGljIG9uRGlzY2FyZCgpOiB2b2lkIHtcclxuICAgICAgICAvLyBUT0RPOiBUaGUgZW1wdHkgZm9ybSBzaG91bGQgYmUgY3JlYXRlZCBzeW5jaHJvbm91c2x5IHNvIGFuZ3VsYXJcclxuICAgICAgICAvLyBjYW4gYmluZCB0byBpdC4gVGhlIHZhbHVlcyBjYW4gYmUgdXBkYXRlZCBvbmNlIHRoZSByZWFsIGRhdGEgaXMgYXZhaWxhYmxlXHJcblxyXG4gICAgICAgIHRoaXMuZm9ybURhdGEgPSB0aGlzLmNyZWF0ZUZvcm1EYXRhRnJvbURhdGFNb2RlbCgpO1xyXG4gICAgICAgIHRoaXMucmVzZXRGb3JtKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTYXZlcyB0aGUgY29udGVudCBvZiB0aGUgZm9ybS4gVGhlIG5ld2VzdCB2ZXJzaW9uIG9mIGRhdGEgZm9yIHRoZSBmb3JtXHJcbiAgICAgKiB3aWxsIGJlIGZldGNoZWQgYmVmb3JlIHBlcmZvcm1pbmcgdGhlIHNhdmUgb3BlcmF0aW9uLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgb25TYXZlKCk6IHZvaWQge1xyXG4gICAgICAgIGlmICh0aGlzLnNhdmluZykge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLnNhdmluZyA9IHRydWU7XHJcblxyXG4gICAgICAgIE1zZnRTbWUuZGVlcEFzc2lnbih0aGlzLmZvcm1EYXRhLCB0aGlzLmZvcm0udmFsdWUpO1xyXG5cclxuICAgICAgICAvLyBNb3ZlIGRpc2FibGUgYWZ0ZXIgZGVlcEFzc2lnbiBzaW5jZSBvbmNlIGRpc2FibGUgZm9ybS52YWx1ZSBiZWNvbWVzIGVtcHR5XHJcbiAgICAgICAgdGhpcy5mb3JtLmRpc2FibGUoKTtcclxuXHJcbiAgICAgICAgbGV0IHVwZGF0ZWRNb2RlbDtcclxuXHJcbiAgICAgICAgdGhpcy5mZXRjaERhdGEoKVxyXG4gICAgICAgICAgICAucGlwZShcclxuICAgICAgICAgICAgICAgIG1lcmdlTWFwKChmcmVzaE1vZGVsKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mb3JtRGF0YS5hcHBseVVwZGF0ZXNUb01vZGVsKGZyZXNoTW9kZWwpO1xyXG4gICAgICAgICAgICAgICAgICAgIHVwZGF0ZWRNb2RlbCA9IGZyZXNoTW9kZWw7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuc2F2ZUZvcm0oZnJlc2hNb2RlbCk7XHJcbiAgICAgICAgICAgICAgICB9KSxcclxuICAgICAgICAgICAgICAgIHRha2UoMSlcclxuICAgICAgICAgICAgKS5zdWJzY3JpYmUoe1xyXG4gICAgICAgICAgICAgICAgbmV4dDogKGZyZXNoTW9kZWwpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmZvcm0uZW5hYmxlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zYXZpbmcgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoZnJlc2hNb2RlbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRhdGFNb2RlbCA9IGZyZXNoTW9kZWw7XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kYXRhTW9kZWwgPSB1cGRhdGVkTW9kZWw7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmZvcm1EYXRhID0gdGhpcy5jcmVhdGVGb3JtRGF0YUZyb21EYXRhTW9kZWwoKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnJlc2V0Rm9ybSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMub25TYXZlU3VjY2VzcygpO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGVycm9yOiAoZXJyb3IpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zYXZpbmcgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5mb3JtLmVuYWJsZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm9uU2F2ZUVycm9yKGVycm9yKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBjYW5EZWFjdGl2YXRlKFxyXG4gICAgICAgIGNvbXBvbmVudDogQ2FuQ29tcG9uZW50RGVhY3RpdmF0ZSxcclxuICAgICAgICByb3V0ZTogQWN0aXZhdGVkUm91dGVTbmFwc2hvdCxcclxuICAgICAgICBzdGF0ZTogUm91dGVyU3RhdGVTbmFwc2hvdCk6IE9ic2VydmFibGU8Ym9vbGVhbj4gfCBQcm9taXNlPGJvb2xlYW4+IHwgYm9vbGVhbiB7XHJcbiAgICAgICAgaWYgKHRoaXMuYXBwQ29udGV4dFNlcnZpY2UgJiYgdGhpcy5mb3JtICYmIHRoaXMuZm9ybS5kaXJ0eSkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5hcHBDb250ZXh0U2VydmljZS5mcmFtZS5zaG93RGlhbG9nQ29uZmlybWF0aW9uKHRoaXMuY29uZmlybUNvbnRpbnVlRWRpdGluZ0RpYWxvZ09wdGlvbnModGhpcy5mb3JtLCBudWxsKSlcclxuICAgICAgICAgICAgICAgIC5waXBlKG1hcCgocmVzdWx0KSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gVGhlIGRlZmF1bHQgaXMgdG8gY29udGludWUgZWRpdGluZ1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbnRpbnVlTmF2aWdhdGlvbiA9ICFyZXN1bHQuY29uZmlybWVkO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjb250aW51ZU5hdmlnYXRpb24pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5mb3JtLnJlc2V0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjb250aW51ZU5hdmlnYXRpb247XHJcbiAgICAgICAgICAgICAgICB9KSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgY29uZmlybUNvbnRpbnVlRWRpdGluZ0RpYWxvZ09wdGlvbnMoXHJcbiAgICAgICAgZGlydHlGb3JtOiBGb3JtR3JvdXAsXHJcbiAgICAgICAgYWxsRm9ybXM6IEZvcm1Hcm91cFtdKTogQ29uZmlybWF0aW9uRGlhbG9nT3B0aW9ucyB7XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgY2FuY2VsQnV0dG9uVGV4dDogdGhpcy5jb25maXJtYXRpb25TdHJpbmdzLnVuc2F2ZWRDaGFuZ2VzQ2FuY2VsVGV4dCxcclxuICAgICAgICAgICAgY29uZmlybUJ1dHRvblRleHQ6IHRoaXMuY29uZmlybWF0aW9uU3RyaW5ncy51bnNhdmVkQ2hhbmdlc0NvbmZpcm1UZXh0LFxyXG4gICAgICAgICAgICBtZXNzYWdlOiB0aGlzLmNvbmZpcm1hdGlvblN0cmluZ3MudW5zYXZlZENoYW5nZXNNZXNzYWdlLFxyXG4gICAgICAgICAgICB0aXRsZTogdGhpcy5jb25maXJtYXRpb25TdHJpbmdzLnVuc2F2ZWRDaGFuZ2VzVGl0bGVcclxuICAgICAgICB9O1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIG1ldGhvZCB0byBpbml0aWFsaXplIHRoZSBmb3JtIHdpdGggZGF0YS5cclxuICAgICAqL1xyXG4gICAgcHJvdGVjdGVkIGluaXQoKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5sb2FkaW5nID0gdHJ1ZTtcclxuICAgICAgICB0aGlzLmZldGNoRGF0YSgpLnBpcGUodGFrZSgxKSkuc3Vic2NyaWJlKHtcclxuICAgICAgICAgICAgbmV4dDogKGRhdGEpID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuZGF0YU1vZGVsID0gZGF0YTtcclxuICAgICAgICAgICAgICAgIHRoaXMucmVzZXRGb3JtRGF0YSgpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5pbml0aWFsaXplVmFsaWRhdGlvbigpO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBlcnJvcjogKGVycm9yKSA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLm9uRmV0Y2hFcnJvcihlcnJvcik7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmZvcm0uZGlzYWJsZSgpO1xyXG4gICAgICAgICAgICAgICAgLy8gVE9ETzogSGF2ZSBhIG1lY2hhbmlzbSB0byByZWZyZXNoIHRoZSBkYXRhXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIGNvbXBsZXRlOiAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmxvYWRpbmcgPSBmYWxzZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVzZXRzIHRoZSBmb3JtIGFuZCBkaXNwbGF5cyB0aGUgb3JpZ2luYWwgdmFsdWVzIHdoaWxlIG1hcmtpbmcgdGhlIGZvcm0gYXMgcHJpc3RpbmUgYW5kIHVudG91Y2hlZC5cclxuICAgICAqL1xyXG4gICAgcHJvdGVjdGVkIHJlc2V0Rm9ybSgpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmZvcm0ucmVzZXQodGhpcy5mb3JtRGF0YSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBQcm9jZXNzZXMgYSBjb250cm9sIGZvciB2YWxpZGF0aW9uLlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSBjb250cm9sIC0gVGhlIGNvbnRyb2wgdG8gdmFsaWRhdGUuXHJcbiAgICAgKiBAcGFyYW0gZm9ybUVycm9ycyAtIFRoZSBlcnJvcnMgb2YgdGhlIGZvcm0uXHJcbiAgICAgKiBAcGFyYW0gdmFsaWRhdGlvbk1lc3NhZ2VzIC0gVGhlIHZhbGlkYXRpb24gbWVzc2FnZXMgb2YgdGhlIGZvcm0uXHJcbiAgICAgKiBAcGFyYW0gZm9ybUVycm9yc0luZGV4IC0gVGhlIGZvcm0gZXJyb3JzIGluZGV4LlxyXG4gICAgICovXHJcbiAgICBwcm90ZWN0ZWQgcHJvY2Vzc0NvbnRyb2xGb3JWYWxpZGF0aW9uKFxyXG4gICAgICAgIGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCxcclxuICAgICAgICBmb3JtRXJyb3JzOiBhbnksXHJcbiAgICAgICAgdmFsaWRhdGlvbk1lc3NhZ2VzOiBGb3JtQ29udHJvbENvbnRhaW5lclZhbGlkYXRpb25NZXNzYWdlcyB8IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIHwgKCgpID0+IHN0cmluZykgfSxcclxuICAgICAgICBmb3JtRXJyb3JzSW5kZXg6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgICAgIGNvbnN0IGlzRm9ybUdyb3VwID0gY29udHJvbCBpbnN0YW5jZW9mIEZvcm1Hcm91cDtcclxuICAgICAgICBsZXQgaXNGb3JtQXJyYXkgPSBmYWxzZTtcclxuICAgICAgICBpZiAoIWlzRm9ybUdyb3VwKSB7XHJcbiAgICAgICAgICAgIGlzRm9ybUFycmF5ID0gY29udHJvbCBpbnN0YW5jZW9mIEZvcm1BcnJheTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChpc0Zvcm1Hcm91cCkge1xyXG4gICAgICAgICAgICAvLyBpdGVyYXRlXHJcbiAgICAgICAgICAgIHRoaXMudXBkYXRlRm9ybUVycm9ycyhcclxuICAgICAgICAgICAgICAgIGNvbnRyb2wgYXMgRm9ybUdyb3VwLFxyXG4gICAgICAgICAgICAgICAgZm9ybUVycm9yc1tmb3JtRXJyb3JzSW5kZXhdLFxyXG4gICAgICAgICAgICAgICAgPEZvcm1Hcm91cFZhbGlkYXRpb25NZXNzYWdlcz4odmFsaWRhdGlvbk1lc3NhZ2VzKSk7XHJcbiAgICAgICAgfSBlbHNlIGlmIChpc0Zvcm1BcnJheSkge1xyXG4gICAgICAgICAgICB0aGlzLnVwZGF0ZUZvcm1FcnJvcnNGb3JBcnJheShcclxuICAgICAgICAgICAgICAgIGNvbnRyb2wgYXMgRm9ybUFycmF5LFxyXG4gICAgICAgICAgICAgICAgZm9ybUVycm9yc1tmb3JtRXJyb3JzSW5kZXhdLFxyXG4gICAgICAgICAgICAgICAgPEZvcm1BcnJheVZhbGlkYXRpb25NZXNzYWdlcz4odmFsaWRhdGlvbk1lc3NhZ2VzKSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgLy8gZm9yIGNvbnRyb2xzLCBjbGVhciB0aGUgcHJldmlvdXMgZXJyb3IgbWVzc2FnZXNcclxuICAgICAgICAgICAgZm9ybUVycm9yc1tmb3JtRXJyb3JzSW5kZXhdID0gJyc7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIWNvbnRyb2wudmFsaWQgJiYgY29udHJvbC5kaXJ0eSkge1xyXG4gICAgICAgICAgICBpZiAoaXNGb3JtR3JvdXAgfHwgaXNGb3JtQXJyYXkpIHtcclxuICAgICAgICAgICAgICAgIC8vIGZvcm0gZ3JvdXBzIGFuZCBhcnJheXMgYXJlIHByb2Nlc3NlZCBvdXRzaWRlIHRoaXMgZm9yIGxvb3Agb25jZSBhbGwgY2hpbGRyZW4gaGF2ZSBiZWVuIHByb2Nlc3NlZFxyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBjb25zdCBtZXNzYWdlcyA9IHZhbGlkYXRpb25NZXNzYWdlcztcclxuICAgICAgICAgICAgaWYgKCFtZXNzYWdlcykge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBjb250cm9sLmVycm9ycykge1xyXG4gICAgICAgICAgICAgICAgaWYgKGNvbnRyb2wuZXJyb3JzLmhhc093blByb3BlcnR5KGtleSkpIHtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgbWVzc2FnZSA9IG1lc3NhZ2VzW2tleV07XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKE1zZnRTbWUuaXNGdW5jdGlvbihtZXNzYWdlKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbWVzc2FnZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgZm9ybUVycm9yc1tmb3JtRXJyb3JzSW5kZXhdID0gbWVzc2FnZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gT25seSBvbmUgZXJyb3IgbWVzc2FnZSBwZXIgY29udHJvbFxyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVXBkYXRlcyB0aGUgZm9ybSBlcnJvcnMuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIGZvcm0gLSBUaGUgZm9ybSB0byB1cGRhdGUuXHJcbiAgICAgKiBAcGFyYW0gZm9ybUVycm9ycyAtIFRoZSBmb3JtIGVycm9ycyB0byBhcHBseS5cclxuICAgICAqIEBwYXJhbSB2YWxpZGF0aW9uTWVzc2FnZXMgLSBUaGUgdmFsaWRhdGlvbiBtZXNzYWdlcyB0byBhcHBseS5cclxuICAgICAqL1xyXG4gICAgcHJvdGVjdGVkIHVwZGF0ZUZvcm1FcnJvcnMoZm9ybTogRm9ybUdyb3VwLCBmb3JtRXJyb3JzOiBhbnksIHZhbGlkYXRpb25NZXNzYWdlczogRm9ybUdyb3VwVmFsaWRhdGlvbk1lc3NhZ2VzKTogdm9pZCB7XHJcbiAgICAgICAgZm9yIChjb25zdCBmaWVsZCBpbiBmb3JtRXJyb3JzKSB7XHJcbiAgICAgICAgICAgIGlmIChmb3JtRXJyb3JzLmhhc093blByb3BlcnR5KGZpZWxkKSkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgY29udHJvbCA9IGZvcm0uZ2V0KGZpZWxkKTtcclxuICAgICAgICAgICAgICAgIGlmIChjb250cm9sKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9jZXNzQ29udHJvbEZvclZhbGlkYXRpb24oY29udHJvbCwgZm9ybUVycm9ycywgdmFsaWRhdGlvbk1lc3NhZ2VzLmNvbnRyb2xzW2ZpZWxkXSwgZmllbGQpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIWZvcm0udmFsaWQgJiYgdmFsaWRhdGlvbk1lc3NhZ2VzLmZvcm1Hcm91cCkge1xyXG4gICAgICAgICAgICB2YWxpZGF0aW9uTWVzc2FnZXMuZm9ybUdyb3VwKGZvcm0uZXJyb3JzKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBVcGRhdGVzIHRoZSBmb3JtIGFycmF5IGVycm9ycy5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0gZm9ybUFycmF5IC0gVGhlIGZvcm0gYXJyYXkgdG8gdXBkYXRlLlxyXG4gICAgICogQHBhcmFtIGZvcm1FcnJvcnMgLSBUaGUgZm9ybSBlcnJvcnMgdG8gYXBwbHkuXHJcbiAgICAgKiBAcGFyYW0gdmFsaWRhdGlvbk1lc3NhZ2VzIC0gVGhlIHZhbGlkYXRpb24gbWVzc2FnZXMgdG8gYXBwbHkuXHJcbiAgICAgKi9cclxuICAgIHByb3RlY3RlZCB1cGRhdGVGb3JtRXJyb3JzRm9yQXJyYXkoZm9ybUFycmF5OiBGb3JtQXJyYXksIGZvcm1FcnJvcnM6IGFueSwgdmFsaWRhdGlvbk1lc3NhZ2VzOiBGb3JtQXJyYXlWYWxpZGF0aW9uTWVzc2FnZXMpOiB2b2lkIHtcclxuICAgICAgICBsZXQgcHJvY2Vzc0l0ZW1zID0gdHJ1ZTtcclxuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkoZm9ybUVycm9ycykpIHtcclxuICAgICAgICAgICAgLy8gZm9ybSBlcnJvcnMgZm9yIGZvcm0gYXJyYXlzIHNob3VsZCBiZSBhbiBhcnJheSBvZiBsb2dTb3VyY2VcclxuICAgICAgICAgICAgcHJvY2Vzc0l0ZW1zID0gZmFsc2U7XHJcbiAgICAgICAgICAgIExvZ2dpbmcubG9nKHtcclxuICAgICAgICAgICAgICAgIHNvdXJjZTogdGhpcy5sb2dnaW5nU291cmNlLFxyXG4gICAgICAgICAgICAgICAgbGV2ZWw6IExvZ0xldmVsLldhcm5pbmcsXHJcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiBgVW5leHBlY3RlZCBmb3JtIGVycm9ycyB0eXBlIGZvciBmb3JtIGFycmF5LiBgICtcclxuICAgICAgICAgICAgICAgICAgICBgSXQgc2hvdWxkIGJlIGFuIGFycmF5IGJ1dCBpdCBpcyAke3R5cGVvZiBmb3JtRXJyb3JzfS4gU2tpcHBpbmcgdmFsaWRhdGlvbmBcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBlcnJvcnNBcnJheSA9IGZvcm1FcnJvcnMgYXMgQXJyYXk8YW55PjtcclxuXHJcbiAgICAgICAgaWYgKGVycm9yc0FycmF5Lmxlbmd0aCAhPT0gZm9ybUFycmF5Lmxlbmd0aCkge1xyXG4gICAgICAgICAgICBwcm9jZXNzSXRlbXMgPSBmYWxzZTtcclxuICAgICAgICAgICAgTG9nZ2luZy5sb2coe1xyXG4gICAgICAgICAgICAgICAgc291cmNlOiB0aGlzLmxvZ2dpbmdTb3VyY2UsXHJcbiAgICAgICAgICAgICAgICBsZXZlbDogTG9nTGV2ZWwuV2FybmluZyxcclxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGBVbmV4cGVjdGVkIGNvdW50IG9mIGVycm9ycyB0eXBlIGZvciBmb3JtIGFycmF5LiBgICtcclxuICAgICAgICAgICAgICAgICAgICBgSXQgc2hvdWxkIGJlICR7Zm9ybUFycmF5Lmxlbmd0aH0gYnV0IGl0IGlzICR7ZXJyb3JzQXJyYXkubGVuZ3RofS4gU2tpcHBpbmcgdmFsaWRhdGlvbmBcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAocHJvY2Vzc0l0ZW1zKSB7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZm9ybUFycmF5Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmdJbmRleCA9ICcnICsgaTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGNvbnRyb2wgPSBmb3JtQXJyYXkuZ2V0KHN0cmluZ0luZGV4KTtcclxuICAgICAgICAgICAgICAgIGlmIChjb250cm9sKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9jZXNzQ29udHJvbEZvclZhbGlkYXRpb24oY29udHJvbCwgZm9ybUVycm9ycywgdmFsaWRhdGlvbk1lc3NhZ2VzLCBzdHJpbmdJbmRleCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICghZm9ybUFycmF5LnZhbGlkICYmIHZhbGlkYXRpb25NZXNzYWdlcy5mb3JtQXJyYXkpIHtcclxuICAgICAgICAgICAgdmFsaWRhdGlvbk1lc3NhZ2VzLmZvcm1BcnJheShmb3JtQXJyYXkuZXJyb3JzKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJbml0aWFsaXplcyB0aGUgZm9ybSB2YWxpZGF0aW9uLlxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGluaXRpYWxpemVWYWxpZGF0aW9uKCk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuZm9ybS52YWx1ZUNoYW5nZXNcclxuICAgICAgICAgICAgLnBpcGUoZGVib3VuY2VUaW1lKDUwMCkpXHJcbiAgICAgICAgICAgIC5zdWJzY3JpYmUoKGRhdGEpID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMub25WYWx1ZUNoYW5nZWQoZGF0YSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICB0aGlzLm9uVmFsdWVDaGFuZ2VkKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgbWV0aG9kIHRvIGNhbGwgd2hlbiB0aGUgZm9ybSB2YWx1ZSBjaGFuZ2VzLlxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIG9uVmFsdWVDaGFuZ2VkKGRhdGE/OiBhbnkpOiB2b2lkIHtcclxuICAgICAgICAvLyBUT0RPOiBWYWxpZGF0ZSB0aGF0IHRoZSBkYXRhPyBwYXJhbXRlciB3YXMgbm90IG5lZWRlZFxyXG4gICAgICAgIGlmICghdGhpcy5mb3JtKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IGZvcm0gPSB0aGlzLmZvcm07XHJcbiAgICAgICAgdGhpcy51cGRhdGVGb3JtRXJyb3JzKGZvcm0sIHRoaXMuZm9ybUVycm9ycywgdGhpcy52YWxpZGF0aW9uTWVzc2FnZXMpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVzZXRzIHRoZSBkYXRhIGJhY2tpbmcgdGhlIGZvcm0gd2l0aG91dCB1cGRhdGluZyB0aGUgZGlzcGxheS5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0gZXhpc3RpbmdGb3JtIC0gVGhlIGV4aXN0aW5nIGZvcm0gZ3JvdXAgb2YgdGhlIGRpc3BsYXkuXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgcmVzZXRGb3JtRGF0YShleGlzdGluZ0Zvcm0/OiBGb3JtR3JvdXApOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmZvcm1EYXRhID0gdGhpcy5jcmVhdGVGb3JtRGF0YUZyb21EYXRhTW9kZWwoKTtcclxuICAgICAgICB0aGlzLmZvcm0gPSB0aGlzLmNyZWF0ZUZvcm0oKTtcclxuICAgIH1cclxufVxyXG4iXX0=