ng-d3-graphs
Version:
<img src="./assets/ng-d3.png" alt="drawing" width="250" height="250"/>
189 lines • 26.4 kB
JavaScript
import * as tslib_1 from "tslib";
import { ChangeDetectionStrategy, Component, ElementRef, HostListener, Input, OnInit, ViewEncapsulation, } from '@angular/core';
import * as d3 from 'd3';
import { Subject } from 'rxjs';
import { debounceTime } from 'rxjs/operators';
import { axisConfig } from '../shared/config/axis.config';
import { D3Service } from '../shared/services/d3.service';
let BarComponent = class BarComponent {
constructor(container, d3Service) {
this.container = container;
this.d3Service = d3Service;
this.data = [];
this.labels = [];
this.options = {};
this.graph = {
xAxis: [],
yAxis: [],
xAxisPath: '',
yAxisPath: '',
rectanglesData: [],
};
this.labelsAndData = [];
this.parseTime = d3.timeParse('%d-%b-%y');
this._options = {
width: 879,
height: 804,
margin: { top: 50, right: 50, bottom: 50, left: 50 },
gridTicks: 0,
};
this.viewBox = {};
this.onResize$ = new Subject();
}
onResize() {
this.onResize$.next();
}
ngOnInit() {
this.options = Object.assign({}, this._options, this.options);
this.viewBox = {
minX: -this.options.margin.left,
minY: -10,
width: this.options.width + this.options.margin.left +
this.options.margin.right,
height: this.options.height + this.options.margin.top,
};
this.labelsAndData = this.combineLabelsDataToOne();
this.onResizeEvent();
this.render();
}
render() {
const currentWidth = parseInt(d3.select(this.container.nativeElement).select('div').style('width'), 10);
const currentHeight = parseInt(d3.select(this.container.nativeElement).select('div').style('height'), 10);
const width = this.options.width - this.options.margin.left -
this.options.margin.right;
const height = this.options.height - this.options.margin.top -
this.options.margin.bottom;
this.viewBox = {
minX: -this.options.margin.left,
minY: -10,
width: this.options.width,
height: this.options.height - this.options.margin.top,
};
const svg = d3.select(this.container.nativeElement)
.select('div')
.append('svg')
.attr('width', currentWidth)
.attr('height', currentHeight)
.attr('viewBox', `${this.viewBox.minX} ${this.viewBox.minY} ${this.viewBox.width} ${this.viewBox.height}`)
.classed('svg-content', true)
.append('g');
const x = d3.scaleBand().rangeRound([0, width]).padding(0.1).domain(this.labels);
const y = d3.scaleLinear().rangeRound([height, 0]).domain([
0, Math.max(...this.data.map((d) => Number(d)))
]);
const xAxis = (g) => g.call(d3.axisBottom(x))
.attr('transform', 'translate(0,' + height + ')');
const yAxis = (g) => g.call(d3.axisLeft(y));
// add the X gridlines
svg.append('g')
.attr('class', 'grid')
.call(this.make_x_gridlines(x).tickSize(height)
// .tickFormat('')
);
// add the Y gridlines
svg.append('g')
.attr('class', 'grid')
.call(this.make_y_gridlines(y).tickSize(-width)
// .tickFormat('')
);
svg.selectAll('.bar')
.data(this.labelsAndData)
.enter()
.append('rect')
.attr('class', 'bar')
.attr('x', (d) => {
return x(d.x);
})
.attr('y', (d) => {
return y(Number(d.y));
})
.attr('width', x.bandwidth())
.attr('height', (d) => {
return height - y(Number(d.y));
});
const _xAxis = svg.append('g').call(xAxis);
// text label for the x axis
this.addLabelAxisX(svg, width, height);
const _yAxis = svg.append('g').call(yAxis);
// text label for the y axis
this.addLabelAxisY(svg, height);
this.removeAxisTicks(_xAxis);
this.removeAxisTicks(_yAxis);
this.changeAxisColor(_xAxis, axisConfig);
this.changeAxisColor(_yAxis, axisConfig);
}
changeAxisColor(axis, config) {
this.d3Service.changeAxisColor(axis, config);
}
removeAxisTicks(axis) {
this.d3Service.removeAxisTicks(axis);
}
addLabelAxisY(svg, height) {
svg.append('text')
.attr('transform', 'rotate(0)')
.attr('y', 0 - this.options.margin.top / 2)
.attr('x', 0)
.attr('dy', '1em')
.style('text-anchor', 'start')
.text(this.options.yAxisLabel);
}
addLabelAxisX(svg, width, height) {
svg.append('text')
.attr('transform', 'translate(' + width / 2 + ' ,' +
(height + this.options.margin.top - 15) + ')')
.style('text-anchor', 'middle')
.text(this.options.xAxisLabel);
}
combineLabelsDataToOne() {
const result = [];
const N = this.data.length;
for (let index = 0; index < N; index++) {
result.push({ x: this.labels[index], y: this.data[index] });
}
return result;
}
// gridlines in x axis function
make_x_gridlines(x) {
return d3.axisBottom(x).ticks(this.options.gridTicks);
}
// gridlines in y axis function
make_y_gridlines(y) {
return d3.axisLeft(y).ticks(this.options.gridTicks);
}
onResizeEvent() {
this.onResize$.pipe(debounceTime(200)).subscribe(() => {
const svgExist = d3.select(this.container.nativeElement).select('svg');
if (svgExist) {
svgExist.remove();
}
this.render();
});
}
};
BarComponent.ctorParameters = () => [
{ type: ElementRef },
{ type: D3Service }
];
tslib_1.__decorate([
Input()
], BarComponent.prototype, "data", void 0);
tslib_1.__decorate([
Input()
], BarComponent.prototype, "labels", void 0);
tslib_1.__decorate([
Input()
], BarComponent.prototype, "options", void 0);
tslib_1.__decorate([
HostListener('window:resize')
], BarComponent.prototype, "onResize", null);
BarComponent = tslib_1.__decorate([
Component({
selector: 'ng-bar',
template: "\n<div class=\"svg-container\"></div>\n",
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
styles: [".svg-container{display:inline-block;position:relative;width:100%;height:100%;padding-bottom:100%;vertical-align:top;overflow:hidden}.svg-content{display:inline-block;position:absolute;top:0;left:0}.grid line{stroke:#d3d3d3;stroke-opacity:.4;shape-rendering:crispEdges}.grid path{stroke-width:0}.grid text{display:none}.bar{fill:#4682b4}.bar:hover{fill:brown}"]
})
], BarComponent);
export { BarComponent };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25nLWQzLWdyYXBocy8iLCJzb3VyY2VzIjpbImJhci9iYXIuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUMsdUJBQXVCLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxpQkFBaUIsR0FBRSxNQUFNLGVBQWUsQ0FBQztBQUM5SCxPQUFPLEtBQUssRUFBRSxNQUFNLElBQUksQ0FBQztBQUN6QixPQUFPLEVBQUMsT0FBTyxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBQzdCLE9BQU8sRUFBQyxZQUFZLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUU1QyxPQUFPLEVBQUMsVUFBVSxFQUFDLE1BQU0sOEJBQThCLENBQUM7QUFJeEQsT0FBTyxFQUFDLFNBQVMsRUFBQyxNQUFNLCtCQUErQixDQUFDO0FBNkN4RCxJQUFhLFlBQVksR0FBekIsTUFBYSxZQUFZO0lBNkJ2QixZQUNZLFNBQXFCLEVBQ3JCLFNBQW9CO1FBRHBCLGNBQVMsR0FBVCxTQUFTLENBQVk7UUFDckIsY0FBUyxHQUFULFNBQVMsQ0FBVztRQTlCdkIsU0FBSSxHQUFjLEVBQUUsQ0FBQztRQUNyQixXQUFNLEdBQVUsRUFBRSxDQUFDO1FBQ25CLFlBQU8sR0FBZ0IsRUFBZ0IsQ0FBQztRQUNqRCxVQUFLLEdBQVU7WUFDYixLQUFLLEVBQUUsRUFBRTtZQUNULEtBQUssRUFBRSxFQUFFO1lBQ1QsU0FBUyxFQUFFLEVBQUU7WUFDYixTQUFTLEVBQUUsRUFBRTtZQUNiLGNBQWMsRUFBRSxFQUFFO1NBQ25CLENBQUM7UUFDRixrQkFBYSxHQUFvQixFQUFFLENBQUM7UUFDcEMsY0FBUyxHQUFHLEVBQUUsQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLENBQUM7UUFFN0IsYUFBUSxHQUFlO1lBQzdCLEtBQUssRUFBRSxHQUFHO1lBQ1YsTUFBTSxFQUFFLEdBQUc7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LElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDeEQsQ0FBQztJQUVELCtCQUErQjtJQUN2QixnQkFBZ0IsQ0FBQyxDQUFDO1FBQ3hCLE9BQU8sRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUN0RCxDQUFDO0lBRUQsYUFBYTtRQUNYLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUU7WUFDcEQsTUFBTSxRQUFRLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUN2RSxJQUFJLFFBQVEsRUFBRTtnQkFDWixRQUFRLENBQUMsTUFBTSxFQUFFLENBQUM7YUFDbkI7WUFDRCxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDaEIsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0NBQ0YsQ0FBQTs7WUFuTHdCLFVBQVU7WUFDVixTQUFTOztBQTlCdkI7SUFBUixLQUFLLEVBQUU7MENBQXNCO0FBQ3JCO0lBQVIsS0FBSyxFQUFFOzRDQUFvQjtBQUNuQjtJQUFSLEtBQUssRUFBRTs2Q0FBeUM7QUFzQmpEO0lBREMsWUFBWSxDQUFDLGVBQWUsQ0FBQzs0Q0FHN0I7QUEzQlUsWUFBWTtJQVB4QixTQUFTLENBQUM7UUFDVCxRQUFRLEVBQUUsUUFBUTtRQUNsQixtREFBbUM7UUFFbkMsYUFBYSxFQUFFLGlCQUFpQixDQUFDLElBQUk7UUFDckMsZUFBZSxFQUFFLHVCQUF1QixDQUFDLE1BQU07O0tBQ2hELENBQUM7R0FDVyxZQUFZLENBaU54QjtTQWpOWSxZQUFZIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ29tcG9uZW50LCBFbGVtZW50UmVmLCBIb3N0TGlzdGVuZXIsIElucHV0LCBPbkluaXQsIFZpZXdFbmNhcHN1bGF0aW9uLH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgKiBhcyBkMyBmcm9tICdkMyc7XG5pbXBvcnQge1N1YmplY3R9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtkZWJvdW5jZVRpbWV9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHtheGlzQ29uZmlnfSBmcm9tICcuLi9zaGFyZWQvY29uZmlnL2F4aXMuY29uZmlnJztcbmltcG9ydCB7QXhpc30gZnJvbSAnLi4vc2hhcmVkL21vZGVscy9heGlzLmludGVyZmFjZSc7XG5pbXBvcnQge0dyYXBoT3B0aW9uc30gZnJvbSAnLi4vc2hhcmVkL21vZGVscy9ncmFwaC1vcHRpb25zLmludGVyZmFjZSc7XG5pbXBvcnQge1ZpZXdCb3h9IGZyb20gJy4uL3NoYXJlZC9tb2RlbHMvdmlld2JveC5pbnRlcmZhY2UnO1xuaW1wb3J0IHtEM1NlcnZpY2V9IGZyb20gJy4uL3NoYXJlZC9zZXJ2aWNlcy9kMy5zZXJ2aWNlJztcblxuaW1wb3J0IHtCYXJTZXJ2aWNlfSBmcm9tICcuL2Jhci5zZXJ2aWNlJztcblxuZXhwb3J0IGludGVyZmFjZSBCYXIge1xuICBsYWJlbHM6IGFueVtdO1xuICBkYXRhOiBhbnlbXTtcbiAgb3B0aW9ucz86IGFueTtcbn1cblxuaW50ZXJmYWNlIEJhckRhdGEge1xuICBsYWJlbDogc3RyaW5nO1xuICB2YWx1ZXM6IGFueVtdO1xufVxuZXhwb3J0IGludGVyZmFjZSBCYXJEMyB7XG4gIHhBeGlzOiBBeGlzW107XG4gIHlBeGlzOiBBeGlzW107XG4gIHhBeGlzUGF0aDogc3RyaW5nO1xuICB5QXhpc1BhdGg6IHN0cmluZztcbiAgcmVjdGFuZ2xlc0RhdGE6IFJlY3RhbmdsZVtdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJlY3RhbmdsZSB7XG4gIHg6IG51bWJlcjtcbiAgeTogbnVtYmVyO1xuICBoZWlnaHQ6IG51bWJlcjtcbiAgd2lkdGg6IG51bWJlcjtcbn1cblxuaW50ZXJmYWNlIExhYmVsc0FuZERhdGEge1xuICB4OiBhbnk7XG4gIHk6IGFueTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBCYXJPcHRpb25zIGV4dGVuZHMgR3JhcGhPcHRpb25zIHtcbiAgZ3JpZFRpY2tzPzogbnVtYmVyO1xufVxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICduZy1iYXInLFxuICB0ZW1wbGF0ZVVybDogJy4vYmFyLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vYmFyLmNvbXBvbmVudC5zY3NzJ10sXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxufSlcbmV4cG9ydCBjbGFzcyBCYXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICBASW5wdXQoKSBkYXRhOiBCYXJEYXRhW10gPSBbXTtcbiAgQElucHV0KCkgbGFiZWxzOiBhbnlbXSA9IFtdO1xuICBASW5wdXQoKSBvcHRpb25zPzogQmFyT3B0aW9ucyA9IHt9IGFzIEJhck9wdGlvbnM7XG4gIGdyYXBoOiBCYXJEMyA9IHtcbiAgICB4QXhpczogW10sXG4gICAgeUF4aXM6IFtdLFxuICAgIHhBeGlzUGF0aDogJycsXG4gICAgeUF4aXNQYXRoOiAnJyxcbiAgICByZWN0YW5nbGVzRGF0YTogW10sXG4gIH07XG4gIGxhYmVsc0FuZERhdGE6IExhYmVsc0FuZERhdGFbXSA9IFtdO1xuICBwYXJzZVRpbWUgPSBkMy50aW1lUGFyc2UoJyVkLSViLSV5Jyk7XG5cbiAgcHJpdmF0ZSBfb3B0aW9uczogQmFyT3B0aW9ucyA9IHtcbiAgICB3aWR0aDogODc5LFxuICAgIGhlaWdodDogODA0LFxuICAgIG1hcmdpbjoge3RvcDogNTAsIHJpZ2h0OiA1MCwgYm90dG9tOiA1MCwgbGVmdDogNTB9LFxuICAgIGdyaWRUaWNrczogMCxcbiAgfTtcblxuICB2aWV3Qm94OiBWaWV3Qm94ID0ge30gYXMgVmlld0JveDtcblxuICBvblJlc2l6ZSQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuICBASG9zdExpc3RlbmVyKCd3aW5kb3c6cmVzaXplJylcbiAgb25SZXNpemUoKTogdm9pZCB7XG4gICAgdGhpcy5vblJlc2l6ZSQubmV4dCgpO1xuICB9XG5cbiAgY29uc3RydWN0b3IoXG4gICAgICBwcml2YXRlIGNvbnRhaW5lcjogRWxlbWVudFJlZixcbiAgICAgIHByaXZhdGUgZDNTZXJ2aWNlOiBEM1NlcnZpY2UsXG4gICkge31cblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLm9wdGlvbnMgPSB7Li4udGhpcy5fb3B0aW9ucywgLi4udGhpcy5vcHRpb25zfTtcbiAgICB0aGlzLnZpZXdCb3ggPSB7XG4gICAgICBtaW5YOiAtdGhpcy5vcHRpb25zLm1hcmdpbi5sZWZ0LFxuICAgICAgbWluWTogLTEwLFxuICAgICAgd2lkdGg6IHRoaXMub3B0aW9ucy53aWR0aCArIHRoaXMub3B0aW9ucy5tYXJnaW4ubGVmdCArXG4gICAgICAgICAgdGhpcy5vcHRpb25zLm1hcmdpbi5yaWdodCxcbiAgICAgIGhlaWdodDogdGhpcy5vcHRpb25zLmhlaWdodCArIHRoaXMub3B0aW9ucy5tYXJnaW4udG9wLFxuICAgIH07XG4gICAgdGhpcy5sYWJlbHNBbmREYXRhID0gdGhpcy5jb21iaW5lTGFiZWxzRGF0YVRvT25lKCk7XG5cbiAgICB0aGlzLm9uUmVzaXplRXZlbnQoKTtcblxuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuICBwcml2YXRlIHJlbmRlcigpIHtcbiAgICBjb25zdCBjdXJyZW50V2lkdGggPSBwYXJzZUludChcbiAgICAgICAgZDMuc2VsZWN0KHRoaXMuY29udGFpbmVyLm5hdGl2ZUVsZW1lbnQpLnNlbGVjdCgnZGl2Jykuc3R5bGUoJ3dpZHRoJyksXG4gICAgICAgIDEwKTtcbiAgICBjb25zdCBjdXJyZW50SGVpZ2h0ID0gcGFyc2VJbnQoXG4gICAgICAgIGQzLnNlbGVjdCh0aGlzLmNvbnRhaW5lci5uYXRpdmVFbGVtZW50KS5zZWxlY3QoJ2RpdicpLnN0eWxlKCdoZWlnaHQnKSxcbiAgICAgICAgMTApO1xuXG4gICAgY29uc3Qgd2lkdGggPSB0aGlzLm9wdGlvbnMud2lkdGggLSB0aGlzLm9wdGlvbnMubWFyZ2luLmxlZnQgLVxuICAgICAgICB0aGlzLm9wdGlvbnMubWFyZ2luLnJpZ2h0O1xuICAgIGNvbnN0IGhlaWdodCA9IHRoaXMub3B0aW9ucy5oZWlnaHQgLSB0aGlzLm9wdGlvbnMubWFyZ2luLnRvcCAtXG4gICAgICAgIHRoaXMub3B0aW9ucy5tYXJnaW4uYm90dG9tO1xuICAgIHRoaXMudmlld0JveCA9IHtcbiAgICAgIG1pblg6IC10aGlzLm9wdGlvbnMubWFyZ2luLmxlZnQsXG4gICAgICBtaW5ZOiAtMTAsXG4gICAgICB3aWR0aDogdGhpcy5vcHRpb25zLndpZHRoLFxuICAgICAgaGVpZ2h0OiB0aGlzLm9wdGlvbnMuaGVpZ2h0IC0gdGhpcy5vcHRpb25zLm1hcmdpbi50b3AsXG4gICAgfTtcblxuICAgIGNvbnN0IHN2ZyA9IGQzLnNlbGVjdCh0aGlzLmNvbnRhaW5lci5uYXRpdmVFbGVtZW50KVxuICAgICAgICAgICAgICAgICAgICAuc2VsZWN0KCdkaXYnKVxuICAgICAgICAgICAgICAgICAgICAuYXBwZW5kKCdzdmcnKVxuICAgICAgICAgICAgICAgICAgICAuYXR0cignd2lkdGgnLCBjdXJyZW50V2lkdGgpXG4gICAgICAgICAgICAgICAgICAgIC5hdHRyKCdoZWlnaHQnLCBjdXJyZW50SGVpZ2h0KVxuXG4gICAgICAgICAgICAgICAgICAgIC5hdHRyKFxuICAgICAgICAgICAgICAgICAgICAgICAgJ3ZpZXdCb3gnLFxuICAgICAgICAgICAgICAgICAgICAgICAgYCR7dGhpcy52aWV3Qm94Lm1pblh9ICR7dGhpcy52aWV3Qm94Lm1pbll9ICR7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy52aWV3Qm94LndpZHRofSAke3RoaXMudmlld0JveC5oZWlnaHR9YClcbiAgICAgICAgICAgICAgICAgICAgLmNsYXNzZWQoJ3N2Zy1jb250ZW50JywgdHJ1ZSlcbiAgICAgICAgICAgICAgICAgICAgLmFwcGVuZCgnZycpO1xuXG4gICAgY29uc3QgeCA9XG4gICAgICAgIGQzLnNjYWxlQmFuZCgpLnJhbmdlUm91bmQoWzAsIHdpZHRoXSkucGFkZGluZygwLjEpLmRvbWFpbih0aGlzLmxhYmVscyk7XG5cbiAgICBjb25zdCB5ID0gZDMuc2NhbGVMaW5lYXIoKS5yYW5nZVJvdW5kKFtoZWlnaHQsIDBdKS5kb21haW4oW1xuICAgICAgMCwgTWF0aC5tYXgoLi4udGhpcy5kYXRhLm1hcCgoZCkgPT4gTnVtYmVyKGQpKSlcbiAgICBdKTtcblxuICAgIGNvbnN0IHhBeGlzID0gKGcpID0+IGcuY2FsbChkMy5heGlzQm90dG9tKHgpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuYXR0cigndHJhbnNmb3JtJywgJ3RyYW5zbGF0ZSgwLCcgKyBoZWlnaHQgKyAnKScpO1xuXG4gICAgY29uc3QgeUF4aXMgPSAoZykgPT4gZy5jYWxsKGQzLmF4aXNMZWZ0KHkpKTtcblxuICAgIC8vIGFkZCB0aGUgWCBncmlkbGluZXNcbiAgICBzdmcuYXBwZW5kKCdnJylcbiAgICAgICAgLmF0dHIoJ2NsYXNzJywgJ2dyaWQnKVxuICAgICAgICAuY2FsbChcbiAgICAgICAgICAgIHRoaXMubWFrZV94X2dyaWRsaW5lcyh4KS50aWNrU2l6ZShoZWlnaHQpXG4gICAgICAgICAgICAvLyAudGlja0Zvcm1hdCgnJylcbiAgICAgICAgKTtcblxuICAgIC8vIGFkZCB0aGUgWSBncmlkbGluZXNcbiAgICBzdmcuYXBwZW5kKCdnJylcbiAgICAgICAgLmF0dHIoJ2NsYXNzJywgJ2dyaWQnKVxuICAgICAgICAuY2FsbChcbiAgICAgICAgICAgIHRoaXMubWFrZV95X2dyaWRsaW5lcyh5KS50aWNrU2l6ZSgtd2lkdGgpXG4gICAgICAgICAgICAvLyAudGlja0Zvcm1hdCgnJylcbiAgICAgICAgKTtcblxuICAgIHN2Zy5zZWxlY3RBbGwoJy5iYXInKVxuICAgICAgICAuZGF0YSh0aGlzLmxhYmVsc0FuZERhdGEpXG4gICAgICAgIC5lbnRlcigpXG4gICAgICAgIC5hcHBlbmQoJ3JlY3QnKVxuICAgICAgICAuYXR0cignY2xhc3MnLCAnYmFyJylcbiAgICAgICAgLmF0dHIoXG4gICAgICAgICAgICAneCcsXG4gICAgICAgICAgICAoZCkgPT4ge1xuICAgICAgICAgICAgICByZXR1cm4geChkLngpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgLmF0dHIoXG4gICAgICAgICAgICAneScsXG4gICAgICAgICAgICAoZCkgPT4ge1xuICAgICAgICAgICAgICByZXR1cm4geShOdW1iZXIoZC55KSk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAuYXR0cignd2lkdGgnLCB4LmJhbmR3aWR0aCgpKVxuICAgICAgICAuYXR0cignaGVpZ2h0JywgKGQpID0+IHtcbiAgICAgICAgICByZXR1cm4gaGVpZ2h0IC0geShOdW1iZXIoZC55KSk7XG4gICAgICAgIH0pO1xuXG4gICAgY29uc3QgX3hBeGlzID0gc3ZnLmFwcGVuZCgnZycpLmNhbGwoeEF4aXMpO1xuXG4gICAgLy8gdGV4dCBsYWJlbCBmb3IgdGhlIHggYXhpc1xuICAgIHRoaXMuYWRkTGFiZWxBeGlzWChzdmcsIHdpZHRoLCBoZWlnaHQpO1xuXG4gICAgY29uc3QgX3lBeGlzID0gc3ZnLmFwcGVuZCgnZycpLmNhbGwoeUF4aXMpO1xuXG4gICAgLy8gdGV4dCBsYWJlbCBmb3IgdGhlIHkgYXhpc1xuICAgIHRoaXMuYWRkTGFiZWxBeGlzWShzdmcsIGhlaWdodCk7XG5cbiAgICB0aGlzLnJlbW92ZUF4aXNUaWNrcyhfeEF4aXMpO1xuICAgIHRoaXMucmVtb3ZlQXhpc1RpY2tzKF95QXhpcyk7XG5cbiAgICB0aGlzLmNoYW5nZUF4aXNDb2xvcihfeEF4aXMsIGF4aXNDb25maWcpO1xuICAgIHRoaXMuY2hhbmdlQXhpc0NvbG9yKF95QXhpcywgYXhpc0NvbmZpZyk7XG4gIH1cblxuICBwcml2YXRlIGNoYW5nZUF4aXNDb2xvcihcbiAgICAgIGF4aXM6IGQzLlNlbGVjdGlvbjxTVkdHRWxlbWVudCwgdW5rbm93biwgbnVsbCwgdW5kZWZpbmVkPiwgY29uZmlnOiBhbnkpIHtcbiAgICB0aGlzLmQzU2VydmljZS5jaGFuZ2VBeGlzQ29sb3IoYXhpcywgY29uZmlnKTtcbiAgfVxuXG5cbiAgcHJpdmF0ZSByZW1vdmVBeGlzVGlja3MoXG4gICAgICBheGlzOiBkMy5TZWxlY3Rpb248U1ZHR0VsZW1lbnQsIHVua25vd24sIG51bGwsIHVuZGVmaW5lZD4pIHtcbiAgICB0aGlzLmQzU2VydmljZS5yZW1vdmVBeGlzVGlja3MoYXhpcyk7XG4gIH1cblxuICBwcml2YXRlIGFkZExhYmVsQXhpc1koXG4gICAgICBzdmc6IGQzLlNlbGVjdGlvbjxTVkdHRWxlbWVudCwgdW5rbm93biwgbnVsbCwgdW5kZWZpbmVkPixcbiAgICAgIGhlaWdodDogbnVtYmVyKSB7XG4gICAgc3ZnLmFwcGVuZCgndGV4dCcpXG4gICAgICAgIC5hdHRyKCd0cmFuc2Zvcm0nLCAncm90YXRlKDApJylcbiAgICAgICAgLmF0dHIoJ3knLCAwIC0gdGhpcy5vcHRpb25zLm1hcmdpbi50b3AgLyAyKVxuICAgICAgICAuYXR0cigneCcsIDApXG4gICAgICAgIC5hdHRyKCdkeScsICcxZW0nKVxuICAgICAgICAuc3R5bGUoJ3RleHQtYW5jaG9yJywgJ3N0YXJ0JylcbiAgICAgICAgLnRleHQodGhpcy5vcHRpb25zLnlBeGlzTGFiZWwpO1xuICB9XG5cbiAgcHJpdmF0ZSBhZGRMYWJlbEF4aXNYKFxuICAgICAgc3ZnOiBkMy5TZWxlY3Rpb248U1ZHR0VsZW1lbnQsIHVua25vd24sIG51bGwsIHVuZGVmaW5lZD4sIHdpZHRoOiBudW1iZXIsXG4gICAgICBoZWlnaHQ6IG51bWJlcikge1xuICAgIHN2Zy5hcHBlbmQoJ3RleHQnKVxuICAgICAgICAuYXR0cihcbiAgICAgICAgICAgICd0cmFuc2Zvcm0nLFxuICAgICAgICAgICAgJ3RyYW5zbGF0ZSgnICsgd2lkdGggLyAyICsgJyAsJyArXG4gICAgICAgICAgICAgICAgKGhlaWdodCArIHRoaXMub3B0aW9ucy5tYXJnaW4udG9wIC0gMTUpICsgJyknKVxuICAgICAgICAuc3R5bGUoJ3RleHQtYW5jaG9yJywgJ21pZGRsZScpXG4gICAgICAgIC50ZXh0KHRoaXMub3B0aW9ucy54QXhpc0xhYmVsKTtcbiAgfVxuXG4gIHByaXZhdGUgY29tYmluZUxhYmVsc0RhdGFUb09uZSgpOiBMYWJlbHNBbmREYXRhW10ge1xuICAgIGNvbnN0IHJlc3VsdCA9IFtdO1xuICAgIGNvbnN0IE4gPSB0aGlzLmRhdGEubGVuZ3RoO1xuICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBOOyBpbmRleCsrKSB7XG4gICAgICByZXN1bHQucHVzaCh7eDogdGhpcy5sYWJlbHNbaW5kZXhdLCB5OiB0aGlzLmRhdGFbaW5kZXhdfSk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbiAgLy8gZ3JpZGxpbmVzIGluIHggYXhpcyBmdW5jdGlvblxuICBwcml2YXRlIG1ha2VfeF9ncmlkbGluZXMoeCkge1xuICAgIHJldHVybiBkMy5heGlzQm90dG9tKHgpLnRpY2tzKHRoaXMub3B0aW9ucy5ncmlkVGlja3MpO1xuICB9XG5cbiAgLy8gZ3JpZGxpbmVzIGluIHkgYXhpcyBmdW5jdGlvblxuICBwcml2YXRlIG1ha2VfeV9ncmlkbGluZXMoeSkge1xuICAgIHJldHVybiBkMy5heGlzTGVmdCh5KS50aWNrcyh0aGlzLm9wdGlvbnMuZ3JpZFRpY2tzKTtcbiAgfVxuXG4gIG9uUmVzaXplRXZlbnQoKTogdm9pZCB7XG4gICAgdGhpcy5vblJlc2l6ZSQucGlwZShkZWJvdW5jZVRpbWUoMjAwKSkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgIGNvbnN0IHN2Z0V4aXN0ID0gZDMuc2VsZWN0KHRoaXMuY29udGFpbmVyLm5hdGl2ZUVsZW1lbnQpLnNlbGVjdCgnc3ZnJyk7XG4gICAgICBpZiAoc3ZnRXhpc3QpIHtcbiAgICAgICAgc3ZnRXhpc3QucmVtb3ZlKCk7XG4gICAgICB9XG4gICAgICB0aGlzLnJlbmRlcigpO1xuICAgIH0pO1xuICB9XG59XG4iXX0=