@microsoft/windows-admin-center-sdk
Version:
Microsoft - Windows Admin Center Shell
373 lines • 45.3 kB
JavaScript
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==