@swimlane/ngx-charts
Version:
Declarative Charting Framework for Angular
243 lines • 29.6 kB
JavaScript
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
import { min, max, quantile } from 'd3-array';
import { trigger, transition, style, animate } from '@angular/animations';
import { formatLabel, escapeLabel } from '../common/label.helper';
import { StyleTypes } from '../common/tooltip/style.type';
import { PlacementTypes } from '../common/tooltip/position';
import { ScaleType } from '../common/types/scale-type.enum';
import * as i0 from "@angular/core";
import * as i1 from "./box.component";
import * as i2 from "../common/tooltip/tooltip.directive";
export class BoxSeriesComponent {
constructor() {
this.animations = true;
this.tooltipDisabled = false;
this.gradient = false;
this.select = new EventEmitter();
this.activate = new EventEmitter();
this.deactivate = new EventEmitter();
}
ngOnChanges(changes) {
this.update();
}
onClick(data) {
this.select.emit(data);
}
update() {
this.updateTooltipSettings();
const width = this.series && this.series.series.length ? Math.round(this.xScale.bandwidth()) : null;
const seriesName = this.series.name;
// Calculate Quantile and Whiskers for each box serie.
this.counts = this.series.series;
const mappedCounts = this.counts.map(serie => Number(serie.value));
this.whiskers = [min(mappedCounts), max(mappedCounts)];
// We get the group count and must sort it in order to retrieve quantiles.
const groupCounts = this.counts.map(item => item.value).sort((a, b) => Number(a) - Number(b));
this.quartiles = this.getBoxQuantiles(groupCounts);
this.lineCoordinates = this.getLinesCoordinates(seriesName.toString(), this.whiskers, this.quartiles, width);
const value = this.quartiles[1];
const formattedLabel = formatLabel(seriesName);
const box = {
value,
data: this.counts,
label: seriesName,
formattedLabel,
width,
height: 0,
x: 0,
y: 0,
roundEdges: this.roundEdges,
quartiles: this.quartiles,
lineCoordinates: this.lineCoordinates
};
box.height = Math.abs(this.yScale(this.quartiles[0]) - this.yScale(this.quartiles[2]));
box.x = this.xScale(seriesName.toString());
box.y = this.yScale(this.quartiles[2]);
box.ariaLabel = formattedLabel + ' - Median: ' + value.toLocaleString();
if (this.colors.scaleType === ScaleType.Ordinal) {
box.color = this.colors.getColor(seriesName);
}
else {
box.color = this.colors.getColor(this.quartiles[1]);
box.gradientStops = this.colors.getLinearGradientStops(this.quartiles[0], this.quartiles[2]);
}
const tooltipLabel = formattedLabel;
const formattedTooltipLabel = `
<span class="tooltip-label">${escapeLabel(tooltipLabel)}</span>
<span class="tooltip-val">
• Q1: ${this.quartiles[0]} • Q2: ${this.quartiles[1]} • Q3: ${this.quartiles[2]}<br>
• Min: ${this.whiskers[0]} • Max: ${this.whiskers[1]}
</span>`;
box.tooltipText = this.tooltipDisabled ? undefined : formattedTooltipLabel;
this.tooltipTitle = this.tooltipDisabled ? undefined : box.tooltipText;
this.box = box;
}
getBoxQuantiles(inputData) {
return [quantile(inputData, 0.25), quantile(inputData, 0.5), quantile(inputData, 0.75)];
}
getLinesCoordinates(seriesName, whiskers, quartiles, barWidth) {
// The X value is not being centered, so had to sum half the width to align it.
const commonX = this.xScale(seriesName);
const offsetX = commonX + barWidth / 2;
const medianLineWidth = Math.max(barWidth + 4 * this.strokeWidth, 1);
const whiskerLineWidth = Math.max(barWidth / 3, 1);
const whiskerZero = this.yScale(whiskers[0]);
const whiskerOne = this.yScale(whiskers[1]);
const median = this.yScale(quartiles[1]);
const topLine = {
v1: { x: offsetX + whiskerLineWidth / 2, y: whiskerZero },
v2: { x: offsetX - whiskerLineWidth / 2, y: whiskerZero }
};
const medianLine = {
v1: { x: offsetX + medianLineWidth / 2, y: median },
v2: { x: offsetX - medianLineWidth / 2, y: median }
};
const bottomLine = {
v1: { x: offsetX + whiskerLineWidth / 2, y: whiskerOne },
v2: { x: offsetX - whiskerLineWidth / 2, y: whiskerOne }
};
const verticalLine = {
v1: { x: offsetX, y: whiskerZero },
v2: { x: offsetX, y: whiskerOne }
};
return [verticalLine, topLine, medianLine, bottomLine];
}
updateTooltipSettings() {
if (this.tooltipDisabled) {
this.tooltipPlacement = undefined;
this.tooltipType = undefined;
}
else {
if (!this.tooltipPlacement) {
this.tooltipPlacement = PlacementTypes.Top;
}
if (!this.tooltipType) {
this.tooltipType = StyleTypes.tooltip;
}
}
}
}
BoxSeriesComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: BoxSeriesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
BoxSeriesComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.0", type: BoxSeriesComponent, selector: "g[ngx-charts-box-series]", inputs: { dims: "dims", series: "series", xScale: "xScale", yScale: "yScale", colors: "colors", animations: "animations", strokeColor: "strokeColor", strokeWidth: "strokeWidth", tooltipDisabled: "tooltipDisabled", tooltipTemplate: "tooltipTemplate", tooltipPlacement: "tooltipPlacement", tooltipType: "tooltipType", roundEdges: "roundEdges", gradient: "gradient" }, outputs: { select: "select", activate: "activate", deactivate: "deactivate" }, usesOnChanges: true, ngImport: i0, template: `
<svg:g
ngx-charts-box
[]="'active'"
[@.disabled]="!animations"
[width]="box.width"
[height]="box.height"
[x]="box.x"
[y]="box.y"
[roundEdges]="box.roundEdges"
[fill]="box.color"
[gradientStops]="box.gradientStops"
[strokeColor]="strokeColor"
[strokeWidth]="strokeWidth"
[data]="box.data"
[lineCoordinates]="box.lineCoordinates"
[gradient]="gradient"
[ariaLabel]="box.ariaLabel"
(select)="onClick($event)"
(activate)="activate.emit($event)"
(deactivate)="deactivate.emit($event)"
ngx-tooltip
[tooltipDisabled]="tooltipDisabled"
[tooltipPlacement]="tooltipPlacement"
[tooltipType]="tooltipType"
[tooltipTitle]="tooltipTitle"
[tooltipTemplate]="tooltipTemplate"
[tooltipContext]="box.data"
[animations]="animations"
></svg:g>
`, isInline: true, components: [{ type: i1.BoxComponent, selector: "g[ngx-charts-box]", inputs: ["strokeColor", "strokeWidth", "fill", "data", "width", "height", "x", "y", "lineCoordinates", "roundEdges", "gradient", "gradientStops", "offset", "isActive", "animations", "ariaLabel", "noBarWhenZero"], outputs: ["select", "activate", "deactivate"] }], directives: [{ type: i2.TooltipDirective, selector: "[ngx-tooltip]", inputs: ["tooltipCssClass", "tooltipTitle", "tooltipAppendToBody", "tooltipSpacing", "tooltipDisabled", "tooltipShowCaret", "tooltipPlacement", "tooltipAlignment", "tooltipType", "tooltipCloseOnClickOutside", "tooltipCloseOnMouseLeave", "tooltipHideTimeout", "tooltipShowTimeout", "tooltipTemplate", "tooltipShowEvent", "tooltipContext", "tooltipImmediateExit"], outputs: ["show", "hide"] }], animations: [
trigger('animationState', [
transition(':leave', [
style({
opacity: 1
}),
animate(500, style({ opacity: 0 }))
])
])
], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: BoxSeriesComponent, decorators: [{
type: Component,
args: [{
selector: 'g[ngx-charts-box-series]',
template: `
<svg:g
ngx-charts-box
[]="'active'"
[@.disabled]="!animations"
[width]="box.width"
[height]="box.height"
[x]="box.x"
[y]="box.y"
[roundEdges]="box.roundEdges"
[fill]="box.color"
[gradientStops]="box.gradientStops"
[strokeColor]="strokeColor"
[strokeWidth]="strokeWidth"
[data]="box.data"
[lineCoordinates]="box.lineCoordinates"
[gradient]="gradient"
[ariaLabel]="box.ariaLabel"
(select)="onClick($event)"
(activate)="activate.emit($event)"
(deactivate)="deactivate.emit($event)"
ngx-tooltip
[tooltipDisabled]="tooltipDisabled"
[tooltipPlacement]="tooltipPlacement"
[tooltipType]="tooltipType"
[tooltipTitle]="tooltipTitle"
[tooltipTemplate]="tooltipTemplate"
[tooltipContext]="box.data"
[animations]="animations"
></svg:g>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
animations: [
trigger('animationState', [
transition(':leave', [
style({
opacity: 1
}),
animate(500, style({ opacity: 0 }))
])
])
]
}]
}], propDecorators: { dims: [{
type: Input
}], series: [{
type: Input
}], xScale: [{
type: Input
}], yScale: [{
type: Input
}], colors: [{
type: Input
}], animations: [{
type: Input
}], strokeColor: [{
type: Input
}], strokeWidth: [{
type: Input
}], tooltipDisabled: [{
type: Input
}], tooltipTemplate: [{
type: Input
}], tooltipPlacement: [{
type: Input
}], tooltipType: [{
type: Input
}], roundEdges: [{
type: Input
}], gradient: [{
type: Input
}], select: [{
type: Output
}], activate: [{
type: Output
}], deactivate: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYm94LXNlcmllcy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zd2ltbGFuZS9uZ3gtY2hhcnRzL3NyYy9saWIvYm94LWNoYXJ0L2JveC1zZXJpZXMuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCx1QkFBdUIsRUFDdkIsU0FBUyxFQUNULFlBQVksRUFDWixLQUFLLEVBRUwsTUFBTSxFQUdQLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLFFBQVEsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUk5QyxPQUFPLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFFMUUsT0FBTyxFQUFFLFdBQVcsRUFBRSxXQUFXLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNsRSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDMUQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQzVELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQzs7OztBQWdENUQsTUFBTSxPQUFPLGtCQUFrQjtJQTdDL0I7UUFtRFcsZUFBVSxHQUFZLElBQUksQ0FBQztRQUczQixvQkFBZSxHQUFZLEtBQUssQ0FBQztRQUtqQyxhQUFRLEdBQVksS0FBSyxDQUFDO1FBRXpCLFdBQU0sR0FBNEIsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUNyRCxhQUFRLEdBQTRCLElBQUksWUFBWSxFQUFFLENBQUM7UUFDdkQsZUFBVSxHQUE0QixJQUFJLFlBQVksRUFBRSxDQUFDO0tBZ0lwRTtJQXZIQyxXQUFXLENBQUMsT0FBc0I7UUFDaEMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBQ2hCLENBQUM7SUFFRCxPQUFPLENBQUMsSUFBZTtRQUNyQixJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN6QixDQUFDO0lBRUQsTUFBTTtRQUNKLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1FBQzdCLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO1FBQ3BHLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDO1FBRXBDLHNEQUFzRDtRQUN0RCxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDO1FBRWpDLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQ25FLElBQUksQ0FBQyxRQUFRLEdBQUcsQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLEVBQUUsR0FBRyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUM7UUFFdkQsMEVBQTBFO1FBQzFFLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM5RixJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDbkQsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsVUFBVSxDQUFDLFFBQVEsRUFBRSxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUU3RyxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2hDLE1BQU0sY0FBYyxHQUFHLFdBQVcsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUMvQyxNQUFNLEdBQUcsR0FBYztZQUNyQixLQUFLO1lBQ0wsSUFBSSxFQUFFLElBQUksQ0FBQyxNQUFNO1lBQ2pCLEtBQUssRUFBRSxVQUFVO1lBQ2pCLGNBQWM7WUFDZCxLQUFLO1lBQ0wsTUFBTSxFQUFFLENBQUM7WUFDVCxDQUFDLEVBQUUsQ0FBQztZQUNKLENBQUMsRUFBRSxDQUFDO1lBQ0osVUFBVSxFQUFFLElBQUksQ0FBQyxVQUFVO1lBQzNCLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUztZQUN6QixlQUFlLEVBQUUsSUFBSSxDQUFDLGVBQWU7U0FDdEMsQ0FBQztRQUVGLEdBQUcsQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3ZGLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQztRQUMzQyxHQUFHLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3ZDLEdBQUcsQ0FBQyxTQUFTLEdBQUcsY0FBYyxHQUFHLGFBQWEsR0FBRyxLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7UUFFeEUsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsS0FBSyxTQUFTLENBQUMsT0FBTyxFQUFFO1lBQy9DLEdBQUcsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUM7U0FDOUM7YUFBTTtZQUNMLEdBQUcsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3BELEdBQUcsQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxzQkFBc0IsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUM5RjtRQUVELE1BQU0sWUFBWSxHQUFHLGNBQWMsQ0FBQztRQUNwQyxNQUFNLHFCQUFxQixHQUFHO2tDQUNBLFdBQVcsQ0FBQyxZQUFZLENBQUM7O2NBRTdDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLFVBQVUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsVUFBVSxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztlQUN0RSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxXQUFXLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO1lBQzlDLENBQUM7UUFFVCxHQUFHLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMscUJBQXFCLENBQUM7UUFDM0UsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUM7UUFFdkUsSUFBSSxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUM7SUFDakIsQ0FBQztJQUVELGVBQWUsQ0FBQyxTQUErQjtRQUM3QyxPQUFPLENBQUMsUUFBUSxDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsRUFBRSxRQUFRLENBQUMsU0FBUyxFQUFFLEdBQUcsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUMxRixDQUFDO0lBRUQsbUJBQW1CLENBQ2pCLFVBQWtCLEVBQ2xCLFFBQTBCLEVBQzFCLFNBQW1DLEVBQ25DLFFBQWdCO1FBRWhCLCtFQUErRTtRQUMvRSxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3hDLE1BQU0sT0FBTyxHQUFHLE9BQU8sR0FBRyxRQUFRLEdBQUcsQ0FBQyxDQUFDO1FBRXZDLE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsUUFBUSxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3JFLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxRQUFRLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBRW5ELE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDN0MsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM1QyxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRXpDLE1BQU0sT0FBTyxHQUFjO1lBQ3pCLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxPQUFPLEdBQUcsZ0JBQWdCLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxXQUFXLEVBQUU7WUFDekQsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLE9BQU8sR0FBRyxnQkFBZ0IsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLFdBQVcsRUFBRTtTQUMxRCxDQUFDO1FBQ0YsTUFBTSxVQUFVLEdBQWM7WUFDNUIsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLE9BQU8sR0FBRyxlQUFlLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxNQUFNLEVBQUU7WUFDbkQsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLE9BQU8sR0FBRyxlQUFlLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxNQUFNLEVBQUU7U0FDcEQsQ0FBQztRQUNGLE1BQU0sVUFBVSxHQUFjO1lBQzVCLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxPQUFPLEdBQUcsZ0JBQWdCLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxVQUFVLEVBQUU7WUFDeEQsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLE9BQU8sR0FBRyxnQkFBZ0IsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLFVBQVUsRUFBRTtTQUN6RCxDQUFDO1FBQ0YsTUFBTSxZQUFZLEdBQWM7WUFDOUIsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLE9BQU8sRUFBRSxDQUFDLEVBQUUsV0FBVyxFQUFFO1lBQ2xDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLFVBQVUsRUFBRTtTQUNsQyxDQUFDO1FBQ0YsT0FBTyxDQUFDLFlBQVksRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBQ3pELENBQUM7SUFFRCxxQkFBcUI7UUFDbkIsSUFBSSxJQUFJLENBQUMsZUFBZSxFQUFFO1lBQ3hCLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxTQUFTLENBQUM7WUFDbEMsSUFBSSxDQUFDLFdBQVcsR0FBRyxTQUFTLENBQUM7U0FDOUI7YUFBTTtZQUNMLElBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUU7Z0JBQzFCLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxjQUFjLENBQUMsR0FBRyxDQUFDO2FBQzVDO1lBQ0QsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUU7Z0JBQ3JCLElBQUksQ0FBQyxXQUFXLEdBQUcsVUFBVSxDQUFDLE9BQU8sQ0FBQzthQUN2QztTQUNGO0lBQ0gsQ0FBQzs7K0dBakpVLGtCQUFrQjttR0FBbEIsa0JBQWtCLGtoQkEzQ25COzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E4QlQsd3pCQUVXO1FBQ1YsT0FBTyxDQUFDLGdCQUFnQixFQUFFO1lBQ3hCLFVBQVUsQ0FBQyxRQUFRLEVBQUU7Z0JBQ25CLEtBQUssQ0FBQztvQkFDSixPQUFPLEVBQUUsQ0FBQztpQkFDWCxDQUFDO2dCQUNGLE9BQU8sQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLEVBQUUsT0FBTyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7YUFDcEMsQ0FBQztTQUNILENBQUM7S0FDSDsyRkFFVSxrQkFBa0I7a0JBN0M5QixTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSwwQkFBMEI7b0JBQ3BDLFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBOEJUO29CQUNELGVBQWUsRUFBRSx1QkFBdUIsQ0FBQyxNQUFNO29CQUMvQyxVQUFVLEVBQUU7d0JBQ1YsT0FBTyxDQUFDLGdCQUFnQixFQUFFOzRCQUN4QixVQUFVLENBQUMsUUFBUSxFQUFFO2dDQUNuQixLQUFLLENBQUM7b0NBQ0osT0FBTyxFQUFFLENBQUM7aUNBQ1gsQ0FBQztnQ0FDRixPQUFPLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxFQUFFLE9BQU8sRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDOzZCQUNwQyxDQUFDO3lCQUNILENBQUM7cUJBQ0g7aUJBQ0Y7OEJBRVUsSUFBSTtzQkFBWixLQUFLO2dCQUNHLE1BQU07c0JBQWQsS0FBSztnQkFDRyxNQUFNO3NCQUFkLEtBQUs7Z0JBQ0csTUFBTTtzQkFBZCxLQUFLO2dCQUNHLE1BQU07c0JBQWQsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0csV0FBVztzQkFBbkIsS0FBSztnQkFDRyxlQUFlO3NCQUF2QixLQUFLO2dCQUNHLGVBQWU7c0JBQXZCLEtBQUs7Z0JBQ0csZ0JBQWdCO3NCQUF4QixLQUFLO2dCQUNHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0csVUFBVTtzQkFBbEIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUVJLE1BQU07c0JBQWYsTUFBTTtnQkFDRyxRQUFRO3NCQUFqQixNQUFNO2dCQUNHLFVBQVU7c0JBQW5CLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ29tcG9uZW50LFxuICBFdmVudEVtaXR0ZXIsXG4gIElucHV0LFxuICBPbkNoYW5nZXMsXG4gIE91dHB1dCxcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgVGVtcGxhdGVSZWZcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBtaW4sIG1heCwgcXVhbnRpbGUgfSBmcm9tICdkMy1hcnJheSc7XG5pbXBvcnQgeyBTY2FsZUxpbmVhciwgU2NhbGVCYW5kIH0gZnJvbSAnZDMtc2NhbGUnO1xuaW1wb3J0IHsgSUJveE1vZGVsLCBCb3hDaGFydFNlcmllcywgRGF0YUl0ZW0gfSBmcm9tICcuLi9tb2RlbHMvY2hhcnQtZGF0YS5tb2RlbCc7XG5pbXBvcnQgeyBJVmVjdG9yMkQgfSBmcm9tICcuLi9tb2RlbHMvY29vcmRpbmF0ZXMubW9kZWwnO1xuaW1wb3J0IHsgdHJpZ2dlciwgdHJhbnNpdGlvbiwgc3R5bGUsIGFuaW1hdGUgfSBmcm9tICdAYW5ndWxhci9hbmltYXRpb25zJztcbmltcG9ydCB7IENvbG9ySGVscGVyIH0gZnJvbSAnLi4vY29tbW9uL2NvbG9yLmhlbHBlcic7XG5pbXBvcnQgeyBmb3JtYXRMYWJlbCwgZXNjYXBlTGFiZWwgfSBmcm9tICcuLi9jb21tb24vbGFiZWwuaGVscGVyJztcbmltcG9ydCB7IFN0eWxlVHlwZXMgfSBmcm9tICcuLi9jb21tb24vdG9vbHRpcC9zdHlsZS50eXBlJztcbmltcG9ydCB7IFBsYWNlbWVudFR5cGVzIH0gZnJvbSAnLi4vY29tbW9uL3Rvb2x0aXAvcG9zaXRpb24nO1xuaW1wb3J0IHsgU2NhbGVUeXBlIH0gZnJvbSAnLi4vY29tbW9uL3R5cGVzL3NjYWxlLXR5cGUuZW51bSc7XG5pbXBvcnQgeyBWaWV3RGltZW5zaW9ucyB9IGZyb20gJy4uL2NvbW1vbi90eXBlcy92aWV3LWRpbWVuc2lvbi5pbnRlcmZhY2UnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdnW25neC1jaGFydHMtYm94LXNlcmllc10nLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxzdmc6Z1xuICAgICAgbmd4LWNoYXJ0cy1ib3hcbiAgICAgIFtAYW5pbWF0aW9uU3RhdGVdPVwiJ2FjdGl2ZSdcIlxuICAgICAgW0AuZGlzYWJsZWRdPVwiIWFuaW1hdGlvbnNcIlxuICAgICAgW3dpZHRoXT1cImJveC53aWR0aFwiXG4gICAgICBbaGVpZ2h0XT1cImJveC5oZWlnaHRcIlxuICAgICAgW3hdPVwiYm94LnhcIlxuICAgICAgW3ldPVwiYm94LnlcIlxuICAgICAgW3JvdW5kRWRnZXNdPVwiYm94LnJvdW5kRWRnZXNcIlxuICAgICAgW2ZpbGxdPVwiYm94LmNvbG9yXCJcbiAgICAgIFtncmFkaWVudFN0b3BzXT1cImJveC5ncmFkaWVudFN0b3BzXCJcbiAgICAgIFtzdHJva2VDb2xvcl09XCJzdHJva2VDb2xvclwiXG4gICAgICBbc3Ryb2tlV2lkdGhdPVwic3Ryb2tlV2lkdGhcIlxuICAgICAgW2RhdGFdPVwiYm94LmRhdGFcIlxuICAgICAgW2xpbmVDb29yZGluYXRlc109XCJib3gubGluZUNvb3JkaW5hdGVzXCJcbiAgICAgIFtncmFkaWVudF09XCJncmFkaWVudFwiXG4gICAgICBbYXJpYUxhYmVsXT1cImJveC5hcmlhTGFiZWxcIlxuICAgICAgKHNlbGVjdCk9XCJvbkNsaWNrKCRldmVudClcIlxuICAgICAgKGFjdGl2YXRlKT1cImFjdGl2YXRlLmVtaXQoJGV2ZW50KVwiXG4gICAgICAoZGVhY3RpdmF0ZSk9XCJkZWFjdGl2YXRlLmVtaXQoJGV2ZW50KVwiXG4gICAgICBuZ3gtdG9vbHRpcFxuICAgICAgW3Rvb2x0aXBEaXNhYmxlZF09XCJ0b29sdGlwRGlzYWJsZWRcIlxuICAgICAgW3Rvb2x0aXBQbGFjZW1lbnRdPVwidG9vbHRpcFBsYWNlbWVudFwiXG4gICAgICBbdG9vbHRpcFR5cGVdPVwidG9vbHRpcFR5cGVcIlxuICAgICAgW3Rvb2x0aXBUaXRsZV09XCJ0b29sdGlwVGl0bGVcIlxuICAgICAgW3Rvb2x0aXBUZW1wbGF0ZV09XCJ0b29sdGlwVGVtcGxhdGVcIlxuICAgICAgW3Rvb2x0aXBDb250ZXh0XT1cImJveC5kYXRhXCJcbiAgICAgIFthbmltYXRpb25zXT1cImFuaW1hdGlvbnNcIlxuICAgID48L3N2ZzpnPlxuICBgLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgYW5pbWF0aW9uczogW1xuICAgIHRyaWdnZXIoJ2FuaW1hdGlvblN0YXRlJywgW1xuICAgICAgdHJhbnNpdGlvbignOmxlYXZlJywgW1xuICAgICAgICBzdHlsZSh7XG4gICAgICAgICAgb3BhY2l0eTogMVxuICAgICAgICB9KSxcbiAgICAgICAgYW5pbWF0ZSg1MDAsIHN0eWxlKHsgb3BhY2l0eTogMCB9KSlcbiAgICAgIF0pXG4gICAgXSlcbiAgXVxufSlcbmV4cG9ydCBjbGFzcyBCb3hTZXJpZXNDb21wb25lbnQgaW1wbGVtZW50cyBPbkNoYW5nZXMge1xuICBASW5wdXQoKSBkaW1zOiBWaWV3RGltZW5zaW9ucztcbiAgQElucHV0KCkgc2VyaWVzOiBCb3hDaGFydFNlcmllcztcbiAgQElucHV0KCkgeFNjYWxlOiBTY2FsZUJhbmQ8c3RyaW5nPjtcbiAgQElucHV0KCkgeVNjYWxlOiBTY2FsZUxpbmVhcjxudW1iZXIsIG51bWJlcj47XG4gIEBJbnB1dCgpIGNvbG9yczogQ29sb3JIZWxwZXI7XG4gIEBJbnB1dCgpIGFuaW1hdGlvbnM6IGJvb2xlYW4gPSB0cnVlO1xuICBASW5wdXQoKSBzdHJva2VDb2xvcjogc3RyaW5nO1xuICBASW5wdXQoKSBzdHJva2VXaWR0aDogbnVtYmVyO1xuICBASW5wdXQoKSB0b29sdGlwRGlzYWJsZWQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgdG9vbHRpcFRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+O1xuICBASW5wdXQoKSB0b29sdGlwUGxhY2VtZW50OiBQbGFjZW1lbnRUeXBlcztcbiAgQElucHV0KCkgdG9vbHRpcFR5cGU6IFN0eWxlVHlwZXM7XG4gIEBJbnB1dCgpIHJvdW5kRWRnZXM6IGJvb2xlYW47XG4gIEBJbnB1dCgpIGdyYWRpZW50OiBib29sZWFuID0gZmFsc2U7XG5cbiAgQE91dHB1dCgpIHNlbGVjdDogRXZlbnRFbWl0dGVyPElCb3hNb2RlbD4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIEBPdXRwdXQoKSBhY3RpdmF0ZTogRXZlbnRFbWl0dGVyPElCb3hNb2RlbD4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIEBPdXRwdXQoKSBkZWFjdGl2YXRlOiBFdmVudEVtaXR0ZXI8SUJveE1vZGVsPiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuICBib3g6IElCb3hNb2RlbDtcbiAgY291bnRzOiBEYXRhSXRlbVtdO1xuICBxdWFydGlsZXM6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXTtcbiAgd2hpc2tlcnM6IFtudW1iZXIsIG51bWJlcl07XG4gIGxpbmVDb29yZGluYXRlczogW0lWZWN0b3IyRCwgSVZlY3RvcjJELCBJVmVjdG9yMkQsIElWZWN0b3IyRF07XG4gIHRvb2x0aXBUaXRsZTogc3RyaW5nO1xuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICB0aGlzLnVwZGF0ZSgpO1xuICB9XG5cbiAgb25DbGljayhkYXRhOiBJQm94TW9kZWwpOiB2b2lkIHtcbiAgICB0aGlzLnNlbGVjdC5lbWl0KGRhdGEpO1xuICB9XG5cbiAgdXBkYXRlKCk6IHZvaWQge1xuICAgIHRoaXMudXBkYXRlVG9vbHRpcFNldHRpbmdzKCk7XG4gICAgY29uc3Qgd2lkdGggPSB0aGlzLnNlcmllcyAmJiB0aGlzLnNlcmllcy5zZXJpZXMubGVuZ3RoID8gTWF0aC5yb3VuZCh0aGlzLnhTY2FsZS5iYW5kd2lkdGgoKSkgOiBudWxsO1xuICAgIGNvbnN0IHNlcmllc05hbWUgPSB0aGlzLnNlcmllcy5uYW1lO1xuXG4gICAgLy8gQ2FsY3VsYXRlIFF1YW50aWxlIGFuZCBXaGlza2VycyBmb3IgZWFjaCBib3ggc2VyaWUuXG4gICAgdGhpcy5jb3VudHMgPSB0aGlzLnNlcmllcy5zZXJpZXM7XG5cbiAgICBjb25zdCBtYXBwZWRDb3VudHMgPSB0aGlzLmNvdW50cy5tYXAoc2VyaWUgPT4gTnVtYmVyKHNlcmllLnZhbHVlKSk7XG4gICAgdGhpcy53aGlza2VycyA9IFttaW4obWFwcGVkQ291bnRzKSwgbWF4KG1hcHBlZENvdW50cyldO1xuXG4gICAgLy8gV2UgZ2V0IHRoZSBncm91cCBjb3VudCBhbmQgbXVzdCBzb3J0IGl0IGluIG9yZGVyIHRvIHJldHJpZXZlIHF1YW50aWxlcy5cbiAgICBjb25zdCBncm91cENvdW50cyA9IHRoaXMuY291bnRzLm1hcChpdGVtID0+IGl0ZW0udmFsdWUpLnNvcnQoKGEsIGIpID0+IE51bWJlcihhKSAtIE51bWJlcihiKSk7XG4gICAgdGhpcy5xdWFydGlsZXMgPSB0aGlzLmdldEJveFF1YW50aWxlcyhncm91cENvdW50cyk7XG4gICAgdGhpcy5saW5lQ29vcmRpbmF0ZXMgPSB0aGlzLmdldExpbmVzQ29vcmRpbmF0ZXMoc2VyaWVzTmFtZS50b1N0cmluZygpLCB0aGlzLndoaXNrZXJzLCB0aGlzLnF1YXJ0aWxlcywgd2lkdGgpO1xuXG4gICAgY29uc3QgdmFsdWUgPSB0aGlzLnF1YXJ0aWxlc1sxXTtcbiAgICBjb25zdCBmb3JtYXR0ZWRMYWJlbCA9IGZvcm1hdExhYmVsKHNlcmllc05hbWUpO1xuICAgIGNvbnN0IGJveDogSUJveE1vZGVsID0ge1xuICAgICAgdmFsdWUsXG4gICAgICBkYXRhOiB0aGlzLmNvdW50cyxcbiAgICAgIGxhYmVsOiBzZXJpZXNOYW1lLFxuICAgICAgZm9ybWF0dGVkTGFiZWwsXG4gICAgICB3aWR0aCxcbiAgICAgIGhlaWdodDogMCxcbiAgICAgIHg6IDAsXG4gICAgICB5OiAwLFxuICAgICAgcm91bmRFZGdlczogdGhpcy5yb3VuZEVkZ2VzLFxuICAgICAgcXVhcnRpbGVzOiB0aGlzLnF1YXJ0aWxlcyxcbiAgICAgIGxpbmVDb29yZGluYXRlczogdGhpcy5saW5lQ29vcmRpbmF0ZXNcbiAgICB9O1xuXG4gICAgYm94LmhlaWdodCA9IE1hdGguYWJzKHRoaXMueVNjYWxlKHRoaXMucXVhcnRpbGVzWzBdKSAtIHRoaXMueVNjYWxlKHRoaXMucXVhcnRpbGVzWzJdKSk7XG4gICAgYm94LnggPSB0aGlzLnhTY2FsZShzZXJpZXNOYW1lLnRvU3RyaW5nKCkpO1xuICAgIGJveC55ID0gdGhpcy55U2NhbGUodGhpcy5xdWFydGlsZXNbMl0pO1xuICAgIGJveC5hcmlhTGFiZWwgPSBmb3JtYXR0ZWRMYWJlbCArICcgLSBNZWRpYW46ICcgKyB2YWx1ZS50b0xvY2FsZVN0cmluZygpO1xuXG4gICAgaWYgKHRoaXMuY29sb3JzLnNjYWxlVHlwZSA9PT0gU2NhbGVUeXBlLk9yZGluYWwpIHtcbiAgICAgIGJveC5jb2xvciA9IHRoaXMuY29sb3JzLmdldENvbG9yKHNlcmllc05hbWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBib3guY29sb3IgPSB0aGlzLmNvbG9ycy5nZXRDb2xvcih0aGlzLnF1YXJ0aWxlc1sxXSk7XG4gICAgICBib3guZ3JhZGllbnRTdG9wcyA9IHRoaXMuY29sb3JzLmdldExpbmVhckdyYWRpZW50U3RvcHModGhpcy5xdWFydGlsZXNbMF0sIHRoaXMucXVhcnRpbGVzWzJdKTtcbiAgICB9XG5cbiAgICBjb25zdCB0b29sdGlwTGFiZWwgPSBmb3JtYXR0ZWRMYWJlbDtcbiAgICBjb25zdCBmb3JtYXR0ZWRUb29sdGlwTGFiZWwgPSBgXG4gICAgPHNwYW4gY2xhc3M9XCJ0b29sdGlwLWxhYmVsXCI+JHtlc2NhcGVMYWJlbCh0b29sdGlwTGFiZWwpfTwvc3Bhbj5cbiAgICA8c3BhbiBjbGFzcz1cInRvb2x0aXAtdmFsXCI+XG4gICAgICDigKIgUTE6ICR7dGhpcy5xdWFydGlsZXNbMF19IOKAoiBRMjogJHt0aGlzLnF1YXJ0aWxlc1sxXX0g4oCiIFEzOiAke3RoaXMucXVhcnRpbGVzWzJdfTxicj5cbiAgICAgIOKAoiBNaW46ICR7dGhpcy53aGlza2Vyc1swXX0g4oCiIE1heDogJHt0aGlzLndoaXNrZXJzWzFdfVxuICAgIDwvc3Bhbj5gO1xuXG4gICAgYm94LnRvb2x0aXBUZXh0ID0gdGhpcy50b29sdGlwRGlzYWJsZWQgPyB1bmRlZmluZWQgOiBmb3JtYXR0ZWRUb29sdGlwTGFiZWw7XG4gICAgdGhpcy50b29sdGlwVGl0bGUgPSB0aGlzLnRvb2x0aXBEaXNhYmxlZCA/IHVuZGVmaW5lZCA6IGJveC50b29sdGlwVGV4dDtcblxuICAgIHRoaXMuYm94ID0gYm94O1xuICB9XG5cbiAgZ2V0Qm94UXVhbnRpbGVzKGlucHV0RGF0YTogQXJyYXk8bnVtYmVyIHwgRGF0ZT4pOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0ge1xuICAgIHJldHVybiBbcXVhbnRpbGUoaW5wdXREYXRhLCAwLjI1KSwgcXVhbnRpbGUoaW5wdXREYXRhLCAwLjUpLCBxdWFudGlsZShpbnB1dERhdGEsIDAuNzUpXTtcbiAgfVxuXG4gIGdldExpbmVzQ29vcmRpbmF0ZXMoXG4gICAgc2VyaWVzTmFtZTogc3RyaW5nLFxuICAgIHdoaXNrZXJzOiBbbnVtYmVyLCBudW1iZXJdLFxuICAgIHF1YXJ0aWxlczogW251bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICAgIGJhcldpZHRoOiBudW1iZXJcbiAgKTogW0lWZWN0b3IyRCwgSVZlY3RvcjJELCBJVmVjdG9yMkQsIElWZWN0b3IyRF0ge1xuICAgIC8vIFRoZSBYIHZhbHVlIGlzIG5vdCBiZWluZyBjZW50ZXJlZCwgc28gaGFkIHRvIHN1bSBoYWxmIHRoZSB3aWR0aCB0byBhbGlnbiBpdC5cbiAgICBjb25zdCBjb21tb25YID0gdGhpcy54U2NhbGUoc2VyaWVzTmFtZSk7XG4gICAgY29uc3Qgb2Zmc2V0WCA9IGNvbW1vblggKyBiYXJXaWR0aCAvIDI7XG5cbiAgICBjb25zdCBtZWRpYW5MaW5lV2lkdGggPSBNYXRoLm1heChiYXJXaWR0aCArIDQgKiB0aGlzLnN0cm9rZVdpZHRoLCAxKTtcbiAgICBjb25zdCB3aGlza2VyTGluZVdpZHRoID0gTWF0aC5tYXgoYmFyV2lkdGggLyAzLCAxKTtcblxuICAgIGNvbnN0IHdoaXNrZXJaZXJvID0gdGhpcy55U2NhbGUod2hpc2tlcnNbMF0pO1xuICAgIGNvbnN0IHdoaXNrZXJPbmUgPSB0aGlzLnlTY2FsZSh3aGlza2Vyc1sxXSk7XG4gICAgY29uc3QgbWVkaWFuID0gdGhpcy55U2NhbGUocXVhcnRpbGVzWzFdKTtcblxuICAgIGNvbnN0IHRvcExpbmU6IElWZWN0b3IyRCA9IHtcbiAgICAgIHYxOiB7IHg6IG9mZnNldFggKyB3aGlza2VyTGluZVdpZHRoIC8gMiwgeTogd2hpc2tlclplcm8gfSxcbiAgICAgIHYyOiB7IHg6IG9mZnNldFggLSB3aGlza2VyTGluZVdpZHRoIC8gMiwgeTogd2hpc2tlclplcm8gfVxuICAgIH07XG4gICAgY29uc3QgbWVkaWFuTGluZTogSVZlY3RvcjJEID0ge1xuICAgICAgdjE6IHsgeDogb2Zmc2V0WCArIG1lZGlhbkxpbmVXaWR0aCAvIDIsIHk6IG1lZGlhbiB9LFxuICAgICAgdjI6IHsgeDogb2Zmc2V0WCAtIG1lZGlhbkxpbmVXaWR0aCAvIDIsIHk6IG1lZGlhbiB9XG4gICAgfTtcbiAgICBjb25zdCBib3R0b21MaW5lOiBJVmVjdG9yMkQgPSB7XG4gICAgICB2MTogeyB4OiBvZmZzZXRYICsgd2hpc2tlckxpbmVXaWR0aCAvIDIsIHk6IHdoaXNrZXJPbmUgfSxcbiAgICAgIHYyOiB7IHg6IG9mZnNldFggLSB3aGlza2VyTGluZVdpZHRoIC8gMiwgeTogd2hpc2tlck9uZSB9XG4gICAgfTtcbiAgICBjb25zdCB2ZXJ0aWNhbExpbmU6IElWZWN0b3IyRCA9IHtcbiAgICAgIHYxOiB7IHg6IG9mZnNldFgsIHk6IHdoaXNrZXJaZXJvIH0sXG4gICAgICB2MjogeyB4OiBvZmZzZXRYLCB5OiB3aGlza2VyT25lIH1cbiAgICB9O1xuICAgIHJldHVybiBbdmVydGljYWxMaW5lLCB0b3BMaW5lLCBtZWRpYW5MaW5lLCBib3R0b21MaW5lXTtcbiAgfVxuXG4gIHVwZGF0ZVRvb2x0aXBTZXR0aW5ncygpIHtcbiAgICBpZiAodGhpcy50b29sdGlwRGlzYWJsZWQpIHtcbiAgICAgIHRoaXMudG9vbHRpcFBsYWNlbWVudCA9IHVuZGVmaW5lZDtcbiAgICAgIHRoaXMudG9vbHRpcFR5cGUgPSB1bmRlZmluZWQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICghdGhpcy50b29sdGlwUGxhY2VtZW50KSB7XG4gICAgICAgIHRoaXMudG9vbHRpcFBsYWNlbWVudCA9IFBsYWNlbWVudFR5cGVzLlRvcDtcbiAgICAgIH1cbiAgICAgIGlmICghdGhpcy50b29sdGlwVHlwZSkge1xuICAgICAgICB0aGlzLnRvb2x0aXBUeXBlID0gU3R5bGVUeXBlcy50b29sdGlwO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuIl19