UNPKG

@catull/igniteui-angular

Version:

Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps

776 lines 107 kB
import { __decorate, __extends, __metadata, __read, __spread } from "tslib";
import { ChangeDetectionStrategy, Component, HostBinding, Input, forwardRef, TemplateRef, ViewChild, ViewChildren, QueryList, ContentChildren, ElementRef, EventEmitter, Output } from '@angular/core';
import { IgxGridBaseDirective } from '../grid-base.directive';
import { GridBaseAPIService } from '../api.service';
import { IgxHierarchicalGridAPIService } from './hierarchical-grid-api.service';
import { IgxRowIslandComponent } from './row-island.component';
import { IgxChildGridRowComponent } from './child-grid-row.component';
import { IgxFilteringService } from '../filtering/grid-filtering.service';
import { DisplayDensity } from '../../core/displayDensity';
import { IgxHierarchicalGridNavigationService } from './hierarchical-grid-navigation.service';
import { IgxGridSummaryService } from '../summaries/grid-summary.service';
import { IgxHierarchicalGridBaseDirective } from './hierarchical-grid-base.directive';
import { takeUntil } from 'rxjs/operators';
import { IgxTemplateOutletDirective } from '../../directives/template-outlet/template_outlet.directive';
import { IgxGridSelectionService, IgxGridCRUDService } from '../selection/selection.service';
import { IgxTransactionService } from '../../services/index';
import { IgxForOfSyncService, IgxForOfScrollSyncService } from '../../directives/for-of/for_of.sync.service';
import { IgxRowIslandAPIService } from './row-island-api.service';
var NEXT_ID = 0;
var IgxHierarchicalGridComponent = /** @class */ (function (_super) {
    __extends(IgxHierarchicalGridComponent, _super);
    function IgxHierarchicalGridComponent() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        /**
         *@hidden
         */
        _this.hierarchicalStateChange = new EventEmitter();
        /**
         * @hidden
         */
        _this.childLayoutKeys = [];
        /**
         * @hidden
         */
        _this.highlightedRowID = null;
        /**
         * @hidden
         */
        _this.updateOnRender = false;
        /**
         * @hidden
         */
        _this.parent = null;
        _this._hierarchicalState = [];
        _this._filteredData = null;
        _this.h_id = "igx-hierarchical-grid-" + NEXT_ID++;
        _this.childGridTemplates = new Map();
        _this.scrollTop = 0;
        _this.scrollLeft = 0;
        return _this;
    }
    IgxHierarchicalGridComponent_1 = IgxHierarchicalGridComponent;
    Object.defineProperty(IgxHierarchicalGridComponent.prototype, "id", {
        /**
         * Sets the value of the `id` attribute. If not provided it will be automatically generated.
         * ```html
         * <igx-hierarchical-grid [id]="'igx-hgrid-1'" [data]="Data" [autoGenerate]="true"></igx-hierarchical-grid>
         * ```
         * @memberof IgxHierarchicalGridComponent
         */
        get: function () {
            return this.h_id;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(IgxHierarchicalGridComponent.prototype, "data", {
        /**
         * Returns an array of data set to the `IgxHierarchicalGridComponent`.
         * ```typescript
         * let filteredData = this.grid.filteredData;
         * ```
         * @memberof IgxHierarchicalGridComponent
         */
        get: function () {
            return this._data;
        },
        /**
         * An @Input property that lets you fill the `IgxHierarchicalGridComponent` with an array of data.
         * ```html
         * <igx-hierarchical-grid [data]="Data" [autoGenerate]="true"></igx-hierarchical-grid>
         * ```
         * @memberof IgxHierarchicalGridComponent
         */
        set: function (value) {
            this._data = value || [];
            this.summaryService.clearSummaryCache();
            if (this.shouldGenerate) {
                this.setupColumns();
                this.reflow();
            }
            this.cdr.markForCheck();
            if (this.parent && (this.height === null || this.height.indexOf('%') !== -1)) {
                // If the height will change based on how much data there is, recalculate sizes in igxForOf.
                this.notifyChanges(true);
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(IgxHierarchicalGridComponent.prototype, "hierarchicalState", {
        /**
        * Sets the state of the `IgxHierarchicalGridComponent` containing which rows are expanded.
        * ```typescript
        * this.gridState = [{ rowID: 1 }, { rowID: 4}];
        * ```
        * ```html
        * <igx-hierarchical-grid [primaryKey]="'ID'" [data]="Data" [autoGenerate]="false" [hierarchicalState]="hgridState">
        *      <igx-column field="ID"  [dataType]='number'></igx-column>
        *      <igx-column field="Product"  [dataType]='string'></igx-column>
        *      <igx-column field="Description"  [dataType]='string'></igx-column>
        * </igx-hierarchical-grid>
        * ```
        *
        * Two-way data binding.
        * ```html
        * <igx-hierarchical-grid [primaryKey]="'ID'" [data]="Data" [autoGenerate]="false" [(hierarchicalState)]="hgridState">
        *      <igx-column field="ID"  [dataType]='number'></igx-column>
        *      <igx-column field="Product"  [dataType]='string'></igx-column>
        *      <igx-column field="Description"  [dataType]='string'></igx-column>
        * </igx-hierarchical-grid>
        * ```
        * @memberof IgxHierarchicalGridComponent
        */
        get: function () {
            return this._hierarchicalState;
        },
        set: function (val) {
            var _this = this;
            if (this._hierarchicalState !== val) {
                this.hierarchicalStateChange.emit(val);
            }
            if (this.hasChildrenKey) {
                val = val.filter(function (item) {
                    var rec = _this.primaryKey ? _this.data.find(function (x) { return x[_this.primaryKey] === item.rowID; }) : item.rowID;
                    return rec[_this.hasChildrenKey];
                });
            }
            this._hierarchicalState = val;
            if (this.parent) {
                this.notifyChanges(true);
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(IgxHierarchicalGridComponent.prototype, "filteredData", {
        /**
         * Returns an array of objects containing the filtered data in the `IgxHierarchicalGridComponent`.
         * ```typescript
         * let filteredData = this.grid.filteredData;
         * ```
         * @memberof IgxHierarchicalGridComponent
         */
        get: function () {
            return this._filteredData;
        },
        /**
         * Sets an array of objects containing the filtered data in the `IgxHierarchicalGridComponent`.
         * ```typescript
         * this.grid.filteredData = [{
         *       ID: 1,
         *       Name: "A"
         * }];
         * ```
         * @memberof IgxHierarchicalGridComponent
         */
        set: function (value) {
            this._filteredData = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(IgxHierarchicalGridComponent.prototype, "expandChildren", {
        /**
         * Gets if all immediate children of the `IgxHierarchicalGridComponent` previously have been set to be expanded/collapsed.
         * If previously set and some rows have been manually expanded/collapsed it will still return the last set value.
         * ```typescript
         * const expanded = this.grid.expandChildren;
         * ```
         * @memberof IgxHierarchicalGridComponent
         */
        get: function () {
            return this._expandChildren;
        },
        /**
         * Sets if all immediate children of the `IgxHierarchicalGridComponent` should be expanded/collapsed.
         * Defult value is false.
         * ```html
         * <igx-hierarchical-grid [id]="'igx-grid-1'" [data]="Data" [autoGenerate]="true" [expandChildren]="true"></igx-hierarchical-grid>
         * ```
         * @memberof IgxHierarchicalGridComponent
         */
        set: function (value) {
            var _this = this;
            this._expandChildren = value;
            if (value && this.data) {
                this.hierarchicalState = this.data.map(function (rec) {
                    return { rowID: _this.primaryKey ? rec[_this.primaryKey] : rec };
                });
            }
            else if (this.data) {
                this.hierarchicalState = [];
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(IgxHierarchicalGridComponent.prototype, "foreignKey", {
        /**
         * Gets the unique identifier of the parent row. It may be a `string` or `number` if `primaryKey` of the
         * parent grid is set or an object reference of the parent record otherwise.
         * ```typescript
         * const foreignKey = this.grid.foreignKey;
         * ```
         * @memberof IgxHierarchicalGridComponent
         */
        get: function () {
            if (!this.parent) {
                return null;
            }
            return this.parent.hgridAPI.getParentRowId(this);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(IgxHierarchicalGridComponent.prototype, "hasExpandableChildren", {
        /**
         * @hidden
         */
        get: function () {
            return !!this.childLayoutKeys.length;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * @hidden
     */
    IgxHierarchicalGridComponent.prototype.ngOnInit = function () {
        if (this._transactions instanceof IgxTransactionService) {
            // transaction service cannot be injected in a derived class in a factory manner
            this._transactions = new IgxTransactionService();
        }
        _super.prototype.ngOnInit.call(this);
    };
    IgxHierarchicalGridComponent.prototype.ngDoCheck = function () {
        if (this._cdrRequestRepaint && !this._init) {
            this.updateSizes();
        }
        _super.prototype.ngDoCheck.call(this);
    };
    /**
     * @hidden
     */
    IgxHierarchicalGridComponent.prototype.ngAfterViewInit = function () {
        var _this = this;
        _super.prototype.ngAfterViewInit.call(this);
        this.verticalScrollContainer.getScroll().addEventListener('scroll', this.hg_verticalScrollHandler.bind(this));
        this.headerContainer.getScroll().addEventListener('scroll', this.hg_horizontalScrollHandler.bind(this));
        if (this.expandChildren && this.data && this.hierarchicalState.length !== this.data.length) {
            this.hierarchicalState = this.data.map(function (rec) {
                return { rowID: _this.primaryKey ? rec[_this.primaryKey] : rec };
            });
            this.cdr.detectChanges();
        }
        this.verticalScrollContainer.onBeforeViewDestroyed.pipe(takeUntil(this.destroy$)).subscribe(function (view) {
            var rowData = view.context.$implicit;
            if (_this.isChildGridRecord(rowData)) {
                var cachedData = _this.childGridTemplates.get(rowData.rowID);
                if (cachedData) {
                    var tmlpOutlet = cachedData.owner;
                    tmlpOutlet._viewContainerRef.detach(0);
                }
            }
        });
        if (this.parent) {
            this._displayDensity = this.rootGrid._displayDensity;
            this.rootGrid.onDensityChanged.pipe(takeUntil(this.destroy$)).subscribe(function () {
                _this._displayDensity = _this.rootGrid._displayDensity;
                _this.notifyChanges(true);
                _this.cdr.markForCheck();
            });
            this.childLayoutKeys = this.parentIsland.children.map(function (item) { return item.key; });
        }
        this.toolbarCustomContentTemplates = this.parentIsland ?
            this.parentIsland.toolbarCustomContentTemplates :
            this.toolbarCustomContentTemplates;
        this.headSelectorsTemplates = this.parentIsland ?
            this.parentIsland.headSelectorsTemplates :
            this.headSelectorsTemplates;
        this.rowSelectorsTemplates = this.parentIsland ?
            this.parentIsland.rowSelectorsTemplates :
            this.rowSelectorsTemplates;
        this.dragIndicatorIconTemplate = this.parentIsland ?
            this.parentIsland.dragIndicatorIconTemplate :
            this.dragIndicatorIconTemplate;
        this.rowExpandedIndicatorTemplate = this.rootGrid.rowExpandedIndicatorTemplate;
        this.rowCollapsedIndicatorTemplate = this.rootGrid.rowCollapsedIndicatorTemplate;
        this.headerCollapseIndicatorTemplate = this.rootGrid.headerCollapseIndicatorTemplate;
        this.headerExpandIndicatorTemplate = this.rootGrid.headerExpandIndicatorTemplate;
        this.hasChildrenKey = this.parentIsland ?
            this.parentIsland.hasChildrenKey || this.rootGrid.hasChildrenKey :
            this.rootGrid.hasChildrenKey;
        this.showExpandAll = this.parentIsland ?
            this.parentIsland.showExpandAll : this.rootGrid.showExpandAll;
    };
    IgxHierarchicalGridComponent.prototype.updateSizes = function () {
        if (document.body.contains(this.nativeElement) && this.isPercentWidth) {
            this.reflow();
            this.hgridAPI.getChildGrids(false).forEach(function (grid) {
                grid.updateSizes();
            });
        }
    };
    IgxHierarchicalGridComponent.prototype._shouldAutoSize = function (renderedHeight) {
        if (this.isPercentHeight && this.parent) {
            return true;
        }
        return _super.prototype._shouldAutoSize.call(this, renderedHeight);
    };
    Object.defineProperty(IgxHierarchicalGridComponent.prototype, "outletDirective", {
        get: function () {
            return this.rootGrid._outletDirective;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * @hidden
     */
    IgxHierarchicalGridComponent.prototype.ngAfterContentInit = function () {
        var _this = this;
        this.updateColumnList(false);
        this.childLayoutKeys = this.parent ?
            this.parentIsland.children.map(function (item) { return item.key; }) :
            this.childLayoutKeys = this.childLayoutList.map(function (item) { return item.key; });
        this.childLayoutList.notifyOnChanges();
        this.childLayoutList.changes.pipe(takeUntil(this.destroy$))
            .subscribe(function () { return _this.onRowIslandChange(); });
        _super.prototype.ngAfterContentInit.call(this);
    };
    /**
    * @hidden
    */
    IgxHierarchicalGridComponent.prototype.onRowIslandChange = function () {
        if (this.parent) {
            this.childLayoutKeys = this.parentIsland.children.filter(function (item) { return !item._destroyed; }).map(function (item) { return item.key; });
        }
        else {
            this.childLayoutKeys = this.childLayoutList.filter(function (item) { return !item._destroyed; }).map(function (item) { return item.key; });
        }
        if (!this.cdr.destroyed) {
            this.cdr.detectChanges();
        }
    };
    IgxHierarchicalGridComponent.prototype.onColumnsChanged = function (change) {
        var _this = this;
        this.updateColumnList();
        var cols = change.filter(function (c) { return c.gridAPI.grid === _this; });
        if (cols.length > 0) {
            this.columnList.reset(cols);
            _super.prototype.onColumnsChanged.call(this, this.columnList);
        }
    };
    IgxHierarchicalGridComponent.prototype.updateColumnList = function (recalcColSizes) {
        if (recalcColSizes === void 0) { recalcColSizes = true; }
        var childLayouts = this.parent ? this.childLayoutList : this.allLayoutList;
        var nestedColumns = childLayouts.map(function (layout) {
            return layout.columnList.toArray();
        });
        var colsArray = [].concat.apply([], nestedColumns);
        var colLength = this.columnList.length;
        if (colsArray.length > 0) {
            var topCols = this.columnList.filter(function (item) {
                return colsArray.indexOf(item) === -1;
            });
            this.columnList.reset(topCols);
            if (recalcColSizes && this.columnList.length !== colLength) {
                this.calculateGridSizes();
            }
        }
    };
    IgxHierarchicalGridComponent.prototype.ngOnDestroy = function () {
        if (!this.parent) {
            this.hgridAPI.getChildGrids(true).forEach(function (grid) {
                if (!grid.childRow.cdr.destroyed) {
                    grid.childRow.cdr.destroy();
                }
            });
        }
        if (this.parent && this.selectionService.activeElement) {
            // in case selection is in destroyed child grid, selection should be cleared.
            this._clearSeletionHighlights();
        }
        _super.prototype.ngOnDestroy.call(this);
    };
    IgxHierarchicalGridComponent.prototype._clearSeletionHighlights = function () {
        __spread([this.rootGrid], this.rootGrid.getChildGrids(true)).forEach(function (grid) {
            grid.selectionService.clear();
            grid.selectionService.activeElement = null;
            grid.nativeElement.classList.remove('igx-grid__tr--highlighted');
            grid.highlightedRowID = null;
            grid.cdr.markForCheck();
        });
    };
    Object.defineProperty(IgxHierarchicalGridComponent.prototype, "template", {
        /**
        * @hidden
        */
        get: function () {
            if (this.filteredData && this.filteredData.length === 0) {
                return this.emptyGridTemplate ? this.emptyGridTemplate : this.emptyFilteredGridTemplate;
            }
            if (this.isLoading && (!this.data || this.dataLength === 0)) {
                return this.loadingGridTemplate ? this.loadingGridTemplate : this.loadingGridDefaultTemplate;
            }
            if (this.dataLength === 0) {
                return this.emptyGridTemplate ? this.emptyGridTemplate : this.emptyGridDefaultTemplate;
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * @hidden
     * Gets the combined width of the columns that are specific to the enabled grid features. They are fixed.
     * TODO: Remove for Angular 8. Calling parent class getter using super is not supported for now.
     */
    IgxHierarchicalGridComponent.prototype.getFeatureColumnsWidth = function () {
        var width = _super.prototype.getFeatureColumnsWidth.call(this);
        if (this.hasExpandableChildren) {
            width += this.headerHierarchyExpander.nativeElement.offsetWidth || this.getDefaultExpanderWidth();
        }
        return width;
    };
    IgxHierarchicalGridComponent.prototype.getDefaultExpanderWidth = function () {
        switch (this.displayDensity) {
            case DisplayDensity.cosy:
                return 57;
            case DisplayDensity.compact:
                return 49;
            default:
                return 72;
        }
    };
    /**
     * @hidden
     */
    IgxHierarchicalGridComponent.prototype.isRowHighlighted = function (rowData) {
        return this.highlightedRowID === rowData.rowID;
    };
    /**
     * @hidden
     */
    IgxHierarchicalGridComponent.prototype.isHierarchicalRecord = function (record) {
        return this.childLayoutList.length !== 0 && record[this.childLayoutList.first.key];
    };
    /**
     * @hidden
     */
    IgxHierarchicalGridComponent.prototype.isChildGridRecord = function (record) {
        // Can be null when there is defined layout but no child data was found
        return record.childGridsData !== undefined;
    };
    /**
     * @hidden
     */
    IgxHierarchicalGridComponent.prototype.trackChanges = function (index, rec) {
        if (rec.childGridsData !== undefined) {
            // if is child rec
            return rec.rowID;
        }
        return rec;
    };
    /**
     * @hidden
     */
    IgxHierarchicalGridComponent.prototype.getContext = function (rowData) {
        if (this.isChildGridRecord(rowData)) {
            var cachedData = this.childGridTemplates.get(rowData.rowID);
            if (cachedData) {
                var view = cachedData.view;
                var tmlpOutlet = cachedData.owner;
                return {
                    $implicit: rowData,
                    moveView: view,
                    owner: tmlpOutlet,
                    index: this.dataView.indexOf(rowData)
                };
            }
            else {
                var rowID = this.primaryKey ? rowData.rowID : this.data.indexOf(rowData.rowID);
                // child rows contain unique grids, hence should have unique templates
                return {
                    $implicit: rowData,
                    templateID: 'childRow-' + rowID,
                    index: this.dataView.indexOf(rowData)
                };
            }
        }
        else {
            return {
                $implicit: rowData,
                templateID: 'dataRow',
                index: this.dataView.indexOf(rowData)
            };
        }
    };
    Object.defineProperty(IgxHierarchicalGridComponent.prototype, "rootGrid", {
        /**
         * @hidden
        */
        get: function () {
            var currGrid = this;
            while (currGrid.parent) {
                currGrid = currGrid.parent;
            }
            return currGrid;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(IgxHierarchicalGridComponent.prototype, "iconTemplate", {
        /**
         * @hidden
        */
        get: function () {
            var expanded = this.hierarchicalState.length > 0 && this.hasExpandableChildren;
            if (!expanded && this.showExpandAll) {
                return this.headerCollapseIndicatorTemplate || this.defaultCollapsedTemplate;
            }
            else {
                return this.headerExpandIndicatorTemplate || this.defaultExpandedTemplate;
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * @hidden
     * @internal
     */
    IgxHierarchicalGridComponent.prototype.getDragGhostCustomTemplate = function () {
        if (this.parentIsland) {
            return this.parentIsland.getDragGhostCustomTemplate();
        }
        return _super.prototype.getDragGhostCustomTemplate.call(this);
    };
    /**
     * @hidden
    */
    IgxHierarchicalGridComponent.prototype.initColumns = function (collection, cb) {
        if (cb === void 0) { cb = null; }
        if (this.hasColumnLayouts) {
            // invalid configuration - hierarchical grid should not allow column layouts
            // remove column layouts
            var nonColumnLayoutColumns = this.columnList.filter(function (col) { return !col.columnLayout && !col.columnLayoutChild; });
            this.columnList.reset(nonColumnLayoutColumns);
        }
        _super.prototype.initColumns.call(this, collection, cb);
    };
    /**
     * @hidden
     * Gets the visible content height that includes header + tbody + footer.
     * For hierarchical child grid it may be scrolled and not fully visible.
     */
    IgxHierarchicalGridComponent.prototype.getVisibleContentHeight = function () {
        var height = _super.prototype.getVisibleContentHeight.call(this);
        if (this.parent) {
            var rootHeight = this.rootGrid.getVisibleContentHeight();
            var topDiff = this.nativeElement.getBoundingClientRect().top - this.rootGrid.nativeElement.getBoundingClientRect().top;
            height = rootHeight - topDiff > height ? height : rootHeight - topDiff;
        }
        return height;
    };
    /**
     * @hidden
    */
    IgxHierarchicalGridComponent.prototype.toggleAll = function () {
        var expanded = this.hierarchicalState.length > 0 && this.hasExpandableChildren;
        if (!expanded && this.showExpandAll) {
            this.expandAll();
        }
        else {
            this.collapseAll();
        }
    };
    /**
     * Collapses all rows of the current hierarchical grid.
     * ```typescript
     * this.grid.collapseAll();
     * ```
     * @memberof IgxHierarchicalGridComponent
     */
    IgxHierarchicalGridComponent.prototype.collapseAll = function () {
        this.hierarchicalState = [];
    };
    /**
     * Expands all rows of the current hierarchical grid.
     * ```typescript
     * this.grid.expandAll();
     * ```
     * @memberof IgxHierarchicalGridComponent
     */
    IgxHierarchicalGridComponent.prototype.expandAll = function () {
        var _this = this;
        if (this.data) {
            this.hierarchicalState = this.data.map(function (rec) {
                return { rowID: _this.primaryKey ? rec[_this.primaryKey] : rec };
            });
        }
    };
    /**
     * @hidden
     */
    IgxHierarchicalGridComponent.prototype.isExpanded = function (record) {
        var _this = this;
        var inState;
        if (record.childGridsData !== undefined) {
            inState = !!this.hierarchicalState.find(function (v) { return v.rowID === record.rowID; });
        }
        else {
            inState = !!this.hierarchicalState.find(function (v) {
                return _this.primaryKey ? v.rowID === record[_this.primaryKey] : v.rowID === record;
            });
        }
        return inState && this.childLayoutList.length !== 0;
    };
    /**
     * @hidden
     */
    IgxHierarchicalGridComponent.prototype.viewCreatedHandler = function (args) {
        if (this.isChildGridRecord(args.context.$implicit)) {
            var key = args.context.$implicit.rowID;
            this.childGridTemplates.set(key, args);
        }
    };
    /**
     * @hidden
     */
    IgxHierarchicalGridComponent.prototype.viewMovedHandler = function (args) {
        var _this = this;
        if (this.isChildGridRecord(args.context.$implicit)) {
            // view was moved, update owner in cache
            var key = args.context.$implicit.rowID;
            var cachedData = this.childGridTemplates.get(key);
            cachedData.owner = args.owner;
            this.childLayoutList.forEach(function (layout) {
                var relatedGrid = _this.hgridAPI.getChildGridByID(layout.key, args.context.$implicit.rowID);
                if (relatedGrid && relatedGrid.updateOnRender) {
                    // Detect changes if `expandChildren` has changed when the grid wasn't visible. This is for performance reasons.
                    relatedGrid.notifyChanges(true);
                    relatedGrid.updateOnRender = false;
                }
            });
            var childGrids = this.getChildGrids(true);
            childGrids.forEach(function (grid) {
                if (grid.isPercentWidth) {
                    grid.notifyChanges(true);
                }
                grid.updateScrollPosition();
            });
        }
    };
    /**
     * @hidden
     */
    IgxHierarchicalGridComponent.prototype.updateScrollPosition = function () {
        var vScr = this.verticalScrollContainer.getScroll();
        var hScr = this.headerContainer.getScroll();
        if (vScr) {
            vScr.scrollTop = this.scrollTop;
        }
        if (hScr) {
            hScr.scrollLeft = this.scrollLeft;
        }
    };
    IgxHierarchicalGridComponent.prototype.getChildGrids = function (inDeph) {
        return this.hgridAPI.getChildGrids(inDeph);
    };
    IgxHierarchicalGridComponent.prototype.generateDataFields = function (data) {
        var _this = this;
        return _super.prototype.generateDataFields.call(this, data).filter(function (field) {
            var layoutsList = _this.parentIsland ? _this.parentIsland.children : _this.childLayoutList;
            var keys = layoutsList.map(function (item) { return item.key; });
            return keys.indexOf(field) === -1;
        });
    };
    IgxHierarchicalGridComponent.prototype.hg_verticalScrollHandler = function (event) {
        this.scrollTop = event.target.scrollTop;
    };
    IgxHierarchicalGridComponent.prototype.onContainerScroll = function () {
        this.hideOverlays();
    };
    IgxHierarchicalGridComponent.prototype.hg_horizontalScrollHandler = function (event) {
        this.scrollLeft = event.target.scrollLeft;
    };
    var IgxHierarchicalGridComponent_1;
    __decorate([
        HostBinding('attr.id'),
        Input(),
        __metadata("design:type", String),
        __metadata("design:paramtypes", [])
    ], IgxHierarchicalGridComponent.prototype, "id", null);
    __decorate([
        Input(),
        __metadata("design:type", Array),
        __metadata("design:paramtypes", [Array])
    ], IgxHierarchicalGridComponent.prototype, "data", null);
    __decorate([
        Input(),
        __metadata("design:type", Object),
        __metadata("design:paramtypes", [Object])
    ], IgxHierarchicalGridComponent.prototype, "hierarchicalState", null);
    __decorate([
        Output(),
        __metadata("design:type", Object)
    ], IgxHierarchicalGridComponent.prototype, "hierarchicalStateChange", void 0);
    __decorate([
        Input(),
        __metadata("design:type", Boolean),
        __metadata("design:paramtypes", [Boolean])
    ], IgxHierarchicalGridComponent.prototype, "expandChildren", null);
    __decorate([
        ContentChildren(IgxRowIslandComponent, { read: IgxRowIslandComponent, descendants: false }),
        __metadata("design:type", QueryList)
    ], IgxHierarchicalGridComponent.prototype, "childLayoutList", void 0);
    __decorate([
        ContentChildren(IgxRowIslandComponent, { read: IgxRowIslandComponent, descendants: true }),
        __metadata("design:type", QueryList)
    ], IgxHierarchicalGridComponent.prototype, "allLayoutList", void 0);
    __decorate([
        ViewChild('hierarchical_record_template', { read: TemplateRef, static: true }),
        __metadata("design:type", TemplateRef)
    ], IgxHierarchicalGridComponent.prototype, "hierarchicalRecordTemplate", void 0);
    __decorate([
        ViewChild('child_record_template', { read: TemplateRef, static: true }),
        __metadata("design:type", TemplateRef)
    ], IgxHierarchicalGridComponent.prototype, "childTemplate", void 0);
    __decorate([
        ViewChild('headerHierarchyExpander', { read: ElementRef, static: true }),
        __metadata("design:type", ElementRef)
    ], IgxHierarchicalGridComponent.prototype, "headerHierarchyExpander", void 0);
    __decorate([
        ViewChildren(IgxTemplateOutletDirective, { read: IgxTemplateOutletDirective }),
        __metadata("design:type", QueryList)
    ], IgxHierarchicalGridComponent.prototype, "templateOutlets", void 0);
    __decorate([
        ViewChildren(IgxChildGridRowComponent, { read: IgxChildGridRowComponent }),
        __metadata("design:type", QueryList)
    ], IgxHierarchicalGridComponent.prototype, "hierarchicalRows", void 0);
    IgxHierarchicalGridComponent = IgxHierarchicalGridComponent_1 = __decorate([
        Component({
            changeDetection: ChangeDetectionStrategy.OnPush,
            preserveWhitespaces: false,
            selector: 'igx-hierarchical-grid',
            template: "<igx-grid-toolbar role=\"rowgroup\" [style.flex-basis.px]=\"outerWidth\" *ngIf=\"showToolbar\" [gridID]=\"id\"\n    [displayDensity]=\"displayDensity\" #toolbar>\n</igx-grid-toolbar>\n\n<div class=\"igx-grid__thead\">\n    <div class=\"igx-grid__thead-wrapper\" role=\"rowgroup\" [style.width.px]='calcWidth' #theadRow>\n        <div class=\"igx-grid__tr\" role=\"row\" [style.width.px]='calcWidth'>\n            <span *ngIf=\"hasMovableColumns && draggedColumn && pinnedColumns.length <= 0\"\n                [igxColumnMovingDrop]=\"headerContainer\" [attr.droppable]=\"true\" id=\"left\"\n                class=\"igx-grid__scroll-on-drag-left\"></span>\n            <span *ngIf=\"hasMovableColumns && draggedColumn && pinnedColumns.length > 0\"\n                [igxColumnMovingDrop]=\"headerContainer\" [attr.droppable]=\"true\" id=\"left\"\n                class=\"igx-grid__scroll-on-drag-pinned\" [style.left.px]=\"pinnedWidth\"></span>\n                <div #headerHierarchyExpander (click)=\"toggleAll()\" [hidden]='!hasExpandableChildren || !hasVisibleColumns' [ngClass]=\"{\n                    'igx-grid__hierarchical-expander igx-grid__hierarchical-expander--header': hasExpandableChildren,\n                    'igx-grid__hierarchical-expander--push': filteringService.isFilterRowVisible,\n                    'igx-grid__hierarchical-expander--no-border': isRowSelectable || rowDraggable\n                }\">\n                <ng-container *ngTemplateOutlet=\"iconTemplate; context: { $implicit: this }\"></ng-container>\n            </div>\n            <ng-container *ngIf=\"rowDraggable\">\n                <div class=\"igx-grid__drag-indicator\" [ngClass]=\"{\n                        'igx-grid__drag-indicator--header': !isRowSelectable\n                    }\" #headerDragContainer>\n                    <div style=\"visibility: hidden;\">\n                        <ng-container\n                            *ngTemplateOutlet=\"this.dragIndicatorIconTemplate ? this.dragIndicatorIconTemplate : this.dragIndicatorIconBase\">\n                        </ng-container>\n                    </div>\n                </div>\n            </ng-container>\n            <ng-container *ngIf=\"showRowSelectors\">\n                <div class=\"igx-grid__cbx-selection\" (click)=\"onHeaderSelectorClick($event)\" #headerSelectorContainer [ngClass]=\"{\n                        'igx-grid__cbx-selection--push': filteringService.isFilterRowVisible\n                    }\">\n                    <ng-template #headSelector\n                        *ngTemplateOutlet=\"\n                        this.headSelectorTemplate ? this.headSelectorTemplate : headSelectorBaseTemplate;\n                        context: { $implicit: {\n                                        selectedCount: this.selectionService.filteredSelectedRowIds.length,\n                                        totalCount: this.totalRowsCountAfterFilter,\n                                        selectAll: selectAllRows.bind(this),\n                                        deselectAll: deselectAllRows.bind(this) }}\">\n                    </ng-template>\n                </div>\n            </ng-container>\n            <ng-container *ngIf=\"pinnedColumns.length > 0\">\n                <ng-template ngFor let-col [ngForOf]=\"pinnedColumns | igxTopLevel\">\n                    <igx-grid-header-group [column]=\"col\" [gridID]=\"id\" [style.min-width]=\"getHeaderGroupWidth(col)\"\n                        [style.flex-basis]=\"getHeaderGroupWidth(col)\"></igx-grid-header-group>\n                </ng-template>\n            </ng-container>\n            <ng-template igxGridFor let-col [igxGridForOf]=\"unpinnedColumns | igxTopLevel\"\n                [igxForScrollOrientation]=\"'horizontal'\" [igxForScrollContainer]=\"parentVirtDir\"\n                [igxForContainerSize]='unpinnedWidth' [igxForTrackBy]='trackColumnChanges'\n                [igxForSizePropName]='\"calcPixelWidth\"' #hContainer>\n                <igx-grid-header-group [column]=\"col\" [gridID]=\"id\" [style.min-width]=\"getHeaderGroupWidth(col)\"\n                    [style.flex-basis]=\"getHeaderGroupWidth(col)\"></igx-grid-header-group>\n            </ng-template>\n        </div>\n        <igx-grid-filtering-row #filteringRow [style.width.px]='calcWidth' *ngIf=\"filteringService.isFilterRowVisible\"\n            [column]=\"filteringService.filteredColumn\"></igx-grid-filtering-row>\n    </div>\n    <div [style.display]=\"shouldOverlayLoading ? 'flex' : 'none'\" #loadingOverlay>\n        <igx-circular-bar [indeterminate]=\"true\">\n        </igx-circular-bar>\n    </div>\n    <span *ngIf=\"hasMovableColumns && draggedColumn\" [igxColumnMovingDrop]=\"headerContainer\" [attr.droppable]=\"true\"\n        id=\"right\" class=\"igx-grid__scroll-on-drag-right\"></span>\n    <div class=\"igx-grid__thead-thumb\" [hidden]='!hasVerticalSroll()' [style.width.px]=\"scrollWidth\"></div>\n</div>\n\n<div igxGridBody (keydown.control.c)=\"copyHandlerIE()\" (copy)=\"copyHandler($event)\" class=\"igx-grid__tbody\">\n    <div class=\"igx-grid__tbody-content\" (onDragStop)=\"selectionService.dragMode = $event\"\n        (onDragScroll)=\"dragScroll($event)\" [igxGridDragSelect]=\"selectionService.dragMode\" role=\"rowgroup\"\n        [style.height.px]='calcHeight' [style.width.px]='calcWidth' #tbody (scroll)='scrollHandler($event)'>\n        <span *ngIf=\"hasMovableColumns && draggedColumn && pinnedColumns.length <= 0\"\n            [igxColumnMovingDrop]=\"headerContainer\" [attr.droppable]=\"true\" id=\"left\"\n            class=\"igx-grid__scroll-on-drag-left\"></span>\n        <span *ngIf=\"hasMovableColumns && draggedColumn && pinnedColumns.length > 0\"\n            [igxColumnMovingDrop]=\"headerContainer\" [attr.droppable]=\"true\" id=\"left\"\n            class=\"igx-grid__scroll-on-drag-pinned\" [style.left.px]=\"pinnedWidth\"></span>\n        <ng-template igxGridFor let-rowData [igxGridForOf]=\"data\n        | gridTransaction:id:pipeTrigger\n        | visibleColumns:hasVisibleColumns\n        | gridFiltering:filteringExpressionsTree:filterStrategy:advancedFilteringExpressionsTree:id:pipeTrigger\n        | gridSort:sortingExpressions:sortStrategy:id:pipeTrigger\n        | gridHierarchicalPaging:page:perPage:id:pipeTrigger\n        | gridHierarchical:hierarchicalState:id:primaryKey:childLayoutKeys:pipeTrigger\" let-rowIndex=\"index\"\n            [igxForScrollOrientation]=\"'vertical'\" [igxForScrollContainer]='verticalScroll'\n            [igxForContainerSize]='calcHeight' [igxForItemSize]=\"renderedRowHeight\" [igxForTrackBy]='trackChanges'\n            #verticalScrollContainer (onChunkPreload)=\"dataLoading($event)\">\n            <ng-template #hierarchical_record_template>\n                <igx-hierarchical-grid-row [gridID]=\"id\" [index]=\"rowIndex\" [rowData]=\"rowData\" #row>\n                </igx-hierarchical-grid-row>\n            </ng-template>\n            <ng-template #child_record_template let-rowIndex=\"index\" let-rowData>\n                <div style=\"overflow:auto;width: 100%;\" [attr.data-rowindex]='rowIndex' (scroll)='onContainerScroll()'\n                    [ngClass]=\"{\n                    'igx-grid__tr-container': true,\n                    'igx-grid__tr--highlighted':isRowHighlighted(rowData)\n                }\">\n                    <igx-child-grid-row *ngFor=\"let layout of childLayoutList\" [parentGridID]=\"id\" [index]=\"rowIndex\"\n                        [rowData]=\"rowData\" [layout]='layout' #row>\n                    </igx-child-grid-row>\n                </div>\n            </ng-template>\n            <ng-template\n            [igxTemplateOutlet]='(isHierarchicalRecord(rowData) ? hierarchical_record_template : (isChildGridRecord(rowData) && isExpanded(rowData) ? child_record_template : hierarchical_record_template))'\n            [igxTemplateOutletContext]='getContext(rowData)' (onViewCreated)='viewCreatedHandler($event)'\n            (onViewMoved)='viewMovedHandler($event)' (onCachedViewLoaded)='cachedViewLoaded($event)'\n            (onBeforeViewDetach)='viewDetachHandler($event)'></ng-template>\n            <!-- <ng-container *igxTemplateOutlet=\"(isHierarchicalRecord(rowData) ? hierarchical_record_template : (isChildGridRecord(rowData) && isExpanded(rowData) ? child_record_template : hierarchical_record_template)); context: getContext(rowData)\"></ng-container> -->\n        </ng-template>\n        <ng-container *ngTemplateOutlet=\"template\"></ng-container>\n        <span *ngIf=\"hasMovableColumns && draggedColumn\" [igxColumnMovingDrop]=\"headerContainer\" [attr.droppable]=\"true\"\n            id=\"right\" class=\"igx-grid__scroll-on-drag-right\"></span>\n        <div class=\"igx-grid__row-editing-outlet\" igxOverlayOutlet #igxRowEditingOverlayOutlet></div>\n    </div>\n    <span *ngIf=\"hasMovableColumns && draggedColumn\" [igxColumnMovingDrop]=\"headerContainer\" [attr.droppable]=\"true\"\n        id=\"right\" class=\"igx-grid__scroll-on-drag-right\"></span>\n    <div [hidden]='!hasVerticalSroll()' class=\"igx-grid__tbody-scrollbar\" [style.width.px]=\"scrollWidth\"\n        [style.height.px]='calcHeight'>\n        <ng-template igxGridFor [igxGridForOf]='[]' #verticalScrollHolder></ng-template>\n    </div>\n</div>\n\n\n<div class=\"igx-grid__tfoot\" role=\"rowgroup\" [style.height.px]='summariesHeight' #tfoot>\n    <igx-grid-summary-row [style.width.px]='calcWidth' [style.height.px]='summariesHeight'\n        *ngIf=\"hasSummarizedColumns && rootSummariesEnabled\" [gridID]=\"id\"\n        [summaries]=\"id | igxGridSummaryDataPipe:summaryService.retriggerRootPipe\" [index]=\"0\"\n        class=\"igx-grid__summaries\" #summaryRow>\n    </igx-grid-summary-row>\n    <div class=\"igx-grid__tfoot-thumb\" [hidden]='!hasVerticalSroll()' [style.height.px]='summariesHeight'\n        [style.width.px]=\"scrollWidth\"></div>\n</div>\n\n<div class=\"igx-grid__scroll\" [style.height]=\"'18px'\" #scr [hidden]=\"isHorizontalScrollHidden\">\n    <div class=\"igx-grid__scroll-start\" [style.width.px]='pinnedWidth' [hidden]=\"pinnedWidth === 0\"></div>\n    <div class=\"igx-grid__scroll-main\" [style.width.px]='unpinnedWidth'>\n        <ng-template igxGridFor [igxGridForOf]='[]' #scrollContainer>\n        </ng-template>\n    </div>\n</div>\n\n<div class=\"igx-grid__footer\" #footer>\n    <ng-content select=\"igx-grid-footer\"></ng-content>\n    <ng-container *ngIf=\"paging && totalRecords\">\n        <ng-container\n            *ngTemplateOutlet=\"paginationTemplate ? paginationTemplate : defaultPaginator; context: {$implicit: this}\">\n        </ng-container>\n    </ng-container>\n</div>\n\n<ng-template #defaultPaginator>\n    <igx-paginator [displayDensity]=\"displayDensity\" [(page)]=\"page\" [totalRecords]=\"totalRecords\" [(perPage)]=\"perPage\">\n    </igx-paginator>\n</ng-template>\n\n<ng-template #emptyFilteredGrid>\n    <span class=\"igx-grid__tbody-message\">{{emptyFilteredGridMessage}}</span>\n</ng-template>\n\n<ng-template #defaultEmptyGrid>\n    <span class=\"igx-grid__tbody-message\">{{emptyGridMessage}}</span>\n</ng-template>\n\n<ng-template #defaultLoadingGrid>\n    <div class=\"igx-grid__loading\">\n        <igx-circular-bar [indeterminate]=\"true\">\n        </igx-circular-bar>\n    </div>\n</ng-template>\n\n<ng-template #defaultCollapsedTemplate>\n    <igx-icon role=\"button\" fontSet=\"material\">unfold_more</igx-icon>\n</ng-template>\n\n<ng-template #defaultExpandedTemplate>\n    <igx-icon role=\"button\" [isActive]='hierarchicalState.length > 0 && hasExpandableChildren' [isActive]='true' fontSet=\"material\">unfold_less</igx-icon>\n</ng-template>\n\n<div *ngIf=\"rowEditable\" igxToggle>\n    <div [className]=\"bannerClass\">\n        <ng-container\n            *ngTemplateOutlet=\"rowEditContainer; context: { rowChangesCount: rowChangesCount, endEdit: endEdit.bind(this) }\">\n        </ng-container>\n    </div>\n</div>\n<ng-template #defaultRowEditText>\n    You have {{ rowChangesCount }} changes in this row\n</ng-template>\n<ng-template #defaultRowEditActions>\n    <button igxButton igxRowEditTabStop (click)=\"endEdit(false, $event)\">Cancel</button>\n    <button igxButton igxRowEditTabStop (click)=\"endEdit(true, $event)\">Done</button>\n</ng-template>\n<ng-template #defaultRowEditTemplate>\n    <div class=\"igx-banner__message\">\n        <span class=\"igx-banner__text\">\n            <ng-container\n                *ngTemplateOutlet=\"rowEditText ? rowEditText : defaultRowEditText; context: { $implicit: rowChangesCount }\">\n            </ng-container>\n        </span>\n    </div>\n    <div class=\"igx-banner__actions\">\n        <div class=\"igx-banner__row\">\n            <ng-container\n                *ngTemplateOutlet=\"rowEditActions ? rowEditActions : defaultRowEditActions; context: { $implicit: endEdit.bind(this) }\">\n            </ng-container>\n        </div>\n    </div>\n</ng-template>\n\n<ng-template #dragIndicatorIconBase>\n    <igx-icon fontSet=\"material\">drag_indicator</igx-icon>\n</ng-template>\n\n<ng-template #headSelectorBaseTemplate igxHeadSelector let-context>\n    <div class=\"igx-grid__cbx-padding\">\n        <igx-checkbox\n            [readonly]=\"true\"\n            [checked]=\"context.selectedCount > 0 && context.totalCount === context.selectedCount\"\n            disableRipple=\"true\"\n            [ngStyle]=\"{'visibility': isMultiRowSelectionEnabled? 'visible' : 'hidden' }\"\n            [indeterminate]=\"context.selectedCount > 0 && context.selectedCount !== context.totalCount\"\n            [aria-label]=\"headSelectorBaseAriaLabel\"\n            #headerCheckbox>\n        </igx-checkbox>\n    </div>\n</ng-template>\n\n<igx-grid-column-resizer *ngIf=\"colResizingService.showResizer\"></igx-grid-column-resizer>\n<div class=\"igx-grid__loading-outlet\" #igxLoadingOverlayOutlet igxOverlayOutlet></div>\n<div class=\"igx-grid__outlet\" #igxFilteringOverlayOutlet igxOverlayOutlet></div>\n",
            providers: [
                IgxGridSelectionService,
                IgxGridCRUDService,
                { provide: GridBaseAPIService, useClass: IgxHierarchicalGridAPIService },
                { provide: IgxGridBaseDirective, useExisting: forwardRef(function () { return IgxHierarchicalGridComponent_1; }) },
                IgxGridSummaryService,
                IgxFilteringService,
                IgxHierarchicalGridNavigationService,
                IgxForOfSyncService,
                IgxForOfScrollSyncService,
                IgxRowIslandAPIService
            ]
        })
    ], IgxHierarchicalGridComponent);
    return IgxHierarchicalGridComponent;
}(IgxHierarchicalGridBaseDirective));
export { IgxHierarchicalGridComponent };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGllcmFyY2hpY2FsLWdyaWQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vaWduaXRldWktYW5ndWxhci8iLCJzb3VyY2VzIjpbImxpYi9ncmlkcy9oaWVyYXJjaGljYWwtZ3JpZC9oaWVyYXJjaGljYWwtZ3JpZC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFDSCx1QkFBdUIsRUFDdkIsU0FBUyxFQUNULFdBQVcsRUFDWCxLQUFLLEVBQ0wsVUFBVSxFQUNWLFdBQVcsRUFDWCxTQUFTLEVBQ1QsWUFBWSxFQUNaLFNBQVMsRUFDVCxlQUFlLEVBQ2YsVUFBVSxFQU1WLFlBQVksRUFDWixNQUFNLEVBQ1QsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDOUQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDcEQsT0FBTyxFQUFFLDZCQUE2QixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDaEYsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDL0QsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDdEUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDMUUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBRTNELE9BQU8sRUFBRSxvQ0FBb0MsRUFBRSxNQUFNLHdDQUF3QyxDQUFDO0FBQzlGLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBQzFFLE9BQU8sRUFBRSxnQ0FBZ0MsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBQ3RGLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMzQyxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSw0REFBNEQsQ0FBQztBQUN4RyxPQUFPLEVB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IHtcbiAgICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgICBDb21wb25lbnQsXG4gICAgSG9zdEJpbmRpbmcsXG4gICAgSW5wdXQsXG4gICAgZm9yd2FyZFJlZixcbiAgICBUZW1wbGF0ZVJlZixcbiAgICBWaWV3Q2hpbGQsXG4gICAgVmlld0NoaWxkcmVuLFxuICAgIFF1ZXJ5TGlzdCxcbiAgICBDb250ZW50Q2hpbGRyZW4sXG4gICAgRWxlbWVudFJlZixcbiAgICBBZnRlclZpZXdJbml0LFxuICAgIEFmdGVyQ29udGVudEluaXQsXG4gICAgT25Jbml0LFxuICAgIE9uRGVzdHJveSxcbiAgICBEb0NoZWNrLFxuICAgIEV2ZW50RW1pdHRlcixcbiAgICBPdXRwdXRcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBJZ3hHcmlkQmFzZURpcmVjdGl2ZSB9IGZyb20gJy4uL2dyaWQtYmFzZS5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgR3JpZEJhc2VBUElTZXJ2aWNlIH0gZnJvbSAnLi4vYXBpLnNlcnZpY2UnO1xuaW1wb3J0IHsgSWd4SGllcmFyY2hpY2FsR3JpZEFQSVNlcnZpY2UgfSBmcm9tICcuL2hpZXJhcmNoaWNhbC1ncmlkLWFwaS5zZXJ2aWNlJztcbmltcG9ydCB7IElneFJvd0lzbGFuZENvbXBvbmVudCB9IGZyb20gJy4vcm93LWlzbGFuZC5jb21wb25lbnQnO1xuaW1wb3J0IHsgSWd4Q2hpbGRHcmlkUm93Q29tcG9uZW50IH0gZnJvbSAnLi9jaGlsZC1ncmlkLXJvdy5jb21wb25lbnQnO1xuaW1wb3J0IHsgSWd4RmlsdGVyaW5nU2VydmljZSB9IGZyb20gJy4uL2ZpbHRlcmluZy9ncmlkLWZpbHRlcmluZy5zZXJ2aWNlJztcbmltcG9ydCB7IERpc3BsYXlEZW5zaXR5IH0gZnJvbSAnLi4vLi4vY29yZS9kaXNwbGF5RGVuc2l0eSc7XG5pbXBvcnQgeyBJZ3hDb2x1bW5Db21wb25lbnQsIH0gZnJvbSAnLi4vY29sdW1ucy9jb2x1bW4uY29tcG9uZW50JztcbmltcG9ydCB7IElneEhpZXJhcmNoaWNhbEdyaWROYXZpZ2F0aW9uU2VydmljZSB9IGZyb20gJy4vaGllcmFyY2hpY2FsLWdyaWQtbmF2aWdhdGlvbi5zZXJ2aWNlJztcbmltcG9ydCB7IElneEdyaWRTdW1tYXJ5U2VydmljZSB9IGZyb20gJy4uL3N1bW1hcmllcy9ncmlkLXN1bW1hcnkuc2VydmljZSc7XG5pbXBvcnQgeyBJZ3hIaWVyYXJjaGljYWxHcmlkQmFzZURpcmVjdGl2ZSB9IGZyb20gJy4vaGllcmFyY2hpY2FsLWdyaWQtYmFzZS5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgdGFrZVVudGlsIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgSWd4VGVtcGxhdGVPdXRsZXREaXJlY3RpdmUgfSBmcm9tICcuLi8uLi9kaXJlY3RpdmVzL3RlbXBsYXRlLW91dGxldC90ZW1wbGF0ZV9vdXRsZXQuZGlyZWN0aXZlJztcbmltcG9ydCB7IElneEdyaWRTZWxlY3Rpb25TZXJ2aWNlLCBJZ3hHcmlkQ1JVRFNlcnZpY2UgfSBmcm9tICcuLi9zZWxlY3Rpb24vc2VsZWN0aW9uLnNlcnZpY2UnO1xuaW1wb3J0IHsgSWd4VHJhbnNhY3Rpb25TZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvaW5kZXgnO1xuaW1wb3J0IHsgSWd4Rm9yT2ZTeW5jU2VydmljZSwgSWd4Rm9yT2ZTY3JvbGxTeW5jU2VydmljZSB9IGZyb20gJy4uLy4uL2RpcmVjdGl2ZXMvZm9yLW9mL2Zvcl9vZi5zeW5jLnNlcnZpY2UnO1xuaW1wb3J0IHsgR3JpZFR5cGUgfSBmcm9tICcuLi9jb21tb24vZ3JpZC5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgSWd4Um93SXNsYW5kQVBJU2VydmljZSB9IGZyb20gJy4vcm93LWlzbGFuZC1hcGkuc2VydmljZSc7XG5cbmxldCBORVhUX0lEID0gMDtcblxuZXhwb3J0IGludGVyZmFjZSBIaWVyYXJjaGljYWxTdGF0ZVJlY29yZCB7XG4gICAgcm93SUQ6IGFueTtcbn1cblxuQENvbXBvbmVudCh7XG4gICAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gICAgcHJlc2VydmVXaGl0ZXNwYWNlczogZmFsc2UsXG4gICAgc2VsZWN0b3I6ICdpZ3gtaGllcmFyY2hpY2FsLWdyaWQnLFxuICAgIHRlbXBsYXRlVXJsOiAnaGllcmFyY2hpY2FsLWdyaWQuY29tcG9uZW50Lmh0bWwnLFxuICAgIHByb3ZpZGVyczogW1xuICAgICAgICBJZ3hHcmlkU2VsZWN0aW9uU2VydmljZSxcbiAgICAgICAgSWd4R3JpZENSVURTZXJ2aWNlLFxuICAgICAgICB7IHByb3ZpZGU6IEdyaWRCYXNlQVBJU2VydmljZSwgdXNlQ2xhc3M6IElneEhpZXJhcmNoaWNhbEdyaWRBUElTZXJ2aWNlIH0sXG4gICAgICAgIHsgcHJvdmlkZTogSWd4R3JpZEJhc2VEaXJlY3RpdmUsIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IElneEhpZXJhcmNoaWNhbEdyaWRDb21wb25lbnQpIH0sXG4gICAgICAgIElneEdyaWRTdW1tYXJ5U2VydmljZSxcbiAgICAgICAgSWd4RmlsdGVyaW5nU2VydmljZSxcbiAgICAgICAgSWd4SGllcmFyY2hpY2FsR3JpZE5hdmlnYXRpb25TZXJ2aWNlLFxuICAgICAgICBJZ3hGb3JPZlN5bmNTZXJ2aWNlLFxuICAgICAgICBJZ3hGb3JPZlNjcm9sbFN5bmNTZXJ2aWNlLFxuICAgICAgICBJZ3hSb3dJc2xhbmRBUElTZXJ2aWNlXG4gICAgXVxufSlcbmV4cG9ydCBjbGFzcyBJZ3hIaWVyYXJjaGljYWxHcmlkQ29tcG9uZW50IGV4dGVuZHMgSWd4SGllcmFyY2hpY2FsR3JpZEJhc2VEaXJlY3RpdmVcbiAgICBpbXBsZW1lbnRzIEdyaWRUeXBlLCBBZnRlclZpZXdJbml0LCBBZnRlckNvbnRlbnRJbml0LCBPbkluaXQsIE9uRGVzdHJveSwgRG9DaGVjayB7XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgYGlkYCBhdHRyaWJ1dGUuIElmIG5vdCBwcm92aWRlZCBpdCB3aWxsIGJlIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkLlxuICAgICAqIGBgYGh0bWxcbiAgICAgKiA8aWd4LWhpZXJhcmNoaWNhbC1ncmlkIFtpZF09XCInaWd4LWhncmlkLTEnXCIgW2RhdGFdPVwiRGF0YVwiIFthdXRvR2VuZXJhdGVdPVwidHJ1ZVwiPjwvaWd4LWhpZXJhcmNoaWNhbC1ncmlkPlxuICAgICAqIGBgYFxuICAgICAqIEBtZW1iZXJvZiBJZ3hIaWVyYXJjaGljYWxHcmlkQ29tcG9uZW50XG4gICAgICovXG4gICAgQEhvc3RCaW5kaW5nKCdhdHRyLmlkJylcbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBnZXQgaWQoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaF9pZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBbiBASW5wdXQgcHJvcGVydHkgdGhhdCBsZXRzIHlvdSBmaWxsIHRoZSBgSWd4SGllcmFyY2hpY2FsR3JpZENvbXBvbmVudGAgd2l0aCBhbiBhcnJheSBvZiBkYXRhLlxuICAgICAqIGBgYGh0bWxcbiAgICAgKiA8aWd4LWhpZXJhcmNoaWNhbC1ncmlkIFtkYXRhXT1cIkRhdGFcIiBbYXV0b0dlbmVyYXRlXT1cInRydWVcIj48L2lneC1oaWVyYXJjaGljYWwtZ3JpZD5cbiAgICAgKiBgYGBcbiAgICAgKiBAbWVtYmVyb2YgSWd4SGllcmFyY2hpY2FsR3JpZENvbXBvbmVudFxuICAgICAqL1xuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIHNldCBkYXRhKHZhbHVlOiBhbnlbXSkge1xuICAgICAgICB0aGlzLl9kYXRhID0gdmFsdWUgfHwgW107XG4gICAgICAgIHRoaXMuc3VtbWFyeVNlcnZpY2UuY2xlYXJTdW1tYXJ5Q2FjaGUoKTtcbiAgICAgICAgaWYgKHRoaXMuc2hvdWxkR2VuZXJhdGUpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0dXBDb2x1bW5zKCk7XG4gICAgICAgICAgICB0aGlzLnJlZmxvdygpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgICAgICBpZiAodGhpcy5wYXJlbnQgJiYgKHRoaXMuaGVpZ2h0ID09PSBudWxsIHx8IHRoaXMuaGVpZ2h0LmluZGV4T2YoJyUnKSAhPT0gLTEpKSB7XG4gICAgICAgICAgICAvLyBJZiB0aGUgaGVpZ2h0IHdpbGwgY2hhbmdlIGJhc2VkIG9uIGhvdyBtdWNoIGRhdGEgdGhlcmUgaXMsIHJlY2FsY3VsYXRlIHNpemVzIGluIGlneEZvck9mLlxuICAgICAgICAgICAgdGhpcy5ub3RpZnlDaGFuZ2VzKHRydWUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhbiBhcnJheSBvZiBkYXRhIHNldCB0byB0aGUgYElneEhpZXJhcmNoaWNhbEdyaWRDb21wb25lbnRgLlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBsZXQgZmlsdGVyZWREYXRhID0gdGhpcy5ncmlkLmZpbHRlcmVkRGF0YTtcbiAgICAgKiBgYGBcbiAgICAgKiBAbWVtYmVyb2YgSWd4SGllcmFyY2hpY2FsR3JpZENvbXBvbmVudFxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgZGF0YSgpOiBhbnlbXSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kYXRhO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogU2V0cyB0aGUgc3RhdGUgb2YgdGhlIGBJZ3hIaWVyYXJjaGljYWxHcmlkQ29tcG9uZW50YCBjb250YWluaW5nIHdoaWNoIHJvd3MgYXJlIGV4cGFuZGVkLlxuICAgICogYGBgdHlwZXNjcmlwdFxuICAgICogdGhpcy5ncmlkU3RhdGUgPSBbeyByb3dJRDogMSB9LCB7IHJvd0lEOiA0fV07XG4gICAgKiBgYGBcbiAgICAqIGBgYGh0bWxcbiAgICAqIDxpZ3gtaGllcmFyY2hpY2FsLWdyaWQgW3ByaW1hcnlLZXldPVwiJ0lEJ1wiIFtkYXRhXT1cIkRhdGFcIiBbYXV0b0dlbmVyYXRlXT1cImZhbHNlXCIgW2hpZXJhcmNoaWNhbFN0YXRlXT1cImhncmlkU3RhdGVcIj5cbiAgICAqICAgICAgPGlneC1jb2x1bW4gZmllbGQ9XCJJRFwiICBbZGF0YVR5cGVdPSdudW1iZXInPjwvaWd4LWNvbHVtbj5cbiAgICAqICAgICAgPGlneC1jb2x1bW4gZmllbGQ9XCJQcm9kdWN0XCIgIFtkYXRhVHlwZV09J3N0cmluZyc+PC9pZ3gtY29sdW1uPlxuICAgICogICAgICA8aWd4LWNvbHVtbiBmaWVsZD1cIkRlc2NyaXB0aW9uXCIgIFtkYXRhVHlwZV09J3N0cmluZyc+PC9pZ3gtY29sdW1uPlxuICAgICogPC9pZ3gtaGllcmFyY2hpY2FsLWdyaWQ+XG4gICAgKiBgYGBcbiAgICAqXG4gICAgKiBUd28td2F5IGRhdGEgYmluZGluZy5cbiAgICAqIGBgYGh0bWxcbiAgICAqIDxpZ3gtaGllcmFyY2hpY2FsLWdyaWQgW3ByaW1hcnlLZXldPVwiJ0lEJ1wiIFtkYXRhXT1cIkRhdGFcIiBbYXV0b0dlbmVyYXRlXT1cImZhbHNlXCIgWyhoaWVyYXJjaGljYWxTdGF0ZSldPVwiaGdyaWRTdGF0ZVwiPlxuICAgICogICAgICA8aWd4LWNvbHVtbiBmaWVsZD1cIklEXCIgIFtkYXRhVHlwZV09J251bWJlcic+PC9pZ3gtY29sdW1uPlxuICAgICogICAgICA8aWd4LWNvbHVtbiBmaWVsZD1cIlByb2R1Y3RcIiAgW2RhdGFUeXBlXT0nc3RyaW5nJz48L2lneC1jb2x1bW4+XG4gICAgKiAgICAgIDxpZ3gtY29sdW1uIGZpZWxkPVwiRGVzY3JpcHRpb25cIiAgW2RhdGFUeXBlXT0nc3RyaW5nJz48L2lneC1jb2x1bW4+XG4gICAgKiA8L2lneC1oaWVyYXJjaGljYWwtZ3JpZD5cbiAgICAqIGBgYFxuICAgICogQG1lbWJlcm9mIElneEhpZXJhcmNoaWNhbEdyaWRDb21wb25lbnRcbiAgICAqL1xuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIGdldCBoaWVyYXJjaGljYWxTdGF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2hpZXJhcmNoaWNhbFN0YXRlO1xuICAgIH1cbiAgICBwdWJsaWMgc2V0IGhpZXJhcmNoaWNhbFN0YXRlKHZhbCkge1xuICAgICAgICBpZiAodGhpcy5faGllcmFyY2hpY2FsU3RhdGUgIT09IHZhbCkge1xuICAgICAgICAgICAgdGhpcy5oaWVyYXJjaGljYWxTdGF0ZUNoYW5nZS5lbWl0KHZhbCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuaGFzQ2hpbGRyZW5LZXkpIHtcbiAgICAgICAgICAgIHZhbCA9IHZhbC5maWx0ZXIoaXRlbSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVjID0gdGhpcy5wcmltYXJ5S2V5ID8gdGhpcy5kYXRhLmZpbmQoeCA9PiB4W3RoaXMucHJpbWFyeUtleV0gPT09IGl0ZW0ucm93SUQpIDogaXRlbS5yb3dJRDtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVjW3RoaXMuaGFzQ2hpbGRyZW5LZXldO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5faGllcmFyY2hpY2FsU3RhdGUgPSB2YWw7XG4gICAgICAgIGlmICh0aGlzLnBhcmVudCkge1xuICAgICAgICAgICAgdGhpcy5ub3RpZnlDaGFuZ2VzKHRydWUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpAaGlkZGVuXG4gICAgICovXG4gICAgQE91dHB1dCgpXG4gICAgcHVibGljIGhpZXJhcmNoaWNhbFN0YXRlQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIGFuIGFycmF5IG9mIG9iamVjdHMgY29udGFpbmluZyB0aGUgZmlsdGVyZWQgZGF0YSBpbiB0aGUgYElneEhpZXJhcmNoaWNhbEdyaWRDb21wb25lbnRgLlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiB0aGlzLmdyaWQuZmlsdGVyZWREYXRhID0gW3tcbiAgICAgKiAgICAgICBJRDogMSxcbiAgICAgKiAgICAgICBOYW1lOiBcIkFcIlxuICAgICAqIH1dO1xuICAgICAqIGBgYFxuICAgICAqIEBtZW1iZXJvZiBJZ3hIaWVyYXJjaGljYWxHcmlkQ29tcG9uZW50XG4gICAgICovXG4gICAgcHVibGljIHNldCBmaWx0ZXJlZERhdGEodmFsdWUpIHtcbiAgICAgICAgdGhpcy5fZmlsdGVyZWREYXRhID0gdmFsdWU7XG5cblxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYW4gYXJyYXkgb2Ygb2JqZWN0cyBjb250YWluaW5nIHRoZSBmaWx0ZXJlZCBkYXRhIGluIHRoZSBgSWd4SGllcmFyY2hpY2FsR3JpZENvbXBvbmVudGAuXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIGxldCBmaWx0ZXJlZERhdGEgPSB0aGlzLmdyaWQuZmlsdGVyZWREYXRhO1xuICAgICAqIGBgYFxuICAgICAqIEBtZW1iZXJvZiBJZ3hIaWVyYXJjaGljYWxHcmlkQ29tcG9uZW50XG4gICAgICovXG4gICAgcHVibGljIGdldCBmaWx0ZXJlZERhdGEoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9maWx0ZXJlZERhdGE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyBpZiBhbGwgaW1tZWRpYXRlIGNoaWxkcmVuIG9mIHRoZSBgSWd4SGllcmFyY2hpY2FsR3JpZENvbXBvbmVudGAgc2hvdWxkIGJlIGV4cGFuZGVkL2NvbGxhcHNlZC5cbiAgICAgKiBEZWZ1bHQgdmFsdWUgaXMgZmFsc2UuXG4gICAgICogYGBgaHRtbFxuICAgICAqIDxpZ3gtaGllcmFyY2hpY2FsLWdyaWQgW2lkXT1cIidpZ3gtZ3JpZC0xJ1wiIFtkYXRhXT1cIkRhdGFcIiBbYXV0b0dlbmVyYXRlXT1cInRydWVcIiBbZXhwYW5kQ2hpbGRyZW5dPVwidHJ1ZVwiPjwvaWd4LWhpZXJhcmNoaWNhbC1ncmlkPlxuICAgICAqIGBgYFxuICAgICAqIEBtZW1iZXJvZiBJZ3hIaWVyYXJjaGljYWxHcmlkQ29tcG9uZW50XG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBzZXQgZXhwYW5kQ2hpbGRyZW4odmFsdWU6IGJvb2xlYW4pIHtcbiAgICAgICAgdGhpcy5fZXhwYW5kQ2hpbGRyZW4gPSB2YWx1ZTtcbiAgICAgICAgaWYgKHZhbHVlICYmIHRoaXMuZGF0YSkge1xuICAgICAgICAgICAgdGhpcy5oaWVyYXJjaGljYWxTdGF0ZSA9IHRoaXMuZGF0YS5tYXAoKHJlYykgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiB7IHJvd0lEOiB0aGlzLnByaW1hcnlLZXkgPyByZWNbdGhpcy5wcmltYXJ5S2V5XSA6IHJlYyB9O1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5kYXRhKSB7XG4gICAgICAgICAgICB0aGlzLmhpZXJhcmNoaWNhbFN0YXRlID0gW107XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIGlmIGFsbCBpbW1lZGlhdGUgY2hpbGRyZW4gb2YgdGhlIGBJZ3hIaWVyYXJjaGljYWxHcmlkQ29tcG9uZW50YCBwcmV2aW91c2x5IGhhdmUgYmVlbiBzZXQgdG8gYmUgZXhwYW5kZWQvY29sbGFwc2VkLlxuICAgICAqIElmIHByZXZpb3VzbHkgc2V0IGFuZCBzb21lIHJvd3MgaGF2ZSBiZWVuIG1hbnVhbGx5IGV4cGFuZGVkL2NvbGxhcHNlZCBpdCB3aWxsIHN0aWxsIHJldHVybiB0aGUgbGFzdCBzZXQgdmFsdWUuXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIGNvbnN0IGV4cGFuZGVkID0gdGhpcy5ncmlkLmV4cGFuZENoaWxkcmVuO1xuICAgICAqIGBgYFxuICAgICAqIEBtZW1iZXJvZiBJZ3hIaWVyYXJjaGljYWxHcmlkQ29tcG9uZW50XG4gICAgICovXG4gICAgZ2V0IGV4cGFuZENoaWxkcmVuKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fZXhwYW5kQ2hpbGRyZW47XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgdW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIHBhcmVudCByb3cuIEl0IG1heSBiZSBhIGBzdHJpbmdgIG9yIGBudW1iZXJgIGlmIGBwcmltYXJ5S2V5YCBvZiB0aGVcbiAgICAgKiBwYXJlbnQgZ3JpZCBpcyBzZXQgb3IgYW4gb2JqZWN0IHJlZmVyZW5jZSBvZiB0aGUgcGFyZW50IHJlY29yZCBvdGhlcndpc2UuXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIGNvbnN0IGZvcmVpZ25LZXkgPSB0aGlzLmdyaWQuZm9yZWlnbktleTtcbiAgICAgKiBgYGBcbiAgICAgKiBAbWVtYmVyb2YgSWd4SGllcmFyY2hpY2FsR3JpZENvbXBvbmVudFxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgZm9yZWlnbktleSgpIHtcbiAgICAgICAgaWYgKCF0aGlzLnBhcmVudCkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMucGFyZW50LmhncmlkQVBJLmdldFBhcmVudFJvd0lkKHRoaXMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBAQ29udGVudENoaWxkcmVuKElneFJvd0lzbGFuZENvbXBvbmVudCwgeyByZWFkOiBJZ3hSb3dJc2xhbmRDb21wb25lbnQsIGRlc2NlbmRhbnRzOiBmYWxzZSB9KVxuICAgIHB1YmxpYyBjaGlsZExheW91dExpc3Q6IFF1ZXJ5TGlzdDxJZ3hSb3dJc2xhbmRDb21wb25lbnQ+O1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIEBDb250ZW50Q2hpbGRyZW4oSWd4Um93SXNsYW5kQ29tcG9uZW50LCB7IHJlYWQ6IElneFJvd0lzbGFuZENvbXBvbmVudCwgZGVzY2VuZGFudHM6IHRydWUgfSlcbiAgICBwdWJsaWMgYWxsTGF5b3V0TGlzdDogUXVlcnlMaXN0PElneFJvd0lzbGFuZENvbXBvbmVudD47XG5cbiAgICBAVmlld0NoaWxkKCdoaWVyYXJjaGljYWxfcmVjb3JkX3RlbXBsYXRlJywgeyByZWFkOiBUZW1wbGF0ZVJlZiwgc3RhdGljOiB0cnVlIH0pXG4gICAgcHJvdGVjdGVkIGhpZXJhcmNoaWNhbFJlY29yZFRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+O1xuXG4gICAgQFZpZXdDaGlsZCgnY2hpbGRfcmVjb3JkX3RlbXBsYXRlJywgeyByZWFkOiBUZW1wbGF0ZVJlZiwgc3RhdGljOiB0cnVlIH0pXG4gICAgcHJvdGVjdGVkIGNoaWxkVGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT47XG5cbiAgICBAVmlld0NoaWxkKCdoZWFkZXJIaWVyYXJjaHlFeHBhbmRlcicsIHsgcmVhZDogRWxlbWVudFJlZiwgc3RhdGljOiB0cnVlIH0pXG4gICAgcHJvdGVjdGVkIGhlYWRlckhpZXJhcmNoeUV4cGFuZGVyOiBFbGVtZW50UmVmO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIEBWaWV3Q2hpbGRyZW4oSWd4VGVtcGxhdGVPdXRsZXREaXJlY3RpdmUsIHsgcmVhZDogSWd4VGVtcGxhdGVPdXRsZXREaXJlY3RpdmUgfSlcbiAgICBwdWJsaWMgdGVtcGxhdGVPdXRsZXRzOiBRdWVyeUxpc3Q8YW55PjtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBAVmlld0NoaWxkcmVuKElneENoaWxkR3JpZFJvd0NvbXBvbmVudCwgeyByZWFkOiBJZ3hDaGlsZEdyaWRSb3dDb21wb25lbnQgfSlcbiAgICBwdWJsaWMgaGllcmFyY2hpY2FsUm93czogUXVlcnlMaXN0PElneENoaWxkR3JpZFJvd0NvbXBvbmVudD47XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZ2V0IGhhc0V4cGFuZGFibGVDaGlsZHJlbigpIHtcbiAgICAgICAgcmV0dXJuICEhdGhpcy5jaGlsZExheW91dEtleXMubGVuZ3RoO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgY2hpbGRMYXlvdXRLZXlzID0gW107XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIGhpZ2hsaWdodGVkUm93SUQgPSBudWxsO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyB1cGRhdGVPblJlbmRlciA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBwYXJlbnQgPSBudWxsO1xuXG4gICAgcHJpdmF0ZSBfaGllcmFyY2hpY2FsU3RhdGUgPSBbXTtcbiAgICBwcml2YXRlIF9kYXRhO1xuICAgIHByaXZhdGUgX2ZpbHRlcmVkRGF0YSA9IG51bGw7XG4gICAgcHJpdmF0ZSBoX2lkID0gYGlneC1oaWVyYXJjaGljYWwtZ3JpZC0ke05FWFRfSUQrK31gO1xuICAgIHByaXZhdGUgY2hpbGRHcmlkVGVtcGxhdGVzOiBNYXA8YW55LCBhbnk+ID0gbmV3IE1hcCgpO1xuICAgIHByaXZhdGUgc2Nyb2xsVG9wID0gMDtcbiAgICBwcml2YXRlIHNjcm9sbExlZnQgPSAwO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG5nT25Jbml0KCkge1xuICAgICAgICBpZiAodGhpcy5fdHJhbnNhY3Rpb25zIGluc3RhbmNlb2YgSWd4VHJhbnNhY3Rpb25TZXJ2aWNlKSB7XG4gICAgICAgICAgICAvLyB0cmFuc2FjdGlvbiBzZXJ2aWNlIGNhbm5vdCBiZSBpbmplY3RlZCBpbiBhIGRlcml2ZWQgY2xhc3MgaW4gYSBmYWN0b3J5IG1hbm5lclxuICAgICAgICAgICAgdGhpcy5fdHJhbnNhY3Rpb25zID0gbmV3IElneFRyYW5zYWN0aW9uU2VydmljZSgpO1xuICAgICAgICB9XG4gICAgICAgIHN1cGVyLm5nT25Jbml0KCk7XG4gICAgfVxuXG4gICAgcHVibGljIG5nRG9DaGVjaygpIHtcbiAgICAgICAgaWYgKHRoaXMuX2NkclJlcXVlc3RSZXBhaW50ICYmICF0aGlzLl9pbml0KSB7XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZVNpemVzKCk7XG4gICAgICAgIH1cbiAgICAgICAgc3VwZXIubmdEb0NoZWNrKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICAgICAgc3VwZXIubmdBZnRlclZpZXdJbml0KCk7XG4gICAgICAgIHRoaXMudmVydGljYWxTY3JvbGxDb250YWluZXIuZ2V0U2Nyb2xsKCkuYWRkRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgdGhpcy5oZ192ZXJ0aWNhbFNjcm9sbEhhbmRsZXIuYmluZCh0aGlzKSk7XG4gICAgICAgIHRoaXMuaGVhZGVyQ29udGFpbmVyLmdldFNjcm9sbCgpLmFkZEV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsIHRoaXMuaGdfaG9yaXpvbnRhbFNjcm9sbEhhbmRsZXIuYmluZCh0aGlzKSk7XG5cbiAgICAgICAgaWYgKHRoaXMuZXhwYW5kQ2hpbGRyZW4gJiYgdGhpcy5kYXRhICYmIHRoaXMuaGllcmFyY2hpY2FsU3RhdGUubGVuZ3RoICE9PSB0aGlzLmRhdGEubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aGlzLmhpZXJhcmNoaWNhbFN0YXRlID0gdGhpcy5kYXRhLm1hcCgocmVjKSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHsgcm93SUQ6IHRoaXMucHJpbWFyeUtleSA/IHJlY1t0aGlzLnByaW1hcnlLZXldIDogcmVjIH07XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMudmVydGljYWxTY3JvbGxDb250YWluZXIub25CZWZvcmVWaWV3RGVzdHJveWVkLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKS5zdWJzY3JpYmUoKHZpZXcpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHJvd0RhdGEgPSB2aWV3LmNvbnRleHQuJGltcGxpY2l0O1xuICAgICAgICAgICAgaWYgKHRoaXMuaXNDaGlsZEdyaWRSZWNvcmQocm93RGF0YSkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjYWNoZWREYXRhID0gdGhpcy5jaGlsZEdyaWRUZW1wbGF0ZXMuZ2V0KHJvd0RhdGEucm93SUQpO1xuICAgICAgICAgICAgICAgIGlmIChjYWNoZWREYXRhKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHRtbHBPdXRsZXQgPSBjYWNoZWREYXRhLm93bmVyO1xuICAgICAgICAgICAgICAgICAgICB0bWxwT3V0bGV0Ll92aWV3Q29udGFpbmVyUmVmLmRldGFjaCgwKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmICh0aGlzLnBhcmVudCkge1xuICAgICAgICAgICAgdGhpcy5fZGlzcGxheURlbnNpdHkgPSB0aGlzLnJvb3RHcmlkLl9kaXNwbGF5RGVuc2l0eTtcbiAgICAgICAgICAgIHRoaXMucm9vdEdyaWQub25EZW5zaXR5Q2hhbmdlZC5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLl9kaXNwbGF5RGVuc2l0eSA9IHRoaXMucm9vdEdyaWQuX2Rpc3BsYXlEZW5zaXR5O1xuICAgICAgICAgICAgICAgIHRoaXMubm90aWZ5Q2hhbmdlcyh0cnVlKTtcbiAgICAgICAgICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5jaGlsZExheW91dEtleXMgPSB0aGlzLnBhcmVudElzbGFuZC5jaGlsZHJlbi5tYXAoKGl0ZW0pID0+IGl0ZW0ua2V5KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMudG9vbGJhckN1c3RvbUNvbnRlbnRUZW1wbGF0ZXMgPSB0aGlzLnBhcmVudElzbGFuZCA/XG4gICAgICAgICAgICB0aGlzLnBhcmVudElzbGFuZC50b29sYmFyQ3VzdG9tQ29udGVudFRlbXBsYXRlcyA6XG4gICAgICAgICAgICB0aGlzLnRvb2xiYXJDdXN0b21Db250ZW50VGVtcGxhdGVzO1xuXG4gICAgICAgIHRoaXMuaGVhZFNlbGVjdG9yc1RlbXBsYXRlcyA9IHRoaXMucGFyZW50SXNsYW5kID9cbiAgICAgICAgICAgIHRoaXMucGFyZW50SXNsYW5kLmhlYWRTZWxlY3RvcnNUZW1wbGF0ZXMgOlxuICAgICAgICAgICAgdGhpcy5oZWFkU2VsZWN0b3JzVGVtcGxhdGVzO1xuXG4gICAgICAgIHRoaXMucm93U2VsZWN0b3JzVGVtcGxhdGVzID0gdGhpcy5wYXJlbnRJc2xhbmQgP1xuICAgICAgICAgICAgdGhpcy5wYXJlbnRJc2xhbmQucm93U2VsZWN0b3JzVGVtcGxhdGVzIDpcbiAgICAgICAgICAgIHRoaXMucm93U2VsZWN0b3JzVGVtcGxhdGVzO1xuICAgICAgICB0aGlzLmRyYWdJbmRpY2F0b3JJY29uVGVtcGxhdGUgPSB0aGlzLnBhcmVudElzbGFuZCA/XG4gICAgICAgICAgICB0aGlzLnBhcmVudElzbGFuZC5kcmFnSW5kaWNhdG9ySWNvblRlbXBsYXRlIDpcbiAgICAgICAgICAgIHRoaXMuZHJhZ0luZGljYXRvckljb25UZW1wbGF0ZTtcbiAgICAgICAgdGhpcy5yb3dFeHBhbmRlZEluZGljYXRvclRlbXBsYXRlICA9IHRoaXMucm9vdEdyaWQucm93RXhwYW5kZWRJbmRpY2F0b3JUZW1wbGF0ZTtcbiAgICAgICAgdGhpcy5yb3dDb2xsYXBzZWRJbmRpY2F0b3JUZW1wbGF0ZSAgID0gdGhpcy5yb290R3JpZC5yb3dDb2xsYXBzZWRJbmRpY2F0b3JUZW1wbGF0ZTtcbiAgICAgICAgdGhpcy5oZWFkZXJDb2xsYXBzZUluZGljYXRvclRlbXBsYXRlID0gdGhpcy5yb290R3JpZC5oZWFkZXJDb2xsYXBzZUluZGljYXRvclRlbXBsYXRlO1xuICAgICAgICB0aGlzLmhlYWRlckV4cGFuZEluZGljYXRvclRlbXBsYXRlID0gdGhpcy5yb290R3JpZC5oZWFkZXJFeHBhbmRJbmRpY2F0b3JUZW1wbGF0ZTtcbiAgICAgICAgdGhpcy5oYXNDaGlsZHJlbktleSA9IHRoaXMucGFyZW50SXNsYW5kID9cbiAgICAgICAgIHRoaXMucGFyZW50SXNsYW5kLmhhc0NoaWxkcmVuS2V5IHx8IHRoaXMucm9vdEdyaWQuaGFzQ2hpbGRyZW5LZXkgOlxuICAgICAgICAgdGhpcy5yb290R3JpZC5oYXNDaGlsZHJlbktleTtcbiAgICAgICAgIHRoaXMuc2hvd0V4cGFuZEFsbCA9IHRoaXMucGFyZW50SXNsYW5kID9cbiAgICAgICAgIHRoaXMucGFyZW50SXNsYW5kLnNob3dFeHBhbmRBbGwgOiB0aGlzLnJvb3RHcmlkLnNob3dFeHBhbmRBbGw7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSB1cGRhdGVTaXplcygpIHtcbiAgICAgICAgaWYgKGRvY3VtZW50LmJvZHkuY29udGFpbnModGhpcy5uYXRpdmVFbGVtZW50KSAmJiB0aGlzLmlzUGVyY2VudFdpZHRoKSB7XG4gICAgICAgICAgICB0aGlzLnJlZmxvdygpO1xuXG4gICAgICAgICAgICB0aGlzLmhncmlkQVBJLmdldENoaWxkR3JpZHMoZmFsc2UpLmZvckVhY2goKGdyaWQpID0+IHtcbiAgICAgICAgICAgICAgICBncmlkLnVwZGF0ZVNpemVzKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByb3RlY3RlZCBfc2hvdWxkQXV0b1NpemUocmVuZGVyZWRIZWlnaHQpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNQZXJjZW50SGVpZ2h0ICYmIHRoaXMucGFyZW50KSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc3VwZXIuX3Nob3VsZEF1dG9TaXplKHJlbmRlcmVkSGVpZ2h0KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IG91dGxldERpcmVjdGl2ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucm9vdEdyaWQuX291dGxldERpcmVjdGl2ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgbmdBZnRlckNvbnRlbnRJbml0KCkge1xuICAgICAgICB0aGlzLnVwZGF0ZUNvbHVtbkxpc3QoZmFsc2UpO1xuICAgICAgICB0aGlzLmNoaWxkTGF5b3V0S2V5cyA9IHRoaXMucGFyZW50ID9cbiAgICAgICAgdGhpcy5wYXJlbnRJc2xhbmQuY2hpbGRyZW4ubWFwKChpdGVtKSA9PiBpdGVtLmtleSkgOlxuICAgICAgICB0aGlzLmNoaWxkTGF5b3V0S2V5cyA9IHRoaXMuY2hpbGRMYXlvdXRMaXN0Lm1hcCgoaXRlbSkgPT4gaXRlbS5rZXkpO1xuICAgICAgICB0aGlzLmNoaWxkTGF5b3V0TGlzdC5ub3RpZnlPbkNoYW5nZXMoKTtcbiAgICAgICAgdGhpcy5jaGlsZExheW91dExpc3QuY2hhbmdlcy5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSlcbiAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB0aGlzLm9uUm93SXNsYW5kQ2hhbmdlKCkpO1xuICAgICAgICBzdXBlci5uZ0FmdGVyQ29udGVudEluaXQoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBoaWRkZW5cbiAgICAqL1xuICAgIHB1YmxpYyBvblJvd0lzbGFuZENoYW5nZSgpIHtcbiAgICAgICAgaWYgKHRoaXMucGFyZW50KSB7XG4gICAgICAgICAgICB0aGlzLmNoaWxkTGF5b3V0S2V5cyA9IHRoaXMucGFyZW50SXNsYW5kLmNoaWxkcmVuLmZpbHRlcihpdGVtID0+ICEoaXRlbSBhcyBhbnkpLl9kZXN0cm95ZWQpLm1hcCgoaXRlbSkgPT4gaXRlbS5rZXkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jaGlsZExheW91dEtleXMgPSB0aGlzLmNoaWxkTGF5b3V0TGlzdC5maWx0ZXIoaXRlbSA9PiAhKGl0ZW0gYXMgYW55KS5fZGVzdHJveWVkKS5tYXAoKGl0ZW0pID0+IGl0ZW0ua2V5KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoISh0aGlzLmNkciBhcyBhbnkpLmRlc3Ryb3llZCkge1xuICAgICAgICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIG9uQ29sdW1uc0NoYW5nZWQoY2hhbmdlOiBRdWVyeUxpc3Q8SWd4Q29sdW1uQ29tcG9uZW50Pikge1xuICAgICAgICB0aGlzLnVwZGF0ZUNvbHVtbkxpc3QoKTtcbiAgICAgICAgY29uc3QgY29scyA9IGNoYW5nZS5maWx0ZXIoYyA9PiBjLmdyaWRBUEkuZ3JpZCA9PT0gdGhpcyk7XG4gICAgICAgIGlmIChjb2xzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRoaXMuY29sdW1uTGlzdC5yZXNldChjb2xzKTtcbiAgICAgICAgICAgIHN1cGVyLm9uQ29sdW1uc0NoYW5nZWQodGhpcy5jb2x1bW5MaXN0KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgdXBkYXRlQ29sdW1uTGlzdChyZWNhbGNDb2xTaXplcyA9IHRydWUpIHtcbiAgICAgICAgY29uc3QgY2hpbGRMYXlvdXRzID0gdGhpcy5wYXJlbnQgPyB0aGlzLmNoaWxkTGF5b3V0TGlzdCA6IHRoaXMuYWxsTGF5b3V0TGlzdDtcbiAgICAgICAgY29uc3QgbmVzdGVkQ29sdW1ucyA9IGNoaWxkTGF5b3V0cy5tYXAoKGxheW91dCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIGxheW91dC5jb2x1bW5MaXN0LnRvQXJyYXkoKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IGNvbHNBcnJheSA9IFtdLmNvbmNhdC5hcHBseShbXSwgbmVzdGVkQ29sdW1ucyk7XG4gICAgICAgIGNvbnN0IGNvbExlbmd0aCA9IHRoaXMuY29sdW1uTGlzdC5sZW5ndGg7XG4gICAgICAgIGlmIChjb2xzQXJyYXkubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgY29uc3QgdG9wQ29scyA9IHRoaXMuY29sdW1uTGlzdC5maWx0ZXIoKGl0ZW0pID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gY29sc0FycmF5LmluZGV4T2YoaXRlbSkgPT09IC0xO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLmNvbHVtbkxpc3QucmVzZXQodG9wQ29scyk7XG4gICAgICAgICAgICBpZiAocmVjYWxjQ29sU2l6ZXMgJiYgdGhpcy5jb2x1bW5MaXN0Lmxlbmd0aCAhPT0gY29sTGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jYWxjdWxhdGVHcmlkU2l6ZXMoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIG5nT25EZXN0cm95KCkge1xuICAgICAgICBpZiAoIXRoaXMucGFyZW50KSB7XG4gICAgICAgICAgICB0aGlzLmhncmlkQVBJLmdldENoaWxkR3JpZHModHJ1ZSkuZm9yRWFjaCgoZ3JpZCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghZ3JpZC5jaGlsZFJvdy5jZHIuZGVzdHJveWVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGdyaWQuY2hpbGRSb3cuY2RyLmRlc3Ryb3koKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5wYXJlbnQgJiYgdGhpcy5zZWxlY3Rpb25TZXJ2aWNlLmFjdGl2ZUVsZW1lbnQpIHtcbiAgICAgICAgICAgIC8vIGluIGNhc2Ugc2VsZWN0aW9uIGlzIGluIGRlc3Ryb3llZCBjaGlsZCBncmlkLCBzZWxlY3Rpb24gc2hvdWxkIGJlIGNsZWFyZWQuXG4gICAgICAgICAgICB0aGlzLl9jbGVhclNlbGV0aW9uSGlnaGxpZ2h0cygpO1xuICAgICAgICB9XG4gICAgICAgIHN1cGVyLm5nT25EZXN0cm95KCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfY2xlYXJTZWxldGlvbkhpZ2hsaWdodHMoKSB7XG4gICAgICAgIFt0aGlzLnJvb3RHcmlkLCAuLi50aGlzLnJvb3RHcmlkLmdldENoaWxkR3JpZHModHJ1ZSldLmZvckVhY2goZ3JpZCA9PiB7XG4gICAgICAgICAgICBncmlkLnNlbGVjdGlvblNlcnZpY2UuY2xlYXIoKTtcbiAgICAgICAgICAgIGdyaWQuc2VsZWN0aW9uU2VydmljZS5hY3RpdmVFbGVtZW50ID0gbnVsbDtcbiAgICAgICAgICAgIGdyaWQubmF0aXZlRWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKCdpZ3gtZ3JpZF9fdHItLWhpZ2hsaWdodGVkJyk7XG4gICAgICAgICAgICBncmlkLmhpZ2hsaWdodGVkUm93SUQgPSBudWxsO1xuICAgICAgICAgICAgZ3JpZC5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQGhpZGRlblxuICAgICovXG4gICAgcHVibGljIGdldCB0ZW1wbGF0ZSgpOiBUZW1wbGF0ZVJlZjxhbnk+IHtcbiAgICAgICAgaWYgKHRoaXMuZmlsdGVyZWREYXRhICYmIHRoaXMuZmlsdGVyZWREYXRhLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZW1wdHlHcmlkVGVtcGxhdGUgPyB0aGlzLmVtcHR5R3JpZFRlbXBsYXRlIDogdGhpcy5lbXB0eUZpbHRlcmVkR3JpZFRlbXBsYXRlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuaXNMb2FkaW5nICYmICghdGhpcy5kYXRhIHx8IHRoaXMuZGF0YUxlbmd0aCA9PT0gMCkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmxvYWRpbmdHcmlkVGVtcGxhdGUgPyB0aGlzLmxvYWRpbmdHcmlkVGVtcGxhdGUgOiB0aGlzLmxvYWRpbmdHcmlkRGVmYXVsdFRlbXBsYXRlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuZGF0YUxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZW1wdHlHcmlkVGVtcGxhdGUgPyB0aGlzLmVtcHR5R3JpZFRlbXBsYXRlIDogdGhpcy5lbXB0eUdyaWREZWZhdWx0VGVtcGxhdGU7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICogR2V0cyB0aGUgY29tYmluZWQgd2lkdGggb2YgdGhlIGNvbHVtbnMgdGhhdCBhcmUgc3BlY2lmaWMgdG8gdGhlIGVuYWJsZWQgZ3JpZCBmZWF0dXJlcy4gVGhleSBhcmUgZml4ZWQuXG4gICAgICogVE9ETzogUmVtb3ZlIGZvciBBbmd1bGFyIDguIENhbGxpbmcgcGFyZW50IGNsYXNzIGdldHRlciB1c2luZyBzdXBlciBpcyBub3Qgc3VwcG9ydGVkIGZvciBub3cuXG4gICAgICovXG4gICAgcHVibGljIGdldEZlYXR1cmVDb2x1bW5zV2lkdGgoKSB7XG4gICAgICAgIGxldCB3aWR0aCA9IHN1cGVyLmdldEZlYXR1cmVDb2x1bW5zV2lkdGgoKTtcblxuICAgICAgICBpZiAodGhpcy5oYXNFeHBhbmRhYmxlQ2hpbGRyZW4pIHtcbiAgICAgICAgICAgIHdpZHRoICs9IHRoaXMuaGVhZGVySGllcmFyY2h5RXhwYW5kZXIubmF0aXZlRWxlbWVudC5vZmZzZXRXaWR0aCB8fCB0aGlzLmdldERlZmF1bHRFeHBhbmRlcldpZHRoKCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gd2lkdGg7XG4gICAgfVxuXG4gICAgIHByaXZhdGUgZ2V0RGVmYXVsdEV4cGFuZGVyV2lkdGgoKTogbnVtYmVyIHtcbiAgICAgICAgc3dpdGNoICh0aGlzLmRpc3BsYXlEZW5zaXR5KSB7XG4gICAgICAgICAgICBjYXNlIERpc3BsYXlEZW5zaXR5LmNvc3k6XG4gICAgICAgICAgICAgICAgcmV0dXJuIDU3O1xuICAgICAgICAgICAgY2FzZSBEaXNwbGF5RGVuc2l0eS5jb21wYWN0OlxuICAgICAgICAgICAgICAgIHJldHVybiA0OTtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIDcyO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBpc1Jvd0hpZ2hsaWdodGVkKHJvd0RhdGEpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaGlnaGxpZ2h0ZWRSb3dJRCA9PT0gcm93RGF0YS5yb3dJRDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIGlzSGllcmFyY2hpY2FsUmVjb3JkKHJlY29yZDogYW55KTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLmNoaWxkTGF5b3V0TGlzdC5sZW5ndGggIT09IDAgJiYgcmVjb3JkW3RoaXMuY2hpbGRMYXlvdXRMaXN0LmZpcnN0LmtleV07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBpc0NoaWxkR3JpZFJlY29yZChyZWNvcmQ6IGFueSk6IGJvb2xlYW4ge1xuICAgICAgICAvLyBDYW4gYmUgbnVsbCB3aGVuIHRoZXJlIGlzIGRlZmluZWQgbGF5b3V0IGJ1dCBubyBjaGlsZCBkYXRhIHdhcyBmb3VuZFxuICAgICAgICByZXR1cm4gcmVjb3JkLmNoaWxkR3JpZHNEYXRhICE9PSB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyB0cmFja0NoYW5nZXMoaW5kZXgsIHJlYykge1xuICAgICAgICBpZiAocmVjLmNoaWxkR3JpZHNEYXRhICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIC8vIGlmIGlzIGNoaWxkIHJlY1xuICAgICAgICAgICAgcmV0dXJuIHJlYy5yb3dJRDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVjO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0Q29udGV4dChyb3dEYXRhKTogYW55IHtcbiAgICAgICAgaWYgKHRoaXMuaXNDaGlsZEdyaWRSZWNvcmQocm93RGF0YSkpIHtcbiAgICAgICAgICAgIGNvbnN0IGNhY2hlZERhdGEgPSB0aGlzLmNoaWxkR3JpZFRlbXBsYXRlcy5nZXQocm93RGF0YS5yb3dJRCk7XG4gICAgICAgICAgICBpZiAoY2FjaGVkRGF0YSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHZpZXcgPSBjYWNoZWREYXRhLnZpZXc7XG4gICAgICAgICAgICAgICAgY29uc3QgdG1scE91dGxldCA9IGNhY2hlZERhdGEub3duZXI7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgJGltcGxpY2l0OiByb3dEYXRhLFxuICAgICAgICAgICAgICAgICAgICBtb3ZlVmlldzogdmlldyxcbiAgICAgICAgICAgICAgICAgICAgb3duZXI6IHRtbHBPdXRsZXQsXG4gICAgICAgICAgICAgICAgICAgIGluZGV4OiB0aGlzLmRhdGFWaWV3LmluZGV4T2Yocm93RGF0YSlcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCByb3dJRCA9IHRoaXMucHJpbWFyeUtleSA/IHJvd0RhdGEucm93SUQgOiB0aGlzLmRhdGEuaW5kZXhPZihyb3dEYXRhLnJvd0lEKTtcbiAgICAgICAgICAgICAgICAvLyBjaGlsZCByb3dzIGNvbnRhaW4gdW5pcXVlIGdyaWRzLCBoZW5jZSBzaG91bGQgaGF2ZSB1bmlxdWUgdGVtcGxhdGVzXG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgJGltcGxpY2l0OiByb3dEYXRhLFxuICAgICAgICAgICAgICAgICAgICB0ZW1wbGF0ZUlEOiAnY2hpbGRSb3ctJyArIHJvd0lELFxuICAgICAgICAgICAgICAgICAgICBpbmRleDogdGhpcy5kYXRhVmlldy5pbmRleE9mKHJvd0RhdGEpXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgJGltcGxpY2l0OiByb3dEYXRhLFxuICAgICAgICAgICAgICAgIHRlbXBsYXRlSUQ6ICdkYXRhUm93JyxcbiAgICAgICAgICAgICAgICBpbmRleDogdGhpcy5kYXRhVmlldy5pbmRleE9mKHJvd0RhdGEpXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICovXG4gICAgcHVibGljIGdldCByb290R3JpZCgpIHtcbiAgICAgICAgbGV0IGN1cnJHcmlkID0gdGhpcztcbiAgICAgICAgd2hpbGUgKGN1cnJHcmlkLnBhcmVudCkge1xuICAgICAgICAgICAgY3VyckdyaWQgPSBjdXJyR3JpZC5wYXJlbnQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGN1cnJHcmlkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAqL1xuICAgIHB1YmxpYyBnZXQgaWNvblRlbXBsYXRlKCkge1xuICAgICAgICBjb25zdCBleHBhbmRlZCA9IHRoaXMuaGllcmFyY2hpY2FsU3RhdGUubGVuZ3RoID4gMCAmJiB0aGlzLmhhc0V4cGFuZGFibGVDaGlsZHJlbjtcbiAgICAgICAgaWYgKCFleHBhbmRlZCAmJiB0aGlzLnNob3dFeHBhbmRBbGwpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmhlYWRlckNvbGxhcHNlSW5kaWNhdG9yVGVtcGxhdGUgfHwgdGhpcy5kZWZhdWx0Q29sbGFwc2VkVGVtcGxhdGU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5oZWFkZXJFeHBhbmRJbmRpY2F0b3JUZW1wbGF0ZSB8fCB0aGlzLmRlZmF1bHRFeHBhbmRlZFRlbXBsYXRlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIHB1YmxpYyBnZXREcmFnR2hvc3RDdXN0b21UZW1wbGF0ZSgpOiBUZW1wbGF0ZVJlZjxhbnk+IHtcbiAgICAgICAgaWYgKHRoaXMucGFyZW50SXNsYW5kKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5wYXJlbnRJc2xhbmQuZ2V0RHJhZ0dob3N0Q3VzdG9tVGVtcGxhdGUoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc3VwZXIuZ2V0RHJhZ0dob3N0Q3VzdG9tVGVtcGxhdGUoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgKi9cbiAgICBwcm90ZWN0ZWQgaW5pdENvbHVtbnMoY29sbGVjdGlvbjogUXVlcnlMaXN0PElneENvbHVtbkNvbXBvbmVudD4sIGNiOiBGdW5jdGlvbiA9IG51bGwpIHtcbiAgICAgICAgaWYgKHRoaXMuaGFzQ29sdW1uTGF5b3V0cykge1xuICAgICAgICAgICAgLy8gaW52YWxpZCBjb25maWd1cmF0aW9uIC0gaGllcmFyY2hpY2FsIGdyaWQgc2hvdWxkIG5vdCBhbGxvdyBjb2x1bW4gbGF5b3V0c1xuICAgICAgICAgICAgLy8gcmVtb3ZlIGNvbHVtbiBsYXlvdXRzXG4gICAgICAgICAgICBjb25zdCBub25Db2x1bW5MYXlvdXRDb2x1bW5zID0gdGhpcy5jb2x1bW5MaXN0LmZpbHRlcigoY29sKSA9PiAhY29sLmNvbHVtbkxheW91dCAmJiAhY29sLmNvbHVtbkxheW91dENoaWxkKTtcbiAgICAgICAgICAgIHRoaXMuY29sdW1uTGlzdC5yZXNldChub25Db2x1bW5MYXlvdXRDb2x1bW5zKTtcbiAgICAgICAgfVxuICAgICAgICBzdXBlci5pbml0Q29sdW1ucyhjb2xsZWN0aW9uLCBjYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqIEdldHMgdGhlIHZpc2libGUgY29udGVudCBoZWlnaHQgdGhhdCBpbmNsdWRlcyBoZWFkZXIgKyB0Ym9keSArIGZvb3Rlci5cbiAgICAgKiBGb3IgaGllcmFyY2hpY2FsIGNoaWxkIGdyaWQgaXQgbWF5IGJlIHNjcm9sbGVkIGFuZCBub3QgZnVsbHkgdmlzaWJsZS5cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0VmlzaWJsZUNvbnRlbnRIZWlnaHQoKSB7XG4gICAgICAgIGxldCBoZWlnaHQgPSBzdXBlci5nZXRWaXNpYmxlQ29udGVudEhlaWdodCgpO1xuICAgICAgICBpZiAodGhpcy5wYXJlbnQpIHtcbiAgICAgICAgICAgIGNvbnN0IHJvb3RIZWlnaHQgPSB0aGlzLnJvb3RHcmlkLmdldFZpc2libGVDb250ZW50SGVpZ2h0KCk7XG4gICAgICAgICAgICBjb25zdCB0b3BEaWZmID0gdGhpcy5uYXRpdmVFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLnRvcCAtIHRoaXMucm9vdEdyaWQubmF0aXZlRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS50b3A7XG4gICAgICAgICAgICBoZWlnaHQgPSByb290SGVpZ2h0IC0gdG9wRGlmZiA+IGhlaWdodCA/IGhlaWdodCA6IHJvb3RIZWlnaHQgLSB0b3BEaWZmO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBoZWlnaHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICovXG4gICB0b2dnbGVBbGwoKSB7XG4gICAgY29uc3QgZXhwYW5kZWQgPSB0aGlzLmhpZXJhcmNoaWNhbFN0YXRlLmxlbmd0aCA+IDAgJiYgdGhpcy5oYXNFeHBhbmRhYmxlQ2hpbGRyZW47XG4gICAgaWYgKCFleHBhbmRlZCAmJiB0aGlzLnNob3dFeHBhbmRBbGwpIHtcbiAgICAgICAgdGhpcy5leHBhbmRBbGwoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmNvbGxhcHNlQWxsKCk7XG4gICAgfVxuICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29sbGFwc2VzIGFsbCByb3dzIG9mIHRoZSBjdXJyZW50IGhpZXJhcmNoaWNhbCBncmlkLlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiB0aGlzLmdyaWQuY29sbGFwc2VBbGwoKTtcbiAgICAgKiBgYGBcblx0ICogQG1lbWJlcm9mIElneEhpZXJhcmNoaWNhbEdyaWRDb21wb25lbnRcbiAgICAgKi9cbiAgICBwdWJsaWMgY29sbGFwc2VBbGwoKSB7XG4gICAgICAgIHRoaXMuaGllcmFyY2hpY2FsU3RhdGUgPSBbXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeHBhbmRzIGFsbCByb3dzIG9mIHRoZSBjdXJyZW50IGhpZXJhcmNoaWNhbCBncmlkLlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiB0aGlzLmdyaWQuZXhwYW5kQWxsKCk7XG4gICAgICogYGBgXG5cdCAqIEBtZW1iZXJvZiBJZ3hIaWVyYXJjaGljYWxHcmlkQ29tcG9uZW50XG4gICAgICovXG4gICAgcHVibGljIGV4cGFuZEFsbCgpIHtcbiAgICAgICAgaWYgKHRoaXMuZGF0YSkge1xuICAgICAgICAgICAgdGhpcy5oaWVyYXJjaGljYWxTdGF0ZSA9IHRoaXMuZGF0YS5tYXAoKHJlYykgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiB7IHJvd0lEOiB0aGlzLnByaW1hcnlLZXkgPyByZWNbdGhpcy5wcmltYXJ5S2V5XSA6IHJlYyB9O1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIGlzRXhwYW5kZWQocmVjb3JkOiBhbnkpOiBib29sZWFuIHtcbiAgICAgICAgbGV0IGluU3RhdGU7XG4gICAgICAgIGlmIChyZWNvcmQuY2hpbGRHcmlkc0RhdGEgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgaW5TdGF0ZSA9ICEhdGhpcy5oaWVyYXJjaGljYWxTdGF0ZS5maW5kKHYgPT4gdi5yb3dJRCA9PT0gcmVjb3JkLnJvd0lEKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGluU3RhdGUgPSAhIXRoaXMuaGllcmFyY2hpY2FsU3RhdGUuZmluZCh2ID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5wcmltYXJ5S2V5ID8gdi5yb3dJRCA9PT0gcmVjb3JkW3RoaXMucHJpbWFyeUtleV0gOiB2LnJvd0lEID09PSByZWNvcmQ7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaW5TdGF0ZSAmJiB0aGlzLmNoaWxkTGF5b3V0TGlzdC5sZW5ndGggIT09IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyB2aWV3Q3JlYXRlZEhhbmRsZXIoYXJncykge1xuICAgICAgICBpZiAodGhpcy5pc0NoaWxkR3JpZFJlY29yZChhcmdzLmNvbnRleHQuJGltcGxpY2l0KSkge1xuICAgICAgICAgICAgY29uc3Qga2V5ID0gYXJncy5jb250ZXh0LiRpbXBsaWNpdC5yb3dJRDtcbiAgICAgICAgICAgIHRoaXMuY2hpbGRHcmlkVGVtcGxhdGVzLnNldChrZXksIGFyZ3MpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyB2aWV3TW92ZWRIYW5kbGVyKGFyZ3MpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNDaGlsZEdyaWRSZWNvcmQoYXJncy5jb250ZXh0LiRpbXBsaWNpdCkpIHtcbiAgICAgICAgICAgIC8vIHZpZXcgd2FzIG1vdmVkLCB1cGRhdGUgb3duZXIgaW4gY2FjaGVcbiAgICAgICAgICAgIGNvbnN0IGtleSA9IGFyZ3MuY29udGV4dC4kaW1wbGljaXQucm93SUQ7XG4gICAgICAgICAgICBjb25zdCBjYWNoZWREYXRhID0gdGhpcy5jaGlsZEdyaWRUZW1wbGF0ZXMuZ2V0KGtleSk7XG4gICAgICAgICAgICBjYWNoZWREYXRhLm93bmVyID0gYXJncy5vd25lcjtcblxuICAgICAgICAgICAgdGhpcy5jaGlsZExheW91dExpc3QuZm9yRWFjaCgobGF5b3V0KSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVsYXRlZEdyaWQgPSB0aGlzLmhncmlkQVBJLmdldENoaWxkR3JpZEJ5SUQobGF5b3V0LmtleSwgYXJncy5jb250ZXh0LiRpbXBsaWNpdC5yb3dJRCk7XG4gICAgICAgICAgICAgICAgaWYgKHJlbGF0ZWRHcmlkICYmIHJlbGF0ZWRHcmlkLnVwZGF0ZU9uUmVuZGVyKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIERldGVjdCBjaGFuZ2VzIGlmIGBleHBhbmRDaGlsZHJlbmAgaGFzIGNoYW5nZWQgd2hlbiB0aGUgZ3JpZCB3YXNuJ3QgdmlzaWJsZS4gVGhpcyBpcyBmb3IgcGVyZm9ybWFuY2UgcmVhc29ucy5cbiAgICAgICAgICAgICAgICAgICAgcmVsYXRlZEdyaWQubm90aWZ5Q2hhbmdlcyh0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgcmVsYXRlZEdyaWQudXBkYXRlT25SZW5kZXIgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgY29uc3QgY2hpbGRHcmlkcyA9IHRoaXMuZ2V0Q2hpbGRHcmlkcyh0cnVlKTtcbiAgICAgICAgICAgIGNoaWxkR3JpZHMuZm9yRWFjaCgoZ3JpZCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChncmlkLmlzUGVyY2VudFdpZHRoKSB7XG4gICAgICAgICAgICAgICAgICAgIGdyaWQubm90aWZ5Q2hhbmdlcyh0cnVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZ3JpZC51cGRhdGVTY3JvbGxQb3NpdGlvbigpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIHVwZGF0ZVNjcm9sbFBvc2l0aW9uKCkge1xuICAgICAgICBjb25zdCB2U2NyID0gdGhpcy52ZXJ0aWNhbFNjcm9sbENvbnRhaW5lci5nZXRTY3JvbGwoKTtcbiAgICAgICAgY29uc3QgaFNjciA9IHRoaXMuaGVhZGVyQ29udGFpbmVyLmdldFNjcm9sbCgpO1xuICAgICAgICBpZiAodlNjcikge1xuICAgICAgICAgICAgdlNjci5zY3JvbGxUb3AgPSB0aGlzLnNjcm9sbFRvcDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaFNjcikge1xuICAgICAgICAgICAgaFNjci5zY3JvbGxMZWZ0ID0gdGhpcy5zY3JvbGxMZWZ0O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGdldENoaWxkR3JpZHMoaW5EZXBoPzogYm9vbGVhbikge1xuICAgICAgICByZXR1cm4gdGhpcy5oZ3JpZEFQSS5nZXRDaGlsZEdyaWRzKGluRGVwaCk7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGdlbmVyYXRlRGF0YUZpZWxkcyhkYXRhOiBhbnlbXSk6IHN0cmluZ1tdIHtcbiAgICAgICAgcmV0dXJuIHN1cGVyLmdlbmVyYXRlRGF0YUZpZWxkcyhkYXRhKS5maWx0ZXIoKGZpZWxkKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBsYXlvdXRzTGlzdCA9IHRoaXMucGFyZW50SXNsYW5kID8gdGhpcy5wYXJlbnRJc2xhbmQuY2hpbGRyZW4gOiB0aGlzLmNoaWxkTGF5b3V0TGlzdDtcbiAgICAgICAgICAgIGNvbnN0IGtleXMgPSBsYXlvdXRzTGlzdC5tYXAoKGl0ZW0pID0+IGl0ZW0ua2V5KTtcbiAgICAgICAgICAgIHJldHVybiBrZXlzLmluZGV4T2YoZmllbGQpID09PSAtMTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICBwcml2YXRlIGhnX3ZlcnRpY2FsU2Nyb2xsSGFuZGxlcihldmVudCkge1xuICAgICAgICB0aGlzLnNjcm9sbFRvcCA9IGV2ZW50LnRhcmdldC5zY3JvbGxUb3A7XG4gICAgfVxuXG4gICAgcHVibGljIG9uQ29udGFpbmVyU2Nyb2xsKCkge1xuICAgICAgICB0aGlzLmhpZGVPdmVybGF5cygpO1xuICAgIH1cblxuICAgIHByaXZhdGUgaGdfaG9yaXpvbnRhbFNjcm9sbEhhbmRsZXIoZXZlbnQpIHtcbiAgICAgICAgdGhpcy5zY3JvbGxMZWZ0ID0gZXZlbnQudGFyZ2V0LnNjcm9sbExlZnQ7XG4gICAgfVxufVxuIl19