UNPKG

@microsoft/windows-admin-center-sdk

Version:

Microsoft - Windows Admin Center Shell

373 lines 45.3 kB
import { __decorate, __metadata } from "tslib"; import { Directive, Inject } from '@angular/core'; import { Debounce } from '@microsoft/windows-admin-center-sdk/core/base/decorators/debounce.decorators'; import { SME_LAYOUT_PROVIDER } from './layout'; import * as i0 from "@angular/core"; /** * It defines the number of breakpoints that WAC currently support. * add more scenarios when WAC is going to support scenarios like tablet etc. */ export var SmeResponsiveWindowBreakpointsValue; (function (SmeResponsiveWindowBreakpointsValue) { SmeResponsiveWindowBreakpointsValue[SmeResponsiveWindowBreakpointsValue["Reflow"] = 399.98] = "Reflow"; SmeResponsiveWindowBreakpointsValue[SmeResponsiveWindowBreakpointsValue["PhoneDown"] = 767.98] = "PhoneDown"; SmeResponsiveWindowBreakpointsValue[SmeResponsiveWindowBreakpointsValue["PhoneUp"] = Number.MAX_SAFE_INTEGER] = "PhoneUp"; })(SmeResponsiveWindowBreakpointsValue || (SmeResponsiveWindowBreakpointsValue = {})); /** * It defines the current supported scenario for window sizes. */ export var SmeResponsiveWindowBreakpoints; (function (SmeResponsiveWindowBreakpoints) { SmeResponsiveWindowBreakpoints["Reflow"] = "Reflow"; SmeResponsiveWindowBreakpoints["PhoneDown"] = "PhoneDown"; SmeResponsiveWindowBreakpoints["PhoneUp"] = "PhoneUp"; })(SmeResponsiveWindowBreakpoints || (SmeResponsiveWindowBreakpoints = {})); // eslint-disable-next-line @angular-eslint/directive-class-suffix export class SmeResponsiveWindowManagerComponent { /** * The manager supports layout component and in the meantime listening to the window size change event. * @param layout the layout component. */ constructor(layout) { this.layout = layout; /** * It defines whether the current window size is for super small window. */ this.internalReflowMode = false; /** * It defines whether the current window size is phone down. */ this.internalPhoneDown = false; /** * It defines whether the current window size is phone up. */ this.internalPhoneUp = false; /** * It defines whether the current solution/tool is using css v2 to support responsive window. */ this.internalCssV2 = false; /** * The array for subscription. */ this.subscriptions = []; this.setIsCssV2Enabled(); if (this.layout) { // on parent layout changes, re-emit the layout change to our event this.subscriptions.push(layout.layoutChanged.subscribe((() => this.onLayoutChanged()))); // on window break point changes, emit the event about critical classes and styling updates signal. this.subscriptions.push(layout.windowBreakpointChanged.subscribe(() => this.onWindowBreakpointChanged())); this.deferredOnLayoutChanged(); } } /** * Gets the current window responsive state. */ get responsiveWindowState() { return this.internalResponsiveWindowMode; } /** * Sets the current window responsive state. */ set responsiveWindowState(input) { const prevResponsiveWindowState = this.internalResponsiveWindowMode; this.internalResponsiveWindowMode = input; if (prevResponsiveWindowState !== this.internalResponsiveWindowMode) { this.layout?.windowBreakpointChanged.emit(); } } /** * Gets the value indicating whether css v2 should be used. */ get cssV2() { return this.internalCssV2; } /** * It sets the value for whether the current tool/solution is using css v2 for window responsiveness. */ set cssV2(input) { this.internalCssV2 = !!input; } /** * Gets the phone down mode. */ get phoneDown() { return this.internalPhoneDown; } /** * Sets the phone down mode. */ set phoneDown(input) { this.internalPhoneDown = !!input; } /** * Gets the phone up mode. */ get phoneUp() { return this.internalPhoneUp; } /** * Set the phone up mode. */ set phoneUp(input) { this.internalPhoneUp = !!input; } /** * Gets the reflow mode. */ get reflowMode() { return this.internalReflowMode; } /** * Sets the reflow mode. */ set reflowMode(input) { this.internalReflowMode = !!input; } /** * Gets the width of the window from the window object. * Should only be called on layout or window size change. */ get width() { return window?.innerWidth; } /** * Gets the height of the window from the window object. * Should only be called on layout or window size change. */ get height() { return window?.innerHeight; } /** * Gets the last known window responsive data. */ get prevSize() { if (this.internalPrevSize?.width === this.width && this.internalPrevSize?.height === this.height) { return this.internalPrevSize; } else { return this.getSmeResponsiveWindowData(); } } /** * Gets the window responsive break points. */ get size() { const width = this.width; if (width <= SmeResponsiveWindowBreakpointsValue.Reflow) { this.reflowMode = true; this.phoneDown = false; this.phoneUp = false; this.responsiveWindowState = SmeResponsiveWindowBreakpoints.Reflow; } else if (width <= SmeResponsiveWindowBreakpointsValue.PhoneDown) { this.reflowMode = false; this.phoneDown = true; this.phoneUp = false; this.responsiveWindowState = SmeResponsiveWindowBreakpoints.PhoneDown; } else { this.reflowMode = false; this.phoneDown = false; this.phoneUp = true; this.responsiveWindowState = SmeResponsiveWindowBreakpoints.PhoneUp; } return this.responsiveWindowState; } /** * It sets whether the current solution/tool is using the css v2 for window responsiveness. */ setIsCssV2Enabled() { this.cssV2 = this.isUsingCssV2(); } /** * The implementation for checking whether the styles are being set. * @returns true if the current tool/solution is using css v2 for window responsiveness. */ isUsingCssV2() { const head = document.getElementsByTagName('head')[0]; const links = head.querySelectorAll('link'); let cssV2 = true; // sme shell root would be containing style.css and either main.css or main-v2.css // thus as long as it is not main.css, should be using css-v2 for (let i = 0; i < links.length; i++) { const link = links[i]; if (link.href && link.href.includes('main.css')) { cssV2 = false; break; } } return cssV2; } /** * The functionality to update the core variables for window responsive data. * @returns The SmeResponsiveWindowData object */ getSmeResponsiveWindowData() { // on window size or layout change, gets the width and height from the window object. const width = this.width; const height = this.height; // based on the window size information, calculates the core paramters. const size = this.size; // the 3 gets above sets these following 3 parameters. const reflowMode = this.reflowMode; const phoneDown = this.phoneDown; const phoneUp = this.phoneUp; // sets the object and return. this.internalPrevSize = { width: width, height: height, size: size, reflowMode: reflowMode, phoneDown: phoneDown, phoneUp: phoneUp }; return this.internalPrevSize; } /** * On layout changed event handler, occurs every time the layout has been changed. */ onLayoutChanged() { this.getSmeResponsiveWindowData(); } /** * The deferred layout changed handler. */ deferredOnLayoutChanged() { this.onLayoutChanged(); } /** * To respond to a layout breakpoint changed event. * @returns void */ onWindowBreakpointChanged() { return; } /** * Gets the parent element by html tag. By default, go up 10 levels for enhanced performance. * @param inputElement The input element. * @returns The targeted html element get by the html tag */ getParentElementByTag(inputElement, parentHtmlTags = ['sme-pivot', 'sme-split-view', 'sme-settings-page'], levelExternal = 10, customKeywords, untilTagName) { if (!inputElement) { return undefined; } let level = levelExternal; let found = false; let parent = inputElement; while (level > 0 && !found) { if (parent) { parent = parent.parentElement; } const parentTagName = parent?.tagName.toLocaleLowerCase(); if (untilTagName) { if (parentTagName === untilTagName.toLowerCase()) { return undefined; } } if (parentHtmlTags.includes(parentTagName) || (customKeywords !== undefined && parentTagName?.includes(customKeywords))) { found = true; return parent; } level -= 1; } return undefined; } /** * The core algorithm for adding and removing classes based on window size and window size settings. * @param settings the settings object * @param curSettings the current setting * @param element the html element for setting up classes. * @returns void. */ updateClassArrayOnWindowSize(settings, curSettings, element) { if (!settings) { return; } settings = JSON.parse(JSON.stringify(settings)); const phoneDown = JSON.parse(JSON.stringify(settings.phoneDown)); const phoneUp = JSON.parse(JSON.stringify(settings.phoneUp)); const reflow = JSON.parse(JSON.stringify(settings.reflow)); let toBeRemovedClassList = []; let toBeAddedClassList = []; switch (curSettings) { case 'phoneUp': toBeAddedClassList = phoneUp; toBeRemovedClassList = phoneDown; toBeRemovedClassList = this.uniqueArray(toBeRemovedClassList, reflow); break; case 'phoneDown': toBeAddedClassList = phoneDown; toBeRemovedClassList = phoneUp; toBeRemovedClassList = this.uniqueArray(toBeRemovedClassList, reflow); break; case 'reflow': toBeAddedClassList = reflow; toBeRemovedClassList = phoneDown; toBeRemovedClassList = this.uniqueArray(toBeRemovedClassList, phoneUp); break; } toBeRemovedClassList = this.removeExistedItem(toBeRemovedClassList, toBeAddedClassList); for (let i = 0; i < toBeRemovedClassList.length; i++) { if (element.classList.contains(toBeRemovedClassList[i])) { element.classList.remove(toBeRemovedClassList[i]); } } for (let i = 0; i < toBeAddedClassList.length; i++) { if (!element.classList.contains(toBeAddedClassList[i])) { element.classList.add(toBeAddedClassList[i]); } } } /** * Merge two arrays with unique items. * @param arrayA the input array A * @param arrayB the input array B * @returns an array that contains unique items from array A and array B */ uniqueArray(arrayA, arrayB) { if (arrayB && arrayB.length) { for (let i = 0; i < arrayB.length; i++) { if (!arrayA.includes(arrayB[i])) { arrayA.push(arrayB[i]); } } } return arrayA; } /** * Guarantees will not remove the classes that needs to be added. * @param toBeRemovedClassList the list of classes that needs to be removed. * @param toBeAddedClassList the list of classes that needs to be added. * @returns the list of classes that needs to be removed and doesn't overlap with the classes that needs to be added. */ removeExistedItem(toBeRemovedClassList, toBeAddedClassList) { if (!toBeAddedClassList || !toBeAddedClassList.length) { return toBeRemovedClassList; } if (!toBeRemovedClassList || !toBeRemovedClassList.length) { return []; } const res = []; for (let i = 0; i < toBeRemovedClassList.length; i++) { if (!toBeAddedClassList.includes(toBeRemovedClassList[i])) { res.push(toBeRemovedClassList[i]); } } return res; } } /** @nocollapse */ SmeResponsiveWindowManagerComponent.ɵfac = function SmeResponsiveWindowManagerComponent_Factory(t) { return new (t || SmeResponsiveWindowManagerComponent)(i0.ɵɵdirectiveInject(SME_LAYOUT_PROVIDER)); }; /** @nocollapse */ SmeResponsiveWindowManagerComponent.ɵdir = /** @pureOrBreakMyCode */ i0.ɵɵdefineDirective({ type: SmeResponsiveWindowManagerComponent }); __decorate([ Debounce(), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", void 0) ], SmeResponsiveWindowManagerComponent.prototype, "deferredOnLayoutChanged", null); (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SmeResponsiveWindowManagerComponent, [{ type: Directive }], function () { return [{ type: undefined, decorators: [{ type: Inject, args: [SME_LAYOUT_PROVIDER] }] }]; }, { deferredOnLayoutChanged: [] }); })(); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21lLXJlc3BvbnNpdmUtd2luZG93LW1hbmFnZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vYW5ndWxhci9zcmMvY29udHJvbHMvY29tbW9uL3NtZS1yZXNwb25zaXZlLXdpbmRvdy1tYW5hZ2VyLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbEQsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLDhFQUE4RSxDQUFDO0FBRXhHLE9BQU8sRUFBVSxtQkFBbUIsRUFBRSxNQUFNLFVBQVUsQ0FBQzs7QUFFdkQ7OztHQUdHO0FBQ0gsTUFBTSxDQUFOLElBQVksbUNBSVg7QUFKRCxXQUFZLG1DQUFtQztJQUMzQyxzR0FBZSxDQUFBO0lBQ2YsNEdBQWtCLENBQUE7SUFDbEIscUZBQVUsTUFBTSxDQUFDLGdCQUFnQixhQUFBLENBQUE7QUFDckMsQ0FBQyxFQUpXLG1DQUFtQyxLQUFuQyxtQ0FBbUMsUUFJOUM7QUFFRDs7R0FFRztBQUNILE1BQU0sQ0FBTixJQUFZLDhCQUlYO0FBSkQsV0FBWSw4QkFBOEI7SUFDdEMsbURBQWlCLENBQUE7SUFDakIseURBQXVCLENBQUE7SUFDdkIscURBQW1CLENBQUE7QUFDdkIsQ0FBQyxFQUpXLDhCQUE4QixLQUE5Qiw4QkFBOEIsUUFJekM7QUFlRCxrRUFBa0U7QUFDbEUsTUFBTSxPQUFPLG1DQUFtQztJQW1LNUM7OztPQUdHO0lBQ0gsWUFBaUQsTUFBZTtRQUFmLFdBQU0sR0FBTixNQUFNLENBQVM7UUFyS2hFOztXQUVHO1FBQ08sdUJBQWtCLEdBQUcsS0FBSyxDQUFDO1FBRXJDOztXQUVHO1FBQ08sc0JBQWlCLEdBQUcsS0FBSyxDQUFDO1FBRXBDOztXQUVHO1FBQ08sb0JBQWUsR0FBRyxLQUFLLENBQUM7UUFFbEM7O1dBRUc7UUFDTyxrQkFB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QixNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2lCQUMxQjthQUNKO1NBQ0o7UUFFRCxPQUFPLE1BQU0sQ0FBQztJQUNsQixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSyxpQkFBaUIsQ0FBQyxvQkFBOEIsRUFBRSxrQkFBNEI7UUFDbEYsSUFBSSxDQUFDLGtCQUFrQixJQUFJLENBQUMsa0JBQWtCLENBQUMsTUFBTSxFQUFFO1lBQ25ELE9BQU8sb0JBQW9CLENBQUM7U0FDL0I7UUFFRCxJQUFJLENBQUMsb0JBQW9CLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLEVBQUU7WUFDdkQsT0FBTyxFQUFFLENBQUM7U0FDYjtRQUVELE1BQU0sR0FBRyxHQUFHLEVBQUUsQ0FBQztRQUVmLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxvQkFBb0IsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDbEQsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFFBQVEsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFO2dCQUN2RCxHQUFHLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDckM7U0FDSjtRQUVELE9BQU8sR0FBRyxDQUFDO0lBQ2YsQ0FBQzs7eUlBN1lRLG1DQUFtQyx1QkF1S3hCLG1CQUFtQjtxSEF2SzlCLG1DQUFtQztBQXlQNUM7SUFBQyxRQUFRLEVBQUU7Ozs7a0ZBR1Y7dUZBNVBRLG1DQUFtQztjQUYvQyxTQUFTOztzQkF5S08sTUFBTTt1QkFBQyxtQkFBbUI7d0JBbUZoQyx1QkFBdUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEaXJlY3RpdmUsIEluamVjdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBEZWJvdW5jZSB9IGZyb20gJ0BtaWNyb3NvZnQvd2luZG93cy1hZG1pbi1jZW50ZXItc2RrL2NvcmUvYmFzZS9kZWNvcmF0b3JzL2RlYm91bmNlLmRlY29yYXRvcnMnO1xyXG5pbXBvcnQgeyBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgTGF5b3V0LCBTTUVfTEFZT1VUX1BST1ZJREVSIH0gZnJvbSAnLi9sYXlvdXQnO1xyXG5cclxuLyoqXHJcbiAqIEl0IGRlZmluZXMgdGhlIG51bWJlciBvZiBicmVha3BvaW50cyB0aGF0IFdBQyBjdXJyZW50bHkgc3VwcG9ydC5cclxuICogYWRkIG1vcmUgc2NlbmFyaW9zIHdoZW4gV0FDIGlzIGdvaW5nIHRvIHN1cHBvcnQgc2NlbmFyaW9zIGxpa2UgdGFibGV0IGV0Yy5cclxuICovXHJcbmV4cG9ydCBlbnVtIFNtZVJlc3BvbnNpdmVXaW5kb3dCcmVha3BvaW50c1ZhbHVlIHtcclxuICAgIFJlZmxvdyA9IDM5OS45OCxcclxuICAgIFBob25lRG93biA9IDc2Ny45OCxcclxuICAgIFBob25lVXAgPSBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUlxyXG59XHJcblxyXG4vKipcclxuICogSXQgZGVmaW5lcyB0aGUgY3VycmVudCBzdXBwb3J0ZWQgc2NlbmFyaW8gZm9yIHdpbmRvdyBzaXplcy5cclxuICovXHJcbmV4cG9ydCBlbnVtIFNtZVJlc3BvbnNpdmVXaW5kb3dCcmVha3BvaW50cyB7XHJcbiAgICBSZWZsb3cgPSAnUmVmbG93JyxcclxuICAgIFBob25lRG93biA9ICdQaG9uZURvd24nLFxyXG4gICAgUGhvbmVVcCA9ICdQaG9uZVVwJ1xyXG59XHJcblxyXG4vKipcclxuICogSXQgZGVmaW5lcyBhbiBvYmplY3QgdG8gY29tbXVuaWNhdGUgYW1vbmcgY29udHJvbHMuXHJcbiAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIFNtZVJlc3BvbnNpdmVXaW5kb3dEYXRhIHtcclxuICAgIHdpZHRoOiBudW1iZXI7XHJcbiAgICBoZWlnaHQ6IG51bWJlcjtcclxuICAgIHNpemU6IFNtZVJlc3BvbnNpdmVXaW5kb3dCcmVha3BvaW50cztcclxuICAgIHJlZmxvd01vZGU6IGJvb2xlYW47XHJcbiAgICBwaG9uZURvd246IGJvb2xlYW47XHJcbiAgICBwaG9uZVVwOiBib29sZWFuO1xyXG59XHJcblxyXG5ARGlyZWN0aXZlKClcclxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEBhbmd1bGFyLWVzbGludC9kaXJlY3RpdmUtY2xhc3Mtc3VmZml4XHJcbmV4cG9ydCBjbGFzcyBTbWVSZXNwb25zaXZlV2luZG93TWFuYWdlckNvbXBvbmVudCB7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJdCBkZWZpbmVzIHdoZXRoZXIgdGhlIGN1cnJlbnQgd2luZG93IHNpemUgaXMgZm9yIHN1cGVyIHNtYWxsIHdpbmRvdy5cclxuICAgICAqL1xyXG4gICAgcHJvdGVjdGVkIGludGVybmFsUmVmbG93TW9kZSA9IGZhbHNlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogSXQgZGVmaW5lcyB3aGV0aGVyIHRoZSBjdXJyZW50IHdpbmRvdyBzaXplIGlzIHBob25lIGRvd24uXHJcbiAgICAgKi9cclxuICAgIHByb3RlY3RlZCBpbnRlcm5hbFBob25lRG93biA9IGZhbHNlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogSXQgZGVmaW5lcyB3aGV0aGVyIHRoZSBjdXJyZW50IHdpbmRvdyBzaXplIGlzIHBob25lIHVwLlxyXG4gICAgICovXHJcbiAgICBwcm90ZWN0ZWQgaW50ZXJuYWxQaG9uZVVwID0gZmFsc2U7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJdCBkZWZpbmVzIHdoZXRoZXIgdGhlIGN1cnJlbnQgc29sdXRpb24vdG9vbCBpcyB1c2luZyBjc3MgdjIgdG8gc3VwcG9ydCByZXNwb25zaXZlIHdpbmRvdy5cclxuICAgICAqL1xyXG4gICAgcHJvdGVjdGVkIGludGVybmFsQ3NzVjIgPSBmYWxzZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIHRoZSBpbnRlcm5hbCBjdXJyZW50IHdpbmRvdyByZXNwb25zaXZlIG1vZGUuXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgaW50ZXJuYWxSZXNwb25zaXZlV2luZG93TW9kZTogU21lUmVzcG9uc2l2ZVdpbmRvd0JyZWFrcG9pbnRzO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIGFycmF5IGZvciBzdWJzY3JpcHRpb24uXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgc3Vic2NyaXB0aW9uczogU3Vic2NyaXB0aW9uW10gPSBbXTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBtb3N0IHJlY2VudCBtZW1vcnkgZm9yIHRoZSBsYXN0IGtub3duIHdpbmRvdyBpbmZvcm1hdGlvbi5cclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBpbnRlcm5hbFByZXZTaXplOiBTbWVSZXNwb25zaXZlV2luZG93RGF0YTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldHMgdGhlIGN1cnJlbnQgd2luZG93IHJlc3BvbnNpdmUgc3RhdGUuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBnZXQgcmVzcG9uc2l2ZVdpbmRvd1N0YXRlKCk6IFNtZVJlc3BvbnNpdmVXaW5kb3dCcmVha3BvaW50cyB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuaW50ZXJuYWxSZXNwb25zaXZlV2luZG93TW9kZTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFNldHMgdGhlIGN1cnJlbnQgd2luZG93IHJlc3BvbnNpdmUgc3RhdGUuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzZXQgcmVzcG9uc2l2ZVdpbmRvd1N0YXRlKGlucHV0OiBTbWVSZXNwb25zaXZlV2luZG93QnJlYWtwb2ludHMpIHtcclxuICAgICAgICBjb25zdCBwcmV2UmVzcG9uc2l2ZVdpbmRvd1N0YXRlID0gdGhpcy5pbnRlcm5hbFJlc3BvbnNpdmVXaW5kb3dNb2RlO1xyXG4gICAgICAgIHRoaXMuaW50ZXJuYWxSZXNwb25zaXZlV2luZG93TW9kZSA9IGlucHV0O1xyXG4gICAgICAgIGlmIChwcmV2UmVzcG9uc2l2ZVdpbmRvd1N0YXRlICE9PSB0aGlzLmludGVybmFsUmVzcG9uc2l2ZVdpbmRvd01vZGUpIHtcclxuICAgICAgICAgICAgdGhpcy5sYXlvdXQ/LndpbmRvd0JyZWFrcG9pbnRDaGFuZ2VkLmVtaXQoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSB2YWx1ZSBpbmRpY2F0aW5nIHdoZXRoZXIgY3NzIHYyIHNob3VsZCBiZSB1c2VkLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZ2V0IGNzc1YyKCk6IGJvb2xlYW4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmludGVybmFsQ3NzVjI7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJdCBzZXRzIHRoZSB2YWx1ZSBmb3Igd2hldGhlciB0aGUgY3VycmVudCB0b29sL3NvbHV0aW9uIGlzIHVzaW5nIGNzcyB2MiBmb3Igd2luZG93IHJlc3BvbnNpdmVuZXNzLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc2V0IGNzc1YyKGlucHV0OiBib29sZWFuKSB7XHJcbiAgICAgICAgdGhpcy5pbnRlcm5hbENzc1YyID0gISFpbnB1dDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldHMgdGhlIHBob25lIGRvd24gbW9kZS5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGdldCBwaG9uZURvd24oKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuaW50ZXJuYWxQaG9uZURvd247XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTZXRzIHRoZSBwaG9uZSBkb3duIG1vZGUuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzZXQgcGhvbmVEb3duKGlucHV0OiBib29sZWFuKSB7XHJcbiAgICAgICAgdGhpcy5pbnRlcm5hbFBob25lRG93biA9ICEhaW5wdXQ7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSBwaG9uZSB1cCBtb2RlLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZ2V0IHBob25lVXAoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuaW50ZXJuYWxQaG9uZVVwO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogU2V0IHRoZSBwaG9uZSB1cCBtb2RlLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc2V0IHBob25lVXAoaW5wdXQ6IGJvb2xlYW4pIHtcclxuICAgICAgICB0aGlzLmludGVybmFsUGhvbmVVcCA9ICEhaW5wdXQ7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSByZWZsb3cgbW9kZS5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGdldCByZWZsb3dNb2RlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmludGVybmFsUmVmbG93TW9kZTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFNldHMgdGhlIHJlZmxvdyBtb2RlLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc2V0IHJlZmxvd01vZGUoaW5wdXQ6IGJvb2xlYW4pIHtcclxuICAgICAgICB0aGlzLmludGVybmFsUmVmbG93TW9kZSA9ICEhaW5wdXQ7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSB3aWR0aCBvZiB0aGUgd2luZG93IGZyb20gdGhlIHdpbmRvdyBvYmplY3QuXHJcbiAgICAgKiBTaG91bGQgb25seSBiZSBjYWxsZWQgb24gbGF5b3V0IG9yIHdpbmRvdyBzaXplIGNoYW5nZS5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGdldCB3aWR0aCgpOiBudW1iZXIge1xyXG4gICAgICAgIHJldHVybiB3aW5kb3c/LmlubmVyV2lkdGg7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSBoZWlnaHQgb2YgdGhlIHdpbmRvdyBmcm9tIHRoZSB3aW5kb3cgb2JqZWN0LlxyXG4gICAgICogU2hvdWxkIG9ubHkgYmUgY2FsbGVkIG9uIGxheW91dCBvciB3aW5kb3cgc2l6ZSBjaGFuZ2UuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBnZXQgaGVpZ2h0KCk6IG51bWJlciB7XHJcbiAgICAgICAgcmV0dXJuIHdpbmRvdz8uaW5uZXJIZWlnaHQ7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSBsYXN0IGtub3duIHdpbmRvdyByZXNwb25zaXZlIGRhdGEuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBnZXQgcHJldlNpemUoKTogU21lUmVzcG9uc2l2ZVdpbmRvd0RhdGEge1xyXG4gICAgICAgIGlmICh0aGlzLmludGVybmFsUHJldlNpemU/LndpZHRoID09PSB0aGlzLndpZHRoICYmIHRoaXMuaW50ZXJuYWxQcmV2U2l6ZT8uaGVpZ2h0ID09PSB0aGlzLmhlaWdodCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5pbnRlcm5hbFByZXZTaXplO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmdldFNtZVJlc3BvbnNpdmVXaW5kb3dEYXRhKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB0aGUgd2luZG93IHJlc3BvbnNpdmUgYnJlYWsgcG9pbnRzLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZ2V0IHNpemUoKTogU21lUmVzcG9uc2l2ZVdpbmRvd0JyZWFrcG9pbnRzIHtcclxuICAgICAgICBjb25zdCB3aWR0aCA9IHRoaXMud2lkdGg7XHJcbiAgICAgICAgaWYgKHdpZHRoIDw9IFNtZVJlc3BvbnNpdmVXaW5kb3dCcmVha3BvaW50c1ZhbHVlLlJlZmxvdykge1xyXG4gICAgICAgICAgICB0aGlzLnJlZmxvd01vZGUgPSB0cnVlO1xyXG4gICAgICAgICAgICB0aGlzLnBob25lRG93biA9IGZhbHNlO1xyXG4gICAgICAgICAgICB0aGlzLnBob25lVXAgPSBmYWxzZTtcclxuICAgICAgICAgICAgdGhpcy5yZXNwb25zaXZlV2luZG93U3RhdGUgPSBTbWVSZXNwb25zaXZlV2luZG93QnJlYWtwb2ludHMuUmVmbG93O1xyXG4gICAgICAgIH0gZWxzZSBpZiAod2lkdGggPD0gU21lUmVzcG9uc2l2ZVdpbmRvd0JyZWFrcG9pbnRzVmFsdWUuUGhvbmVEb3duKSB7XHJcbiAgICAgICAgICAgIHRoaXMucmVmbG93TW9kZSA9IGZhbHNlO1xyXG4gICAgICAgICAgICB0aGlzLnBob25lRG93biA9IHRydWU7XHJcbiAgICAgICAgICAgIHRoaXMucGhvbmVVcCA9IGZhbHNlO1xyXG4gICAgICAgICAgICB0aGlzLnJlc3BvbnNpdmVXaW5kb3dTdGF0ZSA9IFNtZVJlc3BvbnNpdmVXaW5kb3dCcmVha3BvaW50cy5QaG9uZURvd247XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5yZWZsb3dNb2RlID0gZmFsc2U7XHJcbiAgICAgICAgICAgIHRoaXMucGhvbmVEb3duID0gZmFsc2U7XHJcbiAgICAgICAgICAgIHRoaXMucGhvbmVVcCA9IHRydWU7XHJcbiAgICAgICAgICAgIHRoaXMucmVzcG9uc2l2ZVdpbmRvd1N0YXRlID0gU21lUmVzcG9uc2l2ZVdpbmRvd0JyZWFrcG9pbnRzLlBob25lVXA7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5yZXNwb25zaXZlV2luZG93U3RhdGU7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgbWFuYWdlciBzdXBwb3J0cyBsYXlvdXQgY29tcG9uZW50IGFuZCBpbiB0aGUgbWVhbnRpbWUgbGlzdGVuaW5nIHRvIHRoZSB3aW5kb3cgc2l6ZSBjaGFuZ2UgZXZlbnQuXHJcbiAgICAgKiBAcGFyYW0gbGF5b3V0IHRoZSBsYXlvdXQgY29tcG9uZW50LlxyXG4gICAgICovXHJcbiAgICBjb25zdHJ1Y3RvcihASW5qZWN0KFNNRV9MQVlPVVRfUFJPVklERVIpIHByaXZhdGUgbGF5b3V0PzogTGF5b3V0KSB7XHJcbiAgICAgICAgdGhpcy5zZXRJc0Nzc1YyRW5hYmxlZCgpO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5sYXlvdXQpIHtcclxuICAgICAgICAgICAgLy8gb24gcGFyZW50IGxheW91dCBjaGFuZ2VzLCByZS1lbWl0IHRoZSBsYXlvdXQgY2hhbmdlIHRvIG91ciBldmVudFxyXG4gICAgICAgICAgICB0aGlzLnN1YnNjcmlwdGlvbnMucHVzaChsYXlvdXQubGF5b3V0Q2hhbmdlZC5zdWJzY3JpYmUoKCgpID0+IHRoaXMub25MYXlvdXRDaGFuZ2VkKCkpKSk7XHJcbiAgICAgICAgICAgIC8vIG9uIHdpbmRvdyBicmVhayBwb2ludCBjaGFuZ2VzLCBlbWl0IHRoZSBldmVudCBhYm91dCBjcml0aWNhbCBjbGFzc2VzIGFuZCBzdHlsaW5nIHVwZGF0ZXMgc2lnbmFsLlxyXG4gICAgICAgICAgICB0aGlzLnN1YnNjcmlwdGlvbnMucHVzaChsYXlvdXQud2luZG93QnJlYWtwb2ludENoYW5nZWQuc3Vic2NyaWJlKCgpID0+IHRoaXMub25XaW5kb3dCcmVha3BvaW50Q2hhbmdlZCgpKSk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLmRlZmVycmVkT25MYXlvdXRDaGFuZ2VkKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogSXQgc2V0cyB3aGV0aGVyIHRoZSBjdXJyZW50IHNvbHV0aW9uL3Rvb2wgaXMgdXNpbmcgdGhlIGNzcyB2MiBmb3Igd2luZG93IHJlc3BvbnNpdmVuZXNzLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc2V0SXNDc3NWMkVuYWJsZWQoKSB7XHJcbiAgICAgICAgdGhpcy5jc3NWMiA9IHRoaXMuaXNVc2luZ0Nzc1YyKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgaW1wbGVtZW50YXRpb24gZm9yIGNoZWNraW5nIHdoZXRoZXIgdGhlIHN0eWxlcyBhcmUgYmVpbmcgc2V0LlxyXG4gICAgICogQHJldHVybnMgdHJ1ZSBpZiB0aGUgY3VycmVudCB0b29sL3NvbHV0aW9uIGlzIHVzaW5nIGNzcyB2MiBmb3Igd2luZG93IHJlc3BvbnNpdmVuZXNzLlxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGlzVXNpbmdDc3NWMigpOiBib29sZWFuIHtcclxuICAgICAgICBjb25zdCBoZWFkID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2hlYWQnKVswXTtcclxuICAgICAgICBjb25zdCBsaW5rcyA9IGhlYWQucXVlcnlTZWxlY3RvckFsbCgnbGluaycpO1xyXG4gICAgICAgIGxldCBjc3NWMiA9IHRydWU7XHJcblxyXG4gICAgICAgIC8vIHNtZSBzaGVsbCByb290IHdvdWxkIGJlIGNvbnRhaW5pbmcgc3R5bGUuY3NzIGFuZCBlaXRoZXIgbWFpbi5jc3Mgb3IgbWFpbi12Mi5jc3NcclxuICAgICAgICAvLyB0aHVzIGFzIGxvbmcgYXMgaXQgaXMgbm90IG1haW4uY3NzLCBzaG91bGQgYmUgdXNpbmcgY3NzLXYyXHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsaW5rcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBjb25zdCBsaW5rID0gbGlua3NbaV07XHJcbiAgICAgICAgICAgIGlmIChsaW5rLmhyZWYgJiYgbGluay5ocmVmLmluY2x1ZGVzKCdtYWluLmNzcycpKSB7XHJcbiAgICAgICAgICAgICAgICBjc3NWMiA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBjc3NWMjtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBmdW5jdGlvbmFsaXR5IHRvIHVwZGF0ZSB0aGUgY29yZSB2YXJpYWJsZXMgZm9yIHdpbmRvdyByZXNwb25zaXZlIGRhdGEuXHJcbiAgICAgKiBAcmV0dXJucyBUaGUgU21lUmVzcG9uc2l2ZVdpbmRvd0RhdGEgb2JqZWN0XHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBnZXRTbWVSZXNwb25zaXZlV2luZG93RGF0YSgpOiBTbWVSZXNwb25zaXZlV2luZG93RGF0YSB7XHJcbiAgICAgICAgLy8gb24gd2luZG93IHNpemUgb3IgbGF5b3V0IGNoYW5nZSwgZ2V0cyB0aGUgd2lkdGggYW5kIGhlaWdodCBmcm9tIHRoZSB3aW5kb3cgb2JqZWN0LlxyXG4gICAgICAgIGNvbnN0IHdpZHRoID0gdGhpcy53aWR0aDtcclxuICAgICAgICBjb25zdCBoZWlnaHQgPSB0aGlzLmhlaWdodDtcclxuXHJcbiAgICAgICAgLy8gYmFzZWQgb24gdGhlIHdpbmRvdyBzaXplIGluZm9ybWF0aW9uLCBjYWxjdWxhdGVzIHRoZSBjb3JlIHBhcmFtdGVycy5cclxuICAgICAgICBjb25zdCBzaXplID0gdGhpcy5zaXplO1xyXG5cclxuICAgICAgICAvLyB0aGUgMyBnZXRzIGFib3ZlIHNldHMgdGhlc2UgZm9sbG93aW5nIDMgcGFyYW1ldGVycy5cclxuICAgICAgICBjb25zdCByZWZsb3dNb2RlID0gdGhpcy5yZWZsb3dNb2RlO1xyXG4gICAgICAgIGNvbnN0IHBob25lRG93biA9IHRoaXMucGhvbmVEb3duO1xyXG4gICAgICAgIGNvbnN0IHBob25lVXAgPSB0aGlzLnBob25lVXA7XHJcblxyXG4gICAgICAgIC8vIHNldHMgdGhlIG9iamVjdCBhbmQgcmV0dXJuLlxyXG4gICAgICAgIHRoaXMuaW50ZXJuYWxQcmV2U2l6ZSA9ICB7XHJcbiAgICAgICAgICAgIHdpZHRoOiB3aWR0aCxcclxuICAgICAgICAgICAgaGVpZ2h0OiBoZWlnaHQsXHJcbiAgICAgICAgICAgIHNpemU6IHNpemUsXHJcbiAgICAgICAgICAgIHJlZmxvd01vZGU6IHJlZmxvd01vZGUsXHJcbiAgICAgICAgICAgIHBob25lRG93bjogcGhvbmVEb3duLFxyXG4gICAgICAgICAgICBwaG9uZVVwOiBwaG9uZVVwXHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuaW50ZXJuYWxQcmV2U2l6ZTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIE9uIGxheW91dCBjaGFuZ2VkIGV2ZW50IGhhbmRsZXIsIG9jY3VycyBldmVyeSB0aW1lIHRoZSBsYXlvdXQgaGFzIGJlZW4gY2hhbmdlZC5cclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBvbkxheW91dENoYW5nZWQoKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5nZXRTbWVSZXNwb25zaXZlV2luZG93RGF0YSgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIGRlZmVycmVkIGxheW91dCBjaGFuZ2VkIGhhbmRsZXIuXHJcbiAgICAgKi9cclxuICAgIEBEZWJvdW5jZSgpXHJcbiAgICBwdWJsaWMgZGVmZXJyZWRPbkxheW91dENoYW5nZWQoKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5vbkxheW91dENoYW5nZWQoKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFRvIHJlc3BvbmQgdG8gYSBsYXlvdXQgYnJlYWtwb2ludCBjaGFuZ2VkIGV2ZW50LlxyXG4gICAgICogQHJldHVybnMgdm9pZFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgb25XaW5kb3dCcmVha3BvaW50Q2hhbmdlZCgpOiB2b2lkIHtcclxuICAgICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSBwYXJlbnQgZWxlbWVudCBieSBodG1sIHRhZy4gQnkgZGVmYXVsdCwgZ28gdXAgMTAgbGV2ZWxzIGZvciBlbmhhbmNlZCBwZXJmb3JtYW5jZS5cclxuICAgICAqIEBwYXJhbSBpbnB1dEVsZW1lbnQgVGhlIGlucHV0IGVsZW1lbnQuXHJcbiAgICAgKiBAcmV0dXJucyBUaGUgdGFyZ2V0ZWQgaHRtbCBlbGVtZW50IGdldCBieSB0aGUgaHRtbCB0YWdcclxuICAgICAqL1xyXG4gICAgcHVibGljIGdldFBhcmVudEVsZW1lbnRCeVRhZyhpbnB1dEVsZW1lbnQ6IEhUTUxFbGVtZW50LFxyXG4gICAgICAgIHBhcmVudEh0bWxUYWdzID0gWydzbWUtcGl2b3QnLCAnc21lLXNwbGl0LXZpZXcnLCAnc21lLXNldHRpbmdzLXBhZ2UnXSxcclxuICAgICAgICBsZXZlbEV4dGVybmFsID0gMTAsXHJcbiAgICAgICAgY3VzdG9tS2V5d29yZHM/OiBzdHJpbmcsXHJcbiAgICAgICAgdW50aWxUYWdOYW1lPzogc3RyaW5nKTogSFRNTEVsZW1lbnQge1xyXG5cclxuICAgICAgICAgICAgaWYgKCFpbnB1dEVsZW1lbnQpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGxldCBsZXZlbCA9IGxldmVsRXh0ZXJuYWw7XHJcbiAgICAgICAgICAgIGxldCBmb3VuZCA9IGZhbHNlO1xyXG4gICAgICAgICAgICBsZXQgcGFyZW50ID0gaW5wdXRFbGVtZW50O1xyXG4gICAgICAgICAgICB3aGlsZSAobGV2ZWwgPiAwICYmICFmb3VuZCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHBhcmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHBhcmVudCA9IHBhcmVudC5wYXJlbnRFbGVtZW50O1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGNvbnN0IHBhcmVudFRhZ05hbWUgPSBwYXJlbnQ/LnRhZ05hbWUudG9Mb2NhbGVMb3dlckNhc2UoKTtcclxuICAgICAgICAgICAgICAgIGlmICh1bnRpbFRhZ05hbWUpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAocGFyZW50VGFnTmFtZSA9PT0gdW50aWxUYWdOYW1lLnRvTG93ZXJDYXNlKCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKHBhcmVudEh0bWxUYWdzLmluY2x1ZGVzKHBhcmVudFRhZ05hbWUpIHx8IChjdXN0b21LZXl3b3JkcyAhPT0gdW5kZWZpbmVkICYmIHBhcmVudFRhZ05hbWU/LmluY2x1ZGVzKGN1c3RvbUtleXdvcmRzKSkpIHtcclxuICAgICAgICAgICAgICAgICAgICBmb3VuZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHBhcmVudDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGxldmVsIC09IDE7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgY29yZSBhbGdvcml0aG0gZm9yIGFkZGluZyBhbmQgcmVtb3ZpbmcgY2xhc3NlcyBiYXNlZCBvbiB3aW5kb3cgc2l6ZSBhbmQgd2luZG93IHNpemUgc2V0dGluZ3MuXHJcbiAgICAgKiBAcGFyYW0gc2V0dGluZ3MgdGhlIHNldHRpbmdzIG9iamVjdFxyXG4gICAgICogQHBhcmFtIGN1clNldHRpbmdzIHRoZSBjdXJyZW50IHNldHRpbmdcclxuICAgICAqIEBwYXJhbSBlbGVtZW50IHRoZSBodG1sIGVsZW1lbnQgZm9yIHNldHRpbmcgdXAgY2xhc3Nlcy5cclxuICAgICAqIEByZXR1cm5zIHZvaWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyB1cGRhdGVDbGFzc0FycmF5T25XaW5kb3dTaXplKHNldHRpbmdzOiBhbnksIGN1clNldHRpbmdzOiBzdHJpbmcsIGVsZW1lbnQ6IEhUTUxFbGVtZW50KTogdm9pZCB7XHJcbiAgICAgICAgaWYgKCFzZXR0aW5ncykge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBzZXR0aW5ncyA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoc2V0dGluZ3MpKTtcclxuICAgICAgICBjb25zdCBwaG9uZURvd24gPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHNldHRpbmdzLnBob25lRG93bikpO1xyXG4gICAgICAgIGNvbnN0IHBob25lVXAgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHNldHRpbmdzLnBob25lVXApKTtcclxuICAgICAgICBjb25zdCByZWZsb3cgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHNldHRpbmdzLnJlZmxvdykpO1xyXG5cclxuICAgICAgICBsZXQgdG9CZVJlbW92ZWRDbGFzc0xpc3QgPSBbXTtcclxuICAgICAgICBsZXQgdG9CZUFkZGVkQ2xhc3NMaXN0ID0gW107XHJcblxyXG4gICAgICAgIHN3aXRjaCAoY3VyU2V0dGluZ3MpIHtcclxuICAgICAgICAgICAgY2FzZSAncGhvbmVVcCc6XHJcbiAgICAgICAgICAgICAgICB0b0JlQWRkZWRDbGFzc0xpc3QgPSBwaG9uZVVwO1xyXG4gICAgICAgICAgICAgICAgdG9CZVJlbW92ZWRDbGFzc0xpc3QgPSBwaG9uZURvd247XHJcbiAgICAgICAgICAgICAgICB0b0JlUmVtb3ZlZENsYXNzTGlzdCA9IHRoaXMudW5pcXVlQXJyYXkodG9CZVJlbW92ZWRDbGFzc0xpc3QsIHJlZmxvdyk7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgY2FzZSAncGhvbmVEb3duJzpcclxuICAgICAgICAgICAgICAgIHRvQmVBZGRlZENsYXNzTGlzdCA9IHBob25lRG93bjtcclxuICAgICAgICAgICAgICAgIHRvQmVSZW1vdmVkQ2xhc3NMaXN0ID0gcGhvbmVVcDtcclxuICAgICAgICAgICAgICAgIHRvQmVSZW1vdmVkQ2xhc3NMaXN0ID0gdGhpcy51bmlxdWVBcnJheSh0b0JlUmVtb3ZlZENsYXNzTGlzdCwgcmVmbG93KTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBjYXNlICdyZWZsb3cnOlxyXG4gICAgICAgICAgICAgICAgdG9CZUFkZGVkQ2xhc3NMaXN0ID0gcmVmbG93O1xyXG4gICAgICAgICAgICAgICAgdG9CZVJlbW92ZWRDbGFzc0xpc3QgPSBwaG9uZURvd247XHJcbiAgICAgICAgICAgICAgICB0b0JlUmVtb3ZlZENsYXNzTGlzdCA9IHRoaXMudW5pcXVlQXJyYXkodG9CZVJlbW92ZWRDbGFzc0xpc3QsIHBob25lVXApO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0b0JlUmVtb3ZlZENsYXNzTGlzdCA9IHRoaXMucmVtb3ZlRXhpc3RlZEl0ZW0odG9CZVJlbW92ZWRDbGFzc0xpc3QsIHRvQmVBZGRlZENsYXNzTGlzdCk7XHJcblxyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdG9CZVJlbW92ZWRDbGFzc0xpc3QubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgaWYgKGVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKHRvQmVSZW1vdmVkQ2xhc3NMaXN0W2ldKSkge1xyXG4gICAgICAgICAgICAgICAgZWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKHRvQmVSZW1vdmVkQ2xhc3NMaXN0W2ldKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0b0JlQWRkZWRDbGFzc0xpc3QubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgaWYgKCFlbGVtZW50LmNsYXNzTGlzdC5jb250YWlucyh0b0JlQWRkZWRDbGFzc0xpc3RbaV0pKSB7XHJcbiAgICAgICAgICAgICAgICBlbGVtZW50LmNsYXNzTGlzdC5hZGQodG9CZUFkZGVkQ2xhc3NMaXN0W2ldKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIE1lcmdlIHR3byBhcnJheXMgd2l0aCB1bmlxdWUgaXRlbXMuXHJcbiAgICAgKiBAcGFyYW0gYXJyYXlBIHRoZSBpbnB1dCBhcnJheSBBXHJcbiAgICAgKiBAcGFyYW0gYXJyYXlCIHRoZSBpbnB1dCBhcnJheSBCXHJcbiAgICAgKiBAcmV0dXJucyBhbiBhcnJheSB0aGF0IGNvbnRhaW5zIHVuaXF1ZSBpdGVtcyBmcm9tIGFycmF5IEEgYW5kIGFycmF5IEJcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSB1bmlxdWVBcnJheShhcnJheUE6IHN0cmluZ1tdLCBhcnJheUI6IHN0cmluZ1tdKTogc3RyaW5nW10ge1xyXG4gICAgICAgIGlmIChhcnJheUIgJiYgYXJyYXlCLmxlbmd0aCkge1xyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFycmF5Qi5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFhcnJheUEuaW5jbHVkZXMoYXJyYXlCW2ldKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGFycmF5QS5wdXNoKGFycmF5QltpXSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBhcnJheUE7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHdWFyYW50ZWVzIHdpbGwgbm90IHJlbW92ZSB0aGUgY2xhc3NlcyB0aGF0IG5lZWRzIHRvIGJlIGFkZGVkLlxyXG4gICAgICogQHBhcmFtIHRvQmVSZW1vdmVkQ2xhc3NMaXN0IHRoZSBsaXN0IG9mIGNsYXNzZXMgdGhhdCBuZWVkcyB0byBiZSByZW1vdmVkLlxyXG4gICAgICogQHBhcmFtIHRvQmVBZGRlZENsYXNzTGlzdCB0aGUgbGlzdCBvZiBjbGFzc2VzIHRoYXQgbmVlZHMgdG8gYmUgYWRkZWQuXHJcbiAgICAgKiBAcmV0dXJucyB0aGUgbGlzdCBvZiBjbGFzc2VzIHRoYXQgbmVlZHMgdG8gYmUgcmVtb3ZlZCBhbmQgZG9lc24ndCBvdmVybGFwIHdpdGggdGhlIGNsYXNzZXMgdGhhdCBuZWVkcyB0byBiZSBhZGRlZC5cclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSByZW1vdmVFeGlzdGVkSXRlbSh0b0JlUmVtb3ZlZENsYXNzTGlzdDogc3RyaW5nW10sIHRvQmVBZGRlZENsYXNzTGlzdDogc3RyaW5nW10pOiBzdHJpbmdbXSB7XHJcbiAgICAgICAgaWYgKCF0b0JlQWRkZWRDbGFzc0xpc3QgfHwgIXRvQmVBZGRlZENsYXNzTGlzdC5sZW5ndGgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRvQmVSZW1vdmVkQ2xhc3NMaXN0O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKCF0b0JlUmVtb3ZlZENsYXNzTGlzdCB8fCAhdG9CZVJlbW92ZWRDbGFzc0xpc3QubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBbXTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IHJlcyA9IFtdO1xyXG5cclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRvQmVSZW1vdmVkQ2xhc3NMaXN0Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGlmICghdG9CZUFkZGVkQ2xhc3NMaXN0LmluY2x1ZGVzKHRvQmVSZW1vdmVkQ2xhc3NMaXN0W2ldKSkge1xyXG4gICAgICAgICAgICAgICAgcmVzLnB1c2godG9CZVJlbW92ZWRDbGFzc0xpc3RbaV0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gcmVzO1xyXG4gICAgfVxyXG59XHJcbiJdfQ==