primeng
Version:
[](https://badge.fury.io/js/primeng) [](https://www.npmjs.com/package/primeng) [ {
this.cd = cd;
this.chart = chart;
this.subscription = this.chart.selectionSource$.subscribe(() => {
this.cd.markForCheck();
});
}
get leaf() {
if (this.node) {
return this.node.leaf == false ? false : !(this.node.children && this.node.children.length);
}
}
get colspan() {
if (this.node) {
return this.node.children && this.node.children.length ? this.node.children.length * 2 : null;
}
}
onNodeClick(event, node) {
this.chart.onNodeClick(event, node);
}
toggleNode(event, node) {
node.expanded = !node.expanded;
if (node.expanded)
this.chart.onNodeExpand.emit({ originalEvent: event, node: this.node });
else
this.chart.onNodeCollapse.emit({ originalEvent: event, node: this.node });
event.preventDefault();
}
isSelected() {
return this.chart.isSelected(this.node);
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.7", ngImport: i0, type: OrganizationChartNode, deps: [{ token: forwardRef(() => OrganizationChart) }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "16.1.0", version: "17.3.7", type: OrganizationChartNode, selector: "[pOrganizationChartNode]", inputs: { node: "node", root: ["root", "root", booleanAttribute], first: ["first", "first", booleanAttribute], last: ["last", "last", booleanAttribute], collapsible: ["collapsible", "collapsible", booleanAttribute] }, host: { classAttribute: "p-element" }, ngImport: i0, template: `
<tbody *ngIf="node" [attr.data-pc-section]="'body'">
<tr [attr.data-pc-section]="'row'">
<td [attr.colspan]="colspan" [attr.data-pc-section]="'cell'">
<div
[class]="node.styleClass"
[ngClass]="{ 'p-organizationchart-node-content': true, 'p-organizationchart-selectable-node': chart.selectionMode && node.selectable !== false, 'p-highlight': isSelected() }"
(click)="onNodeClick($event, node)"
[attr.data-pc-section]="'node'"
>
<div *ngIf="!chart.getTemplateForNode(node)">{{ node.label }}</div>
<div *ngIf="chart.getTemplateForNode(node)">
<ng-container *ngTemplateOutlet="chart.getTemplateForNode(node); context: { $implicit: node }"></ng-container>
</div>
<ng-container *ngIf="collapsible">
<a *ngIf="!leaf" tabindex="0" class="p-node-toggler" (click)="toggleNode($event, node)" (keydown.enter)="toggleNode($event, node)" (keydown.space)="toggleNode($event, node)" [attr.data-pc-section]="'nodeToggler'">
<ng-container *ngIf="!chart.togglerIconTemplate">
<ChevronDownIcon *ngIf="node.expanded" [styleClass]="'p-node-toggler-icon'" [attr.data-pc-section]="'nodeTogglerIcon'" />
<ChevronUpIcon *ngIf="!node.expanded" [styleClass]="'p-node-toggler-icon'" [attr.data-pc-section]="'nodeTogglerIcon'" />
</ng-container>
<span class="p-node-toggler-icon" *ngIf="chart.togglerIconTemplate" [attr.data-pc-section]="'nodeTogglerIcon'">
<ng-template *ngTemplateOutlet="chart.togglerIconTemplate; context: { $implicit: node.expanded }"></ng-template>
</span>
</a>
</ng-container>
</div>
</td>
</tr>
<tr [ngClass]="!leaf && node.expanded ? 'p-organizationchart-node-visible' : 'p-organizationchart-node-hidden'" class="p-organizationchart-lines" [@childState]="'in'" [attr.data-pc-section]="'lines'">
<td [attr.data-pc-section]="'lineCell'" [attr.colspan]="colspan">
<div [attr.data-pc-section]="'lineDown'" class="p-organizationchart-line-down"></div>
</td>
</tr>
<tr [ngClass]="!leaf && node.expanded ? 'p-organizationchart-node-visible' : 'p-organizationchart-node-hidden'" class="p-organizationchart-lines" [@childState]="'in'" [attr.data-pc-section]="'lines'">
<ng-container *ngIf="node.children && node.children.length === 1">
<td [attr.data-pc-section]="'lineCell'" [attr.colspan]="colspan">
<div [attr.data-pc-section]="'lineDown'" class="p-organizationchart-line-down"></div>
</td>
</ng-container>
<ng-container *ngIf="node.children && node.children.length > 1">
<ng-template ngFor let-child [ngForOf]="node.children" let-first="first" let-last="last">
<td [attr.data-pc-section]="'lineLeft'" class="p-organizationchart-line-left" [ngClass]="{ 'p-organizationchart-line-top': !first }"> </td>
<td [attr.data-pc-section]="'lineRight'" class="p-organizationchart-line-right" [ngClass]="{ 'p-organizationchart-line-top': !last }"> </td>
</ng-template>
</ng-container>
</tr>
<tr [ngClass]="!leaf && node.expanded ? 'p-organizationchart-node-visible' : 'p-organizationchart-node-hidden'" class="p-organizationchart-nodes" [@childState]="'in'" [attr.data-pc-section]="'nodes'">
<td *ngFor="let child of node.children" colspan="2" [attr.data-pc-section]="'nodeCell'">
<table class="p-organizationchart-table" pOrganizationChartNode [node]="child" [collapsible]="node.children && node.children.length > 0"></table>
</td>
</tr>
</tbody>
`, isInline: true, styles: ["@layer primeng{.p-organizationchart-table{border-spacing:0;border-collapse:separate;margin:0 auto}.p-organizationchart-table>tbody>tr>td{text-align:center;vertical-align:top;padding:0 .75rem}.p-organizationchart-node-content{display:inline-block;position:relative}.p-organizationchart-node-content .p-node-toggler{position:absolute;bottom:-.75rem;margin-left:-.75rem;z-index:2;left:50%;-webkit-user-select:none;user-select:none;cursor:pointer;width:1.5rem;height:1.5rem}.p-organizationchart-node-content .p-node-toggler .p-node-toggler-icon{position:relative;top:.25rem}.p-organizationchart-line-down{margin:0 auto;height:20px;width:1px}.p-organizationchart-line-right,.p-organizationchart-line-left{border-radius:0}.p-organizationchart-selectable-node{cursor:pointer}.p-organizationchart .p-organizationchart-node-hidden{display:none}.p-organizationchart-preservespace .p-organizationchart-node-hidden{visibility:hidden;display:inherit}}\n"], dependencies: [{ kind: "directive", type: i0.forwardRef(() => i1.NgClass), selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i0.forwardRef(() => i1.NgForOf), selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i0.forwardRef(() => i1.NgIf), selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i0.forwardRef(() => i1.NgTemplateOutlet), selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i0.forwardRef(() => ChevronDownIcon), selector: "ChevronDownIcon" }, { kind: "component", type: i0.forwardRef(() => ChevronUpIcon), selector: "ChevronUpIcon" }, { kind: "component", type: i0.forwardRef(() => OrganizationChartNode), selector: "[pOrganizationChartNode]", inputs: ["node", "root", "first", "last", "collapsible"] }], animations: [trigger('childState', [state('in', style({ opacity: 1 })), transition('void => *', [style({ opacity: 0 }), animate(150)]), transition('* => void', [animate(150, style({ opacity: 0 }))])])], changeDetection: i0.ChangeDetectionStrategy.Default, encapsulation: i0.ViewEncapsulation.None });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.7", ngImport: i0, type: OrganizationChartNode, decorators: [{
type: Component,
args: [{ selector: '[pOrganizationChartNode]', template: `
<tbody *ngIf="node" [attr.data-pc-section]="'body'">
<tr [attr.data-pc-section]="'row'">
<td [attr.colspan]="colspan" [attr.data-pc-section]="'cell'">
<div
[class]="node.styleClass"
[ngClass]="{ 'p-organizationchart-node-content': true, 'p-organizationchart-selectable-node': chart.selectionMode && node.selectable !== false, 'p-highlight': isSelected() }"
(click)="onNodeClick($event, node)"
[attr.data-pc-section]="'node'"
>
<div *ngIf="!chart.getTemplateForNode(node)">{{ node.label }}</div>
<div *ngIf="chart.getTemplateForNode(node)">
<ng-container *ngTemplateOutlet="chart.getTemplateForNode(node); context: { $implicit: node }"></ng-container>
</div>
<ng-container *ngIf="collapsible">
<a *ngIf="!leaf" tabindex="0" class="p-node-toggler" (click)="toggleNode($event, node)" (keydown.enter)="toggleNode($event, node)" (keydown.space)="toggleNode($event, node)" [attr.data-pc-section]="'nodeToggler'">
<ng-container *ngIf="!chart.togglerIconTemplate">
<ChevronDownIcon *ngIf="node.expanded" [styleClass]="'p-node-toggler-icon'" [attr.data-pc-section]="'nodeTogglerIcon'" />
<ChevronUpIcon *ngIf="!node.expanded" [styleClass]="'p-node-toggler-icon'" [attr.data-pc-section]="'nodeTogglerIcon'" />
</ng-container>
<span class="p-node-toggler-icon" *ngIf="chart.togglerIconTemplate" [attr.data-pc-section]="'nodeTogglerIcon'">
<ng-template *ngTemplateOutlet="chart.togglerIconTemplate; context: { $implicit: node.expanded }"></ng-template>
</span>
</a>
</ng-container>
</div>
</td>
</tr>
<tr [ngClass]="!leaf && node.expanded ? 'p-organizationchart-node-visible' : 'p-organizationchart-node-hidden'" class="p-organizationchart-lines" [@childState]="'in'" [attr.data-pc-section]="'lines'">
<td [attr.data-pc-section]="'lineCell'" [attr.colspan]="colspan">
<div [attr.data-pc-section]="'lineDown'" class="p-organizationchart-line-down"></div>
</td>
</tr>
<tr [ngClass]="!leaf && node.expanded ? 'p-organizationchart-node-visible' : 'p-organizationchart-node-hidden'" class="p-organizationchart-lines" [@childState]="'in'" [attr.data-pc-section]="'lines'">
<ng-container *ngIf="node.children && node.children.length === 1">
<td [attr.data-pc-section]="'lineCell'" [attr.colspan]="colspan">
<div [attr.data-pc-section]="'lineDown'" class="p-organizationchart-line-down"></div>
</td>
</ng-container>
<ng-container *ngIf="node.children && node.children.length > 1">
<ng-template ngFor let-child [ngForOf]="node.children" let-first="first" let-last="last">
<td [attr.data-pc-section]="'lineLeft'" class="p-organizationchart-line-left" [ngClass]="{ 'p-organizationchart-line-top': !first }"> </td>
<td [attr.data-pc-section]="'lineRight'" class="p-organizationchart-line-right" [ngClass]="{ 'p-organizationchart-line-top': !last }"> </td>
</ng-template>
</ng-container>
</tr>
<tr [ngClass]="!leaf && node.expanded ? 'p-organizationchart-node-visible' : 'p-organizationchart-node-hidden'" class="p-organizationchart-nodes" [@childState]="'in'" [attr.data-pc-section]="'nodes'">
<td *ngFor="let child of node.children" colspan="2" [attr.data-pc-section]="'nodeCell'">
<table class="p-organizationchart-table" pOrganizationChartNode [node]="child" [collapsible]="node.children && node.children.length > 0"></table>
</td>
</tr>
</tbody>
`, animations: [trigger('childState', [state('in', style({ opacity: 1 })), transition('void => *', [style({ opacity: 0 }), animate(150)]), transition('* => void', [animate(150, style({ opacity: 0 }))])])], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.Default, host: {
class: 'p-element'
}, styles: ["@layer primeng{.p-organizationchart-table{border-spacing:0;border-collapse:separate;margin:0 auto}.p-organizationchart-table>tbody>tr>td{text-align:center;vertical-align:top;padding:0 .75rem}.p-organizationchart-node-content{display:inline-block;position:relative}.p-organizationchart-node-content .p-node-toggler{position:absolute;bottom:-.75rem;margin-left:-.75rem;z-index:2;left:50%;-webkit-user-select:none;user-select:none;cursor:pointer;width:1.5rem;height:1.5rem}.p-organizationchart-node-content .p-node-toggler .p-node-toggler-icon{position:relative;top:.25rem}.p-organizationchart-line-down{margin:0 auto;height:20px;width:1px}.p-organizationchart-line-right,.p-organizationchart-line-left{border-radius:0}.p-organizationchart-selectable-node{cursor:pointer}.p-organizationchart .p-organizationchart-node-hidden{display:none}.p-organizationchart-preservespace .p-organizationchart-node-hidden{visibility:hidden;display:inherit}}\n"] }]
}], ctorParameters: () => [{ type: OrganizationChart, decorators: [{
type: Inject,
args: [forwardRef(() => OrganizationChart)]
}] }, { type: i0.ChangeDetectorRef }], propDecorators: { node: [{
type: Input
}], root: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], first: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], last: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], collapsible: [{
type: Input,
args: [{ transform: booleanAttribute }]
}] } });
/**
* OrganizationChart visualizes hierarchical organization data.
* @group Components
*/
export class OrganizationChart {
el;
cd;
/**
* An array of nested TreeNodes.
* @group Props
*/
value;
/**
* Inline style of the component.
* @group Props
*/
style;
/**
* Style class of the component.
* @group Props
*/
styleClass;
/**
* Defines the selection mode.
* @group Props
*/
selectionMode;
/**
* Whether the nodes can be expanded or toggled.
* @group Props
*/
collapsible;
/**
* Whether the space allocated by a node is preserved when hidden.
* @group Props
*/
preserveSpace = true;
/**
* A single treenode instance or an array to refer to the selections.
* @group Props
*/
get selection() {
return this._selection;
}
set selection(val) {
this._selection = val;
if (this.initialized)
this.selectionSource.next(null);
}
/**
* Callback to invoke on selection change.
* @param {*} any - selected value.
* @group Emits
*/
selectionChange = new EventEmitter();
/**
* Callback to invoke when a node is selected.
* @param {OrganizationChartNodeSelectEvent} event - custom node select event.
* @group Emits
*/
onNodeSelect = new EventEmitter();
/**
* Callback to invoke when a node is unselected.
* @param {OrganizationChartNodeUnSelectEvent} event - custom node unselect event.
* @group Emits
*/
onNodeUnselect = new EventEmitter();
/**
* Callback to invoke when a node is expanded.
* @param {OrganizationChartNodeExpandEvent} event - custom node expand event.
* @group Emits
*/
onNodeExpand = new EventEmitter();
/**
* Callback to invoke when a node is collapsed.
* @param {OrganizationChartNodeCollapseEvent} event - custom node collapse event.
* @group Emits
*/
onNodeCollapse = new EventEmitter();
templates;
templateMap;
togglerIconTemplate;
selectionSource = new Subject();
_selection;
initialized;
selectionSource$ = this.selectionSource.asObservable();
constructor(el, cd) {
this.el = el;
this.cd = cd;
}
get root() {
return this.value && this.value.length ? this.value[0] : null;
}
ngAfterContentInit() {
if (this.templates.length) {
this.templateMap = {};
}
this.templates.forEach((item) => {
if (item.getType() === 'togglericon') {
this.togglerIconTemplate = item.template;
}
else {
this.templateMap[item.getType()] = item.template;
}
});
this.initialized = true;
}
getTemplateForNode(node) {
if (this.templateMap)
return node.type ? this.templateMap[node.type] : this.templateMap['default'];
else
return null;
}
onNodeClick(event, node) {
let eventTarget = event.target;
if (eventTarget.className && (DomHandler.hasClass(eventTarget, 'p-node-toggler') || DomHandler.hasClass(eventTarget, 'p-node-toggler-icon'))) {
return;
}
else if (this.selectionMode) {
if (node.selectable === false) {
return;
}
let index = this.findIndexInSelection(node);
let selected = index >= 0;
if (this.selectionMode === 'single') {
if (selected) {
this.selection = null;
this.onNodeUnselect.emit({ originalEvent: event, node: node });
}
else {
this.selection = node;
this.onNodeSelect.emit({ originalEvent: event, node: node });
}
}
else if (this.selectionMode === 'multiple') {
if (selected) {
this.selection = this.selection.filter((val, i) => i != index);
this.onNodeUnselect.emit({ originalEvent: event, node: node });
}
else {
this.selection = [...(this.selection || []), node];
this.onNodeSelect.emit({ originalEvent: event, node: node });
}
}
this.selectionChange.emit(this.selection);
this.selectionSource.next(null);
}
}
findIndexInSelection(node) {
let index = -1;
if (this.selectionMode && this.selection) {
if (this.selectionMode === 'single') {
index = this.selection == node ? 0 : -1;
}
else if (this.selectionMode === 'multiple') {
for (let i = 0; i < this.selection.length; i++) {
if (this.selection[i] == node) {
index = i;
break;
}
}
}
}
return index;
}
isSelected(node) {
return this.findIndexInSelection(node) != -1;
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.7", ngImport: i0, type: OrganizationChart, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "16.1.0", version: "17.3.7", type: OrganizationChart, selector: "p-organizationChart", inputs: { value: "value", style: "style", styleClass: "styleClass", selectionMode: "selectionMode", collapsible: ["collapsible", "collapsible", booleanAttribute], preserveSpace: ["preserveSpace", "preserveSpace", booleanAttribute], selection: "selection" }, outputs: { selectionChange: "selectionChange", onNodeSelect: "onNodeSelect", onNodeUnselect: "onNodeUnselect", onNodeExpand: "onNodeExpand", onNodeCollapse: "onNodeCollapse" }, host: { classAttribute: "p-element" }, queries: [{ propertyName: "templates", predicate: PrimeTemplate }], ngImport: i0, template: `
<div [ngStyle]="style" [class]="styleClass" [ngClass]="{ 'p-organizationchart p-component': true, 'p-organizationchart-preservespace': preserveSpace }" [attr.data-pc-section]="'root'">
<table class="p-organizationchart-table" [collapsible]="collapsible" pOrganizationChartNode [node]="root" *ngIf="root"></table>
</div>
`, isInline: true, dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: OrganizationChartNode, selector: "[pOrganizationChartNode]", inputs: ["node", "root", "first", "last", "collapsible"] }], changeDetection: i0.ChangeDetectionStrategy.Default });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.7", ngImport: i0, type: OrganizationChart, decorators: [{
type: Component,
args: [{
selector: 'p-organizationChart',
template: `
<div [ngStyle]="style" [class]="styleClass" [ngClass]="{ 'p-organizationchart p-component': true, 'p-organizationchart-preservespace': preserveSpace }" [attr.data-pc-section]="'root'">
<table class="p-organizationchart-table" [collapsible]="collapsible" pOrganizationChartNode [node]="root" *ngIf="root"></table>
</div>
`,
changeDetection: ChangeDetectionStrategy.Default,
host: {
class: 'p-element'
}
}]
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }], propDecorators: { value: [{
type: Input
}], style: [{
type: Input
}], styleClass: [{
type: Input
}], selectionMode: [{
type: Input
}], collapsible: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], preserveSpace: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], selection: [{
type: Input
}], selectionChange: [{
type: Output
}], onNodeSelect: [{
type: Output
}], onNodeUnselect: [{
type: Output
}], onNodeExpand: [{
type: Output
}], onNodeCollapse: [{
type: Output
}], templates: [{
type: ContentChildren,
args: [PrimeTemplate]
}] } });
export class OrganizationChartModule {
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.7", ngImport: i0, type: OrganizationChartModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.3.7", ngImport: i0, type: OrganizationChartModule, declarations: [OrganizationChart, OrganizationChartNode], imports: [CommonModule, ChevronDownIcon, ChevronUpIcon, SharedModule], exports: [OrganizationChart, SharedModule] });
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.3.7", ngImport: i0, type: OrganizationChartModule, imports: [CommonModule, ChevronDownIcon, ChevronUpIcon, SharedModule, SharedModule] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.7", ngImport: i0, type: OrganizationChartModule, decorators: [{
type: NgModule,
args: [{
imports: [CommonModule, ChevronDownIcon, ChevronUpIcon, SharedModule],
exports: [OrganizationChart, SharedModule],
declarations: [OrganizationChart, OrganizationChartNode]
}]
}] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3JnYW5pemF0aW9uY2hhcnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYXBwL2NvbXBvbmVudHMvb3JnYW5pemF0aW9uY2hhcnQvb3JnYW5pemF0aW9uY2hhcnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLFVBQVUsRUFBRSxPQUFPLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNqRixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUVILHVCQUF1QixFQUV2QixTQUFTLEVBQ1QsZUFBZSxFQUVmLFlBQVksRUFDWixNQUFNLEVBQ04sS0FBSyxFQUNMLFFBQVEsRUFFUixNQUFNLEVBR04saUJBQWlCLEVBQ2pCLGdCQUFnQixFQUNoQixVQUFVLEVBQ2IsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLGFBQWEsRUFBRSxZQUFZLEVBQVksTUFBTSxhQUFhLENBQUM7QUFDcEUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUN6QyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDNUQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBRXhELE9BQU8sRUFBRSxPQUFPLEVBQWdCLE1BQU0sTUFBTSxDQUFDOzs7QUFpRTdDLE1BQU0sT0FBTyxxQkFBcUI7SUFlNEQ7SUFkakYsSUFBSSxDQUE0QjtJQUVELElBQUksQ0FBc0I7SUFFMUIsS0FBSyxDQUFzQjtJQUUzQixJQUFJLENBQXNCO0lBRTFCLFdBQVcsQ0FBc0I7SUFFekUsS0FBSyxDQUFvQjtJQUV6QixZQUFZLENBQWU7SUFFM0IsWUFBeUQsS0FBd0IsRUFBUyxFQUFxQjtRQUFyQixPQUFFLEdBQUYsRUFBRSxDQUFtQjtRQUMzRyxJQUFJLENBQUMsS0FBSyxHQUFHLEtBQTBCLENBQUM7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O29CQUNOLE9BQU8sRUFBRSxDQUFDLFlBQVksRUFBRSxlQUFlLEVBQUUsYUFBYSxFQUFFLFlBQVksQ0FBQztvQkFDckUsT0FBTyxFQUFFLENBQUMsaUJBQWlCLEVBQUUsWUFBWSxDQUFDO29CQUMxQyxZQUFZLEVBQUUsQ0FBQyxpQkFBaUIsRUFBRSxxQkFBcUIsQ0FBQztpQkFDM0QiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBhbmltYXRlLCBzdGF0ZSwgc3R5bGUsIHRyYW5zaXRpb24sIHRyaWdnZXIgfSBmcm9tICdAYW5ndWxhci9hbmltYXRpb25zJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQge1xuICAgIEFmdGVyQ29udGVudEluaXQsXG4gICAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gICAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgQ29tcG9uZW50LFxuICAgIENvbnRlbnRDaGlsZHJlbixcbiAgICBFbGVtZW50UmVmLFxuICAgIEV2ZW50RW1pdHRlcixcbiAgICBJbmplY3QsXG4gICAgSW5wdXQsXG4gICAgTmdNb2R1bGUsXG4gICAgT25EZXN0cm95LFxuICAgIE91dHB1dCxcbiAgICBRdWVyeUxpc3QsXG4gICAgVGVtcGxhdGVSZWYsXG4gICAgVmlld0VuY2Fwc3VsYXRpb24sXG4gICAgYm9vbGVhbkF0dHJpYnV0ZSxcbiAgICBmb3J3YXJkUmVmXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgUHJpbWVUZW1wbGF0ZSwgU2hhcmVkTW9kdWxlLCBUcmVlTm9kZSB9IGZyb20gJ3ByaW1lbmcvYXBpJztcbmltcG9ydCB7IERvbUhhbmRsZXIgfSBmcm9tICdwcmltZW5nL2RvbSc7XG5pbXBvcnQgeyBDaGV2cm9uRG93bkljb24gfSBmcm9tICdwcmltZW5nL2ljb25zL2NoZXZyb25kb3duJztcbmltcG9ydCB7IENoZXZyb25VcEljb24gfSBmcm9tICdwcmltZW5nL2ljb25zL2NoZXZyb251cCc7XG5pbXBvcnQgeyBOdWxsYWJsZSB9IGZyb20gJ3ByaW1lbmcvdHMtaGVscGVycyc7XG5pbXBvcnQgeyBTdWJqZWN0LCBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IE9yZ2FuaXphdGlvbkNoYXJ0Tm9kZUNvbGxhcHNlRXZlbnQsIE9yZ2FuaXphdGlvbkNoYXJ0Tm9kZUV4cGFuZEV2ZW50LCBPcmdhbml6YXRpb25DaGFydE5vZGVTZWxlY3RFdmVudCwgT3JnYW5pemF0aW9uQ2hhcnROb2RlVW5TZWxlY3RFdmVudCB9IGZyb20gJy4vb3JnYW5pemF0aW9uY2hhcnQuaW50ZXJmYWNlJztcbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnW3BPcmdhbml6YXRpb25DaGFydE5vZGVdJyxcbiAgICB0ZW1wbGF0ZTogYFxuICAgICAgICA8dGJvZHkgKm5nSWY9XCJub2RlXCIgW2F0dHIuZGF0YS1wYy1zZWN0aW9uXT1cIidib2R5J1wiPlxuICAgICAgICAgICAgPHRyIFthdHRyLmRhdGEtcGMtc2VjdGlvbl09XCIncm93J1wiPlxuICAgICAgICAgICAgICAgIDx0ZCBbYXR0ci5jb2xzcGFuXT1cImNvbHNwYW5cIiBbYXR0ci5kYXRhLXBjLXNlY3Rpb25dPVwiJ2NlbGwnXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzc109XCJub2RlLnN0eWxlQ2xhc3NcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieyAncC1vcmdhbml6YXRpb25jaGFydC1ub2RlLWNvbnRlbnQnOiB0cnVlLCAncC1vcmdhbml6YXRpb25jaGFydC1zZWxlY3RhYmxlLW5vZGUnOiBjaGFydC5zZWxlY3Rpb25Nb2RlICYmIG5vZGUuc2VsZWN0YWJsZSAhPT0gZmFsc2UsICdwLWhpZ2hsaWdodCc6IGlzU2VsZWN0ZWQoKSB9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJvbk5vZGVDbGljaygkZXZlbnQsIG5vZGUpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFthdHRyLmRhdGEtcGMtc2VjdGlvbl09XCInbm9kZSdcIlxuICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiIWNoYXJ0LmdldFRlbXBsYXRlRm9yTm9kZShub2RlKVwiPnt7IG5vZGUubGFiZWwgfX08L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJjaGFydC5nZXRUZW1wbGF0ZUZvck5vZGUobm9kZSlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiY2hhcnQuZ2V0VGVtcGxhdGVGb3JOb2RlKG5vZGUpOyBjb250ZXh0OiB7ICRpbXBsaWNpdDogbm9kZSB9XCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjb2xsYXBzaWJsZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxhICpuZ0lmPVwiIWxlYWZcIiB0YWJpbmRleD1cIjBcIiBjbGFzcz1cInAtbm9kZS10b2dnbGVyXCIgKGNsaWNrKT1cInRvZ2dsZU5vZGUoJGV2ZW50LCBub2RlKVwiIChrZXlkb3duLmVudGVyKT1cInRvZ2dsZU5vZGUoJGV2ZW50LCBub2RlKVwiIChrZXlkb3duLnNwYWNlKT1cInRvZ2dsZU5vZGUoJGV2ZW50LCBub2RlKVwiIFthdHRyLmRhdGEtcGMtc2VjdGlvbl09XCInbm9kZVRvZ2dsZXInXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhY2hhcnQudG9nZ2xlckljb25UZW1wbGF0ZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPENoZXZyb25Eb3duSWNvbiAqbmdJZj1cIm5vZGUuZXhwYW5kZWRcIiBbc3R5bGVDbGFzc109XCIncC1ub2RlLXRvZ2dsZXItaWNvbidcIiBbYXR0ci5kYXRhLXBjLXNlY3Rpb25dPVwiJ25vZGVUb2dnbGVySWNvbidcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPENoZXZyb25VcEljb24gKm5nSWY9XCIhbm9kZS5leHBhbmRlZFwiIFtzdHlsZUNsYXNzXT1cIidwLW5vZGUtdG9nZ2xlci1pY29uJ1wiIFthdHRyLmRhdGEtcGMtc2VjdGlvbl09XCInbm9kZVRvZ2dsZXJJY29uJ1wiIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInAtbm9kZS10b2dnbGVyLWljb25cIiAqbmdJZj1cImNoYXJ0LnRvZ2dsZXJJY29uVGVtcGxhdGVcIiBbYXR0ci5kYXRhLXBjLXNlY3Rpb25dPVwiJ25vZGVUb2dnbGVySWNvbidcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAqbmdUZW1wbGF0ZU91dGxldD1cImNoYXJ0LnRvZ2dsZXJJY29uVGVtcGxhdGU7IGNvbnRleHQ6IHsgJGltcGxpY2l0OiBub2RlLmV4cGFuZGVkIH1cIj48L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgPHRyIFtuZ0NsYXNzXT1cIiFsZWFmICYmIG5vZGUuZXhwYW5kZWQgPyAncC1vcmdhbml6YXRpb25jaGFydC1ub2RlLXZpc2libGUnIDogJ3Atb3JnYW5pemF0aW9uY2hhcnQtbm9kZS1oaWRkZW4nXCIgY2xhc3M9XCJwLW9yZ2FuaXphdGlvbmNoYXJ0LWxpbmVzXCIgW0BjaGlsZFN0YXRlXT1cIidpbidcIiBbYXR0ci5kYXRhLXBjLXNlY3Rpb25dPVwiJ2xpbmVzJ1wiPlxuICAgICAgICAgICAgICAgIDx0ZCBbYXR0ci5kYXRhLXBjLXNlY3Rpb25dPVwiJ2xpbmVDZWxsJ1wiIFthdHRyLmNvbHNwYW5dPVwiY29sc3BhblwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IFthdHRyLmRhdGEtcGMtc2VjdGlvbl09XCInbGluZURvd24nXCIgY2xhc3M9XCJwLW9yZ2FuaXphdGlvbmNoYXJ0LWxpbmUtZG93blwiPjwvZGl2PlxuICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgPHRyIFtuZ0NsYXNzXT1cIiFsZWFmICYmIG5vZGUuZXhwYW5kZWQgPyAncC1vcmdhbml6YXRpb25jaGFydC1ub2RlLXZpc2libGUnIDogJ3Atb3JnYW5pemF0aW9uY2hhcnQtbm9kZS1oaWRkZW4nXCIgY2xhc3M9XCJwLW9yZ2FuaXphdGlvbmNoYXJ0LWxpbmVzXCIgW0BjaGlsZFN0YXRlXT1cIidpbidcIiBbYXR0ci5kYXRhLXBjLXNlY3Rpb25dPVwiJ2xpbmVzJ1wiPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJub2RlLmNoaWxkcmVuICYmIG5vZGUuY2hpbGRyZW4ubGVuZ3RoID09PSAxXCI+XG4gICAgICAgICAgICAgICAgICAgIDx0ZCBbYXR0ci5kYXRhLXBjLXNlY3Rpb25dPVwiJ2xpbmVDZWxsJ1wiIFthdHRyLmNvbHNwYW5dPVwiY29sc3BhblwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBbYXR0ci5kYXRhLXBjLXNlY3Rpb25dPVwiJ2xpbmVEb3duJ1wiIGNsYXNzPVwicC1vcmdhbml6YXRpb25jaGFydC1saW5lLWRvd25cIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwibm9kZS5jaGlsZHJlbiAmJiBub2RlLmNoaWxkcmVuLmxlbmd0aCA+IDFcIj5cbiAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIG5nRm9yIGxldC1jaGlsZCBbbmdGb3JPZl09XCJub2RlLmNoaWxkcmVuXCIgbGV0LWZpcnN0PVwiZmlyc3RcIiBsZXQtbGFzdD1cImxhc3RcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBbYXR0ci5kYXRhLXBjLXNlY3Rpb25dPVwiJ2xpbmVMZWZ0J1wiIGNsYXNzPVwicC1vcmdhbml6YXRpb25jaGFydC1saW5lLWxlZnRcIiBbbmdDbGFzc109XCJ7ICdwLW9yZ2FuaXphdGlvbmNoYXJ0LWxpbmUtdG9wJzogIWZpcnN0IH1cIj4mbmJzcDs8L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRkIFthdHRyLmRhdGEtcGMtc2VjdGlvbl09XCInbGluZVJpZ2h0J1wiIGNsYXNzPVwicC1vcmdhbml6YXRpb25jaGFydC1saW5lLXJpZ2h0XCIgW25nQ2xhc3NdPVwieyAncC1vcmdhbml6YXRpb25jaGFydC1saW5lLXRvcCc6ICFsYXN0IH1cIj4mbmJzcDs8L3RkPlxuICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICAgIDx0ciBbbmdDbGFzc109XCIhbGVhZiAmJiBub2RlLmV4cGFuZGVkID8gJ3Atb3JnYW5pemF0aW9uY2hhcnQtbm9kZS12aXNpYmxlJyA6ICdwLW9yZ2FuaXphdGlvbmNoYXJ0LW5vZGUtaGlkZGVuJ1wiIGNsYXNzPVwicC1vcmdhbml6YXRpb25jaGFydC1ub2Rlc1wiIFtAY2hpbGRTdGF0ZV09XCInaW4nXCIgW2F0dHIuZGF0YS1wYy1zZWN0aW9uXT1cIidub2RlcydcIj5cbiAgICAgICAgICAgICAgICA8dGQgKm5nRm9yPVwibGV0IGNoaWxkIG9mIG5vZGUuY2hpbGRyZW5cIiBjb2xzcGFuPVwiMlwiIFthdHRyLmRhdGEtcGMtc2VjdGlvbl09XCInbm9kZUNlbGwnXCI+XG4gICAgICAgICAgICAgICAgICAgIDx0YWJsZSBjbGFzcz1cInAtb3JnYW5pemF0aW9uY2hhcnQtdGFibGVcIiBwT3JnYW5pemF0aW9uQ2hhcnROb2RlIFtub2RlXT1cImNoaWxkXCIgW2NvbGxhcHNpYmxlXT1cIm5vZGUuY2hpbGRyZW4gJiYgbm9kZS5jaGlsZHJlbi5sZW5ndGggPiAwXCI+PC90YWJsZT5cbiAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPC90cj5cbiAgICAgICAgPC90Ym9keT5cbiAgICBgLFxuICAgIGFuaW1hdGlvbnM6IFt0cmlnZ2VyKCdjaGlsZFN0YXRlJywgW3N0YXRlKCdpbicsIHN0eWxlKHsgb3BhY2l0eTogMSB9KSksIHRyYW5zaXRpb24oJ3ZvaWQgPT4gKicsIFtzdHlsZSh7IG9wYWNpdHk6IDAgfSksIGFuaW1hdGUoMTUwKV0pLCB0cmFuc2l0aW9uKCcqID0+IHZvaWQnLCBbYW5pbWF0ZSgxNTAsIHN0eWxlKHsgb3BhY2l0eTogMCB9KSldKV0pXSxcbiAgICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICAgIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuRGVmYXVsdCxcbiAgICBzdHlsZVVybHM6IFsnLi9vcmdhbml6YXRpb25jaGFydC5jc3MnXSxcbiAgICBob3N0OiB7XG4gICAgICAgIGNsYXNzOiAncC1lbGVtZW50J1xuICAgIH1cbn0pXG5leHBvcnQgY2xhc3MgT3JnYW5pemF0aW9uQ2hhcnROb2RlIGltcGxlbWVudHMgT25EZXN0cm95IHtcbiAgICBASW5wdXQoKSBub2RlOiBUcmVlTm9kZTxhbnk+IHwgdW5kZWZpbmVkO1xuXG4gICAgQElucHV0KHsgdHJhbnNmb3JtOiBib29sZWFuQXR0cmlidXRlIH0pIHJvb3Q6IGJvb2xlYW4gfCB1bmRlZmluZWQ7XG5cbiAgICBASW5wdXQoeyB0cmFuc2Zvcm06IGJvb2xlYW5BdHRyaWJ1dGUgfSkgZmlyc3Q6IGJvb2xlYW4gfCB1bmRlZmluZWQ7XG5cbiAgICBASW5wdXQoeyB0cmFuc2Zvcm06IGJvb2xlYW5BdHRyaWJ1dGUgfSkgbGFzdDogYm9vbGVhbiB8IHVuZGVmaW5lZDtcblxuICAgIEBJbnB1dCh7IHRyYW5zZm9ybTogYm9vbGVhbkF0dHJpYnV0ZSB9KSBjb2xsYXBzaWJsZTogYm9vbGVhbiB8IHVuZGVmaW5lZDtcblxuICAgIGNoYXJ0OiBPcmdhbml6YXRpb25DaGFydDtcblxuICAgIHN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uO1xuXG4gICAgY29uc3RydWN0b3IoQEluamVjdChmb3J3YXJkUmVmKCgpID0+IE9yZ2FuaXphdGlvbkNoYXJ0KSkgY2hhcnQ6IE9yZ2FuaXphdGlvbkNoYXJ0LCBwdWJsaWMgY2Q6IENoYW5nZURldGVjdG9yUmVmKSB7XG4gICAgICAgIHRoaXMuY2hhcnQgPSBjaGFydCBhcyBPcmdhbml6YXRpb25DaGFydDtcbiAgICAgICAgdGhpcy5zdWJzY3JpcHRpb24gPSB0aGlzLmNoYXJ0LnNlbGVjdGlvblNvdXJjZSQuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuY2QubWFya0ZvckNoZWNrKCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGdldCBsZWFmKCk6IGJvb2xlYW4gfCB1bmRlZmluZWQge1xuICAgICAgICBpZiAodGhpcy5ub2RlKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5ub2RlLmxlYWYgPT0gZmFsc2UgPyBmYWxzZSA6ICEodGhpcy5ub2RlLmNoaWxkcmVuICYmIHRoaXMubm9kZS5jaGlsZHJlbi5sZW5ndGgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2V0IGNvbHNwYW4oKSB7XG4gICAgICAgIGlmICh0aGlzLm5vZGUpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm5vZGUuY2hpbGRyZW4gJiYgdGhpcy5ub2RlLmNoaWxkcmVuLmxlbmd0aCA/IHRoaXMubm9kZS5jaGlsZHJlbi5sZW5ndGggKiAyIDogbnVsbDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uTm9kZUNsaWNrKGV2ZW50OiBFdmVudCwgbm9kZTogVHJlZU5vZGUpIHtcbiAgICAgICAgdGhpcy5jaGFydC5vbk5vZGVDbGljayhldmVudCwgbm9kZSk7XG4gICAgfVxuXG4gICAgdG9nZ2xlTm9kZShldmVudDogRXZlbnQsIG5vZGU6IFRyZWVOb2RlKSB7XG4gICAgICAgIG5vZGUuZXhwYW5kZWQgPSAhbm9kZS5leHBhbmRlZDtcbiAgICAgICAgaWYgKG5vZGUuZXhwYW5kZWQpIHRoaXMuY2hhcnQub25Ob2RlRXhwYW5kLmVtaXQoeyBvcmlnaW5hbEV2ZW50OiBldmVudCwgbm9kZTogPFRyZWVOb2RlPnRoaXMubm9kZSB9KTtcbiAgICAgICAgZWxzZSB0aGlzLmNoYXJ0Lm9uTm9kZUNvbGxhcHNlLmVtaXQoeyBvcmlnaW5hbEV2ZW50OiBldmVudCwgbm9kZTogPFRyZWVOb2RlPnRoaXMubm9kZSB9KTtcblxuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cblxuICAgIGlzU2VsZWN0ZWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNoYXJ0LmlzU2VsZWN0ZWQodGhpcy5ub2RlIGFzIFRyZWVOb2RlKTtcbiAgICB9XG5cbiAgICBuZ09uRGVzdHJveSgpIHtcbiAgICAgICAgdGhpcy5zdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICB9XG59XG4vKipcbiAqIE9yZ2FuaXphdGlvbkNoYXJ0IHZpc3VhbGl6ZXMgaGllcmFyY2hpY2FsIG9yZ2FuaXphdGlvbiBkYXRhLlxuICogQGdyb3VwIENvbXBvbmVudHNcbiAqL1xuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICdwLW9yZ2FuaXphdGlvbkNoYXJ0JyxcbiAgICB0ZW1wbGF0ZTogYFxuICAgICAgICA8ZGl2IFtuZ1N0eWxlXT1cInN0eWxlXCIgW2NsYXNzXT1cInN0eWxlQ2xhc3NcIiBbbmdDbGFzc109XCJ7ICdwLW9yZ2FuaXphdGlvbmNoYXJ0IHAtY29tcG9uZW50JzogdHJ1ZSwgJ3Atb3JnYW5pemF0aW9uY2hhcnQtcHJlc2VydmVzcGFjZSc6IHByZXNlcnZlU3BhY2UgfVwiIFthdHRyLmRhdGEtcGMtc2VjdGlvbl09XCIncm9vdCdcIj5cbiAgICAgICAgICAgIDx0YWJsZSBjbGFzcz1cInAtb3JnYW5pemF0aW9uY2hhcnQtdGFibGVcIiBbY29sbGFwc2libGVdPVwiY29sbGFwc2libGVcIiBwT3JnYW5pemF0aW9uQ2hhcnROb2RlIFtub2RlXT1cInJvb3RcIiAqbmdJZj1cInJvb3RcIj48L3RhYmxlPlxuICAgICAgICA8L2Rpdj5cbiAgICBgLFxuICAgIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuRGVmYXVsdCxcbiAgICBob3N0OiB7XG4gICAgICAgIGNsYXNzOiAncC1lbGVtZW50J1xuICAgIH1cbn0pXG5leHBvcnQgY2xhc3MgT3JnYW5pemF0aW9uQ2hhcnQgaW1wbGVtZW50cyBBZnRlckNvbnRlbnRJbml0IHtcbiAgICAvKipcbiAgICAgKiBBbiBhcnJheSBvZiBuZXN0ZWQgVHJlZU5vZGVzLlxuICAgICAqIEBncm91cCBQcm9wc1xuICAgICAqL1xuICAgIEBJbnB1dCgpIHZhbHVlOiBUcmVlTm9kZVtdIHwgdW5kZWZpbmVkO1xuICAgIC8qKlxuICAgICAqIElubGluZSBzdHlsZSBvZiB0aGUgY29tcG9uZW50LlxuICAgICAqIEBncm91cCBQcm9wc1xuICAgICAqL1xuICAgIEBJbnB1dCgpIHN0eWxlOiB7IFtrbGFzczogc3RyaW5nXTogYW55IH0gfCBudWxsIHwgdW5kZWZpbmVkO1xuICAgIC8qKlxuICAgICAqIFN0eWxlIGNsYXNzIG9mIHRoZSBjb21wb25lbnQuXG4gICAgICogQGdyb3VwIFByb3BzXG4gICAgICovXG4gICAgQElucHV0KCkgc3R5bGVDbGFzczogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgIC8qKlxuICAgICAqIERlZmluZXMgdGhlIHNlbGVjdGlvbiBtb2RlLlxuICAgICAqIEBncm91cCBQcm9wc1xuICAgICAqL1xuICAgIEBJbnB1dCgpIHNlbGVjdGlvbk1vZGU6ICdzaW5nbGUnIHwgJ211bHRpcGxlJyB8IG51bGwgfCB1bmRlZmluZWQ7XG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgbm9kZXMgY2FuIGJlIGV4cGFuZGVkIG9yIHRvZ2dsZWQuXG4gICAgICogQGdyb3VwIFByb3BzXG4gICAgICovXG4gICAgQElucHV0KHsgdHJhbnNmb3JtOiBib29sZWFuQXR0cmlidXRlIH0pIGNvbGxhcHNpYmxlOiBib29sZWFuIHwgdW5kZWZpbmVkO1xuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIHNwYWNlIGFsbG9jYXRlZCBieSBhIG5vZGUgaXMgcHJlc2VydmVkIHdoZW4gaGlkZGVuLlxuICAgICAqIEBncm91cCBQcm9wc1xuICAgICAqL1xuICAgIEBJbnB1dCh7IHRyYW5zZm9ybTogYm9vbGVhbkF0dHJpYnV0ZSB9KSBwcmVzZXJ2ZVNwYWNlOiBib29sZWFuID0gdHJ1ZTtcbiAgICAvKipcbiAgICAgKiBBIHNpbmdsZSB0cmVlbm9kZSBpbnN0YW5jZSBvciBhbiBhcnJheSB0byByZWZlciB0byB0aGUgc2VsZWN0aW9ucy5cbiAgICAgKiBAZ3JvdXAgUHJvcHNcbiAgICAgKi9cbiAgICBASW5wdXQoKSBnZXQgc2VsZWN0aW9uKCk6IGFueSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zZWxlY3Rpb247XG4gICAgfVxuICAgIHNldCBzZWxlY3Rpb24odmFsOiBhbnkpIHtcbiAgICAgICAgdGhpcy5fc2VsZWN0aW9uID0gdmFsO1xuXG4gICAgICAgIGlmICh0aGlzLmluaXRpYWxpemVkKSB0aGlzLnNlbGVjdGlvblNvdXJjZS5uZXh0KG51bGwpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDYWxsYmFjayB0byBpbnZva2Ugb24gc2VsZWN0aW9uIGNoYW5nZS5cbiAgICAgKiBAcGFyYW0geyp9IGFueSAtIHNlbGVjdGVkIHZhbHVlLlxuICAgICAqIEBncm91cCBFbWl0c1xuICAgICAqL1xuICAgIEBPdXRwdXQoKSBzZWxlY3Rpb25DaGFuZ2U6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICAgIC8qKlxuICAgICAqIENhbGxiYWNrIHRvIGludm9rZSB3aGVuIGEgbm9kZSBpcyBzZWxlY3