@asoftwareworld/charts
Version:
`ASW Charts` helps you with the Highcharts library comes with all the tools you need to create reliable and secure data visualizations and Built on Angular.
479 lines • 67.8 kB
JavaScript
import { Component, EventEmitter, Input, Output, ViewChild } from '@angular/core';
import { AswChartConstants, CurrencyCodeEnum, GridOptionsEnum } from '@asoftwareworld/charts/core';
import * as Highcharts from 'highcharts';
import HighchartsMore from 'highcharts/highcharts-more';
import HighchartsSolidGauge from 'highcharts/modules/solid-gauge.src';
import { ObjectUtils } from '@asoftwareworld/charts/utils';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
HighchartsMore(Highcharts);
HighchartsSolidGauge(Highcharts);
export class AswSemiCircleDonut {
constructor(percentPipe, currencyPipe) {
this.percentPipe = percentPipe;
this.currencyPipe = currencyPipe;
this.deviceSize = GridOptionsEnum.Large;
this.viewInitialized = false;
this.isLegendSort = true;
this.isMute = false;
this.isLegendDisplay = true;
// @Input() chartType: ChartTypeEnum = ChartTypeEnum.Donut;
this.currencyCode = CurrencyCodeEnum.INR;
// @Input() legendPosition: LegendPositionEnum = LegendPositionEnum.Right;
// @Input() legendType: LegendTypeEnum = LegendTypeEnum.Both;
this.legendWidthPx = 250;
this.donutSliceClick = new EventEmitter();
}
ngOnChanges() {
if (!this.viewInitialized) {
return;
}
this.initializeChart();
}
ngAfterViewInit() {
this.viewInitialized = true;
this.initializeChart();
}
initializeChart() {
if (this.config) {
this.cloneConfiguration = this.config;
const containerWidth = this.semiCircleDonutChart.nativeElement.clientWidth;
this.deviceSize = ObjectUtils.findDeviceSize(containerWidth);
this.findDeviceSize();
this.removeChartCredit();
this.setSemiDonutChartTooltip();
// const series: SeriesPieOptions[] = this.cloneConfiguration.series as SeriesPieOptions[];
// this.setDonutChartSeriesOptions(series);
// this.setDonutChartLegendOption(this.legendWidthPx);
// // if (this.chartType === ChartTypeEnum.Donut) {
// // this.setDonutChartInnerText();
// // }
this.semiDonutChartSliceClick();
this.setSemiDonutChartShape();
Highcharts.chart(this.semiCircleDonutChart.nativeElement, this.cloneConfiguration);
}
}
removeChartCredit() {
this.cloneConfiguration.credits = {
enabled: false
};
}
setSemiDonutChartTooltip() {
const this$ = this;
this.cloneConfiguration.tooltip = {
useHTML: true,
split: false,
backgroundColor: AswChartConstants.blackColor,
borderColor: AswChartConstants.blackColor,
style: {
color: AswChartConstants.whiteColor,
fontWeight: AswChartConstants.fontWeight
},
borderRadius: 0,
enabled: this.isMute ? false : true,
formatter() {
const percentage = this.point.percentage;
return `
<div class="row">
${this.point.name ?
`<div class="col-md-12 text-end">
<span style="color: ${this.point.color}">\u25A0</span>
<strong>${this.point.name}</strong>
</div>` : ``}
<div class="col-md-12 text-end">
${percentage ? this$.percentPipe.transform(percentage / 100, '.2') : this.point.options.y + '%'}
</div>
</div>
`;
}
};
}
semiDonutChartSliceClick() {
if (this.isMute) {
return;
}
this.cloneConfiguration.plotOptions = {
pie: {
dataLabels: {
enabled: false,
},
states: {
hover: {
enabled: false
}
},
startAngle: -90,
endAngle: 90,
center: ['50%', '75%'],
size: '110%'
},
series: {
point: {
events: {
click: ((event) => {
// const pointClickEvent: PointClickEvent = {
// name: event.point.name,
// id: event.point.options.id,
// percentage: event.point.percentage,
// value: event.point.options.value,
// target: event.point.options.target
// };
// this.donutSliceClick.emit(pointClickEvent);
})
}
}
}
};
}
setSemiDonutChartShape() {
this.cloneConfiguration.pane = {
center: ['50%', '70%'],
size: '70%',
startAngle: -90,
endAngle: 90,
background: [{
borderWidth: 0,
backgroundColor: 'none',
shape: 'arc',
}],
};
}
setDonutChartSeriesOptions(series) {
series.forEach((seriesOption) => {
seriesOption.allowPointSelect = true;
seriesOption.showInLegend = true;
// if (this.chartType === ChartTypeEnum.Donut) {
// seriesOption.innerSize = AswChartConstants.innerSize;
// }
if (this.isMute) {
seriesOption.opacity = 0.35;
seriesOption.states = {
hover: {
enabled: false
},
inactive: {
enabled: false
}
};
seriesOption.slicedOffset = 0;
}
seriesOption.cursor = AswChartConstants.pointer;
const data = seriesOption.data;
this.handleNegativeSeriesData(data);
const sortedSeriesOptionData = this.isLegendSort ? this.sortSeriesData(data) : data;
seriesOption.data = sortedSeriesOptionData;
});
}
sortSeriesData(data) {
// if (this.legendType === LegendTypeEnum.Default) {
// data.sort((a: any, b: any) => {
// return ('' + a.name).localeCompare(b.name);
// });
// return data;
// } else {
data.sort((a, b) => {
if (a.y && b.y) {
return a.value - b.value;
}
else {
return 0;
}
});
data.reverse();
return data;
// }
}
handleNegativeSeriesData(data) {
data.forEach((element) => {
element.value = element.y;
element.y = element.y ? Math.abs(element.y) : 0.001;
});
}
setDonutChartLegendOption(legendWidthPx) {
const this$ = this;
this.cloneConfiguration.legend = {
useHTML: true,
enabled: this.isMute ? false : this.isLegendDisplay,
floating: false,
// navigation: {
// arrowSize: 12
// },
align: this.setLegendAlignment(),
layout: 'vertical',
verticalAlign: this.setLegendVerticalAlignment(),
symbolHeight: 10,
symbolWidth: 10,
symbolRadius: 0,
itemMarginTop: 3,
itemMarginBottom: 3,
itemStyle: {
fontSize: this.deviceSize === GridOptionsEnum.ExtraSmall ? '12px' : '14px',
fontWeight: AswChartConstants.fontWeight
},
width: legendWidthPx + 15,
title: {
text: this$.setDonutChartLegendWithHeader(legendWidthPx + 15),
style: {
fontSize: this.deviceSize === GridOptionsEnum.ExtraSmall
? AswChartConstants.fontSize12 : AswChartConstants.fontSize14,
color: '#6c757d',
fontWeight: AswChartConstants.fontWeight,
fontFamily: '500 14px/20px Google Sans Text,Arial,Helvetica,sans-serif'
}
},
labelFormatter() {
const point = this;
return this$.setDonutChartLegendWithHeader(legendWidthPx, point.name, point.percentage, point.options.value);
}
};
}
setFontSize() {
return this.deviceSize === GridOptionsEnum.ExtraSmall ? AswChartConstants.fontSize14 : AswChartConstants.fontSize16;
}
setLegendAlignment() {
if (this.deviceSize === GridOptionsEnum.ExtraSmall) {
return 'center';
}
// else if (this.legendPosition === LegendPositionEnum.Right) {
// return LegendPositionEnum.Right;
// } else if (this.legendPosition === LegendPositionEnum.Left) {
// return LegendPositionEnum.Left;
// }
else {
return 'center';
}
}
setLegendVerticalAlignment() {
// if (this.deviceSize === GridOptionsEnum.ExtraSmall) {
// return LegendPositionEnum.Bottom;
// } else if (this.legendPosition === LegendPositionEnum.Right) {
// return 'middle';
// } else if (this.legendPosition === LegendPositionEnum.Left) {
// return 'middle';
// } else {
// return LegendPositionEnum.Bottom;
// }
return 'bottom';
}
setDonutChartLegendWithHeader(legendWidthPx, name, percentage, value) {
// let legendCategoryWidthPx: number;
// let legendValueWidthPx: number;
// let legendPercentageWidthPx: number;
// switch (this.legendType) {
// case LegendTypeEnum.Default:
// return `
// <div style="width:${legendWidthPx}px">
// <div class="row">
// <div class="col-md-12 col-sm-12 col-12">
// ${name ? name : 'Category'}
// </div>
// </div>
// </div>
// `;
// case LegendTypeEnum.Percentage:
// legendCategoryWidthPx = legendWidthPx * 0.9;
// legendPercentageWidthPx = legendWidthPx * 0.1;
// return `
// <div style="width:${legendCategoryWidthPx + legendPercentageWidthPx}px">
// <div class="row">
// <div class="col-md-8 col-sm-8 col-8">
// ${name ? name : 'Category'}
// </div>
// <div class="col-md-4 col-sm-4 col-4 text-end">
// ${percentage ? this.percentPipe.transform(percentage / 100, '.0') : '%'}
// </div>
// </div>
// </div>
// `;
// case LegendTypeEnum.Value:
// legendCategoryWidthPx = legendWidthPx * 0.5;
// legendValueWidthPx = legendWidthPx * 0.5;
// return `
// <div style="width:${legendCategoryWidthPx + legendValueWidthPx}px">
// <div class="row">
// <div class="col-md-6 col-sm-6 col-6">
// ${name ? name : 'Category'}
// </div>
// <div class="col-md-6 col-sm-6 col-6 text-end">
// ${value ? this.currencyPipe.transform(value, 'INR') : 'Total'}
// </div>
// </div>
// </div>
// `;
// default:
// legendCategoryWidthPx = legendWidthPx * 0.5;
// legendPercentageWidthPx = legendWidthPx * 0.1;
// legendValueWidthPx = legendWidthPx * 0.4;
// return `
// <div style="width:${legendCategoryWidthPx + legendPercentageWidthPx + legendValueWidthPx}px">
// <div class="row">
// <div class="col-md-5 col-sm-5 col-5">
// ${name ? name : 'Category'}
// </div>
// <div class="col-md-2 col-xs-2 col-2 text-end">
// ${percentage ? this.percentPipe.transform(percentage / 100) : '%'}
// </div>
// <div class="col-md-5 col-sm-5 col-5 text-end">
// ${value ? this.currencyPipe.transform(value, this.currencyCode) : 'Total'}
// </div>
// </div>
// </div>
// `;
// }
return '';
}
findDeviceSize() {
const containerWidth = this.semiCircleDonutChart.nativeElement.clientWidth;
if (containerWidth >= 1400) {
this.deviceSize = GridOptionsEnum.ExtraExtraLarge;
}
else if (containerWidth >= 1200) {
this.deviceSize = GridOptionsEnum.ExtraLarge;
}
else if (containerWidth >= 992) {
this.deviceSize = GridOptionsEnum.Large;
}
else if (containerWidth >= 768) {
this.deviceSize = GridOptionsEnum.Medium;
}
else if (containerWidth >= 576) {
this.deviceSize = GridOptionsEnum.Small;
}
else if (containerWidth < 576) {
this.deviceSize = GridOptionsEnum.ExtraSmall;
}
}
setDonutChartInnerText() {
const this$ = this;
this.cloneConfiguration.chart = {
events: {
load() {
let centerX;
let centerY;
let itemWidth;
this.series.forEach((element) => {
const points = element.points.slice(0, 1);
points.forEach((point) => {
centerX = this.plotLeft + (point.shapeArgs.x - point.shapeArgs.innerR) + 8;
centerY = this.plotTop + point.shapeArgs.y - 14;
itemWidth = (point.shapeArgs.innerR * 2) - 20;
});
if (this$.icon) {
this.renderer.label(this$.setInnerTextIcon(itemWidth), centerX, this$.deviceSize === GridOptionsEnum.ExtraSmall ? centerY - 20 : centerY - 25, undefined, 30, 30, true).css({
fontSize: this$.setFontSize(),
textAlign: AswChartConstants.centerAlign,
fontWeight: AswChartConstants.fontWeight
}).add();
this.renderer.label(this$.setInnerTextLabel(itemWidth), centerX, centerY, undefined, 30, 30, true).css({
fontSize: this$.setFontSize(),
textAlign: AswChartConstants.centerAlign,
fontWeight: AswChartConstants.fontWeight
}).add();
this.renderer.label(this$.setInnerTextValue(itemWidth), centerX, this$.deviceSize === GridOptionsEnum.ExtraSmall ? centerY + 20 : centerY + 25, undefined, 30, 30, true).css({
fontSize: this$.setFontSize(),
textAlign: AswChartConstants.centerAlign,
fontWeight: AswChartConstants.fontWeight
}).add();
}
else {
this.renderer.label(this$.setInnerTextLabel(itemWidth), centerX, this$.deviceSize === GridOptionsEnum.ExtraSmall ? centerY - 20 : centerY - 25, undefined, 30, 30, true).css({
fontSize: this$.setFontSize(),
textAlign: AswChartConstants.centerAlign,
fontWeight: AswChartConstants.fontWeight
}).add();
this.renderer.label(this$.setInnerTextValue(itemWidth), centerX, centerY, undefined, 30, 30, true).css({
fontSize: this$.setFontSize(),
textAlign: AswChartConstants.centerAlign,
fontWeight: AswChartConstants.fontWeight
}).add();
this.renderer.label(this$.setInnerTextTarget(itemWidth), centerX, this$.deviceSize === GridOptionsEnum.ExtraSmall ? centerY + 20 : centerY + 25, undefined, 30, 30, true).css({
fontSize: this$.setFontSize(),
textAlign: AswChartConstants.centerAlign,
fontWeight: AswChartConstants.fontWeight
}).add();
}
});
}
}
};
}
setInnerTextLabel(width) {
return `
<div style="width: ${width}px; opacity: ${this.isMute ? 0.35 : 1}">
<div class="row">
<div class="col-md-12 text-truncate">
${this.label}
</div>
</div>
</div>
`;
}
setInnerTextIcon(width) {
return `
<div style="width: ${width}px; opacity: ${this.isMute ? 0.35 : 1}">
<div class="row">
<div class="col-md-12 text-truncate">
${this.icon}
</div>
</div>
</div>
`;
}
setInnerTextValue(width) {
return `
<div style="width: ${width}px; opacity: ${this.isMute ? 0.35 : 1}">
<div class="row">
<div class="col-md-12 text-truncate">
<strong>${this.currencyPipe.transform(this.amount, this.currencyCode)}</strong>
</div>
</div>
</div>
`;
}
setInnerTextTarget(width) {
return `
<div style="width: ${width}px; opacity: ${this.isMute ? 0.35 : 1}">
<div class="row">
<div class="col-md-12 text-truncate">
${this.target ? this.target : ''}
</div>
</div>
</div>
`;
}
}
AswSemiCircleDonut.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.2", ngImport: i0, type: AswSemiCircleDonut, deps: [{ token: i1.PercentPipe }, { token: i1.CurrencyPipe }], target: i0.ɵɵFactoryTarget.Component });
AswSemiCircleDonut.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.2", type: AswSemiCircleDonut, selector: "asw-semi-circle-donut", inputs: { config: "config", isLegendSort: "isLegendSort", isMute: "isMute", isLegendDisplay: "isLegendDisplay", icon: "icon", label: "label", amount: "amount", target: "target", currencyCode: "currencyCode", legendWidthPx: "legendWidthPx" }, outputs: { donutSliceClick: "donutSliceClick" }, viewQueries: [{ propertyName: "semiCircleDonutChart", first: true, predicate: ["semiCircleDonutChart"], descendants: true, static: true }, { propertyName: "chartId", first: true, predicate: ["chartId"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div #semiCircleDonutChart></div>", styles: [""] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.2", ngImport: i0, type: AswSemiCircleDonut, decorators: [{
type: Component,
args: [{ selector: 'asw-semi-circle-donut', template: "<div #semiCircleDonutChart></div>", styles: [""] }]
}], ctorParameters: function () { return [{ type: i1.PercentPipe }, { type: i1.CurrencyPipe }]; }, propDecorators: { config: [{
type: Input
}], isLegendSort: [{
type: Input
}], isMute: [{
type: Input
}], isLegendDisplay: [{
type: Input
}], icon: [{
type: Input
}], label: [{
type: Input
}], amount: [{
type: Input
}], target: [{
type: Input
}], currencyCode: [{
type: Input
}], legendWidthPx: [{
type: Input
}], donutSliceClick: [{
type: Output
}], semiCircleDonutChart: [{
type: ViewChild,
args: ['semiCircleDonutChart', { static: true }]
}], chartId: [{
type: ViewChild,
args: ['chartId', { static: true }]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VtaS1jaXJjbGUtZG9udXQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvYXBwL2NvbXBvbmVudC9zZW1pLWNpcmNsZS1kb251dC9jb21wb25lbnQvc2VtaS1jaXJjbGUtZG9udXQudHMiLCIuLi8uLi8uLi8uLi9zcmMvYXBwL2NvbXBvbmVudC9zZW1pLWNpcmNsZS1kb251dC9jb21wb25lbnQvc2VtaS1jaXJjbGUtZG9udXQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFTQSxPQUFPLEVBQWlCLFNBQVMsRUFBYyxZQUFZLEVBQUUsS0FBSyxFQUFhLE1BQU0sRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDeEgsT0FBTyxFQUFFLGlCQUFpQixFQUFFLGdCQUFnQixFQUFFLGVBQWUsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ25HLE9BQU8sS0FBSyxVQUFVLE1BQU0sWUFBWSxDQUFDO0FBQ3pDLE9BQU8sY0FBYyxNQUFNLDRCQUE0QixDQUFDO0FBRXhELE9BQU8sb0JBQW9CLE1BQU0sb0NBQW9DLENBQUM7QUFhdEUsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDhCQUE4QixDQUFDOzs7QUFkM0QsY0FBYyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0FBRTNCLG9CQUFvQixDQUFDLFVBQVUsQ0FBQyxDQUFDO0FBbUJqQyxNQUFNLE9BQU8sa0JBQWtCO0lBdUIzQixZQUNZLFdBQXdCLEVBQ3hCLFlBQTBCO1FBRDFCLGdCQUFXLEdBQVgsV0FBVyxDQUFhO1FBQ3hCLGlCQUFZLEdBQVosWUFBWSxDQUFjO1FBdEIvQixlQUFVLEdBQW9CLGVBQWUsQ0FBQyxLQUFLLENBQUM7UUFDbkQsb0JBQWUsR0FBRyxLQUFLLENBQUM7UUFFdkIsaUJBQVksR0FBRyxJQUFJLENBQUM7UUFDcEIsV0FBTSxHQUFHLEtBQUssQ0FBQztRQUNmLG9CQUFlLEdBQUcsSUFBSSxDQUFDO1FBS2hDLDJEQUEyRDtRQUNsRCxpQkFBWSxHQUFx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LEtBQUs7Z0JBQ0csS0FBSztzQkFBYixLQUFLO2dCQUNHLE1BQU07c0JBQWQsS0FBSztnQkFDRyxNQUFNO3NCQUFkLEtBQUs7Z0JBRUcsWUFBWTtzQkFBcEIsS0FBSztnQkFHRyxhQUFhO3NCQUFyQixLQUFLO2dCQUVJLGVBQWU7c0JBQXhCLE1BQU07Z0JBRThDLG9CQUFvQjtzQkFBeEUsU0FBUzt1QkFBQyxzQkFBc0IsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Z0JBQ1gsT0FBTztzQkFBOUMsU0FBUzt1QkFBQyxTQUFTLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXHJcbiAqIEBsaWNlbnNlXHJcbiAqIENvcHlyaWdodCBBU1cgKEEgU29mdHdhcmUgV29ybGQpIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXHJcbiAqXHJcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXHJcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGVcclxuICovXHJcblxyXG5pbXBvcnQgeyBDdXJyZW5jeVBpcGUsIFBlcmNlbnRQaXBlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcclxuaW1wb3J0IHsgQWZ0ZXJWaWV3SW5pdCwgQ29tcG9uZW50LCBFbGVtZW50UmVmLCBFdmVudEVtaXR0ZXIsIElucHV0LCBPbkNoYW5nZXMsIE91dHB1dCwgVmlld0NoaWxkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IEFzd0NoYXJ0Q29uc3RhbnRzLCBDdXJyZW5jeUNvZGVFbnVtLCBHcmlkT3B0aW9uc0VudW0gfSBmcm9tICdAYXNvZnR3YXJld29ybGQvY2hhcnRzL2NvcmUnO1xyXG5pbXBvcnQgKiBhcyBIaWdoY2hhcnRzIGZyb20gJ2hpZ2hjaGFydHMnO1xyXG5pbXBvcnQgSGlnaGNoYXJ0c01vcmUgZnJvbSAnaGlnaGNoYXJ0cy9oaWdoY2hhcnRzLW1vcmUnO1xyXG5IaWdoY2hhcnRzTW9yZShIaWdoY2hhcnRzKTtcclxuaW1wb3J0IEhpZ2hjaGFydHNTb2xpZEdhdWdlIGZyb20gJ2hpZ2hjaGFydHMvbW9kdWxlcy9zb2xpZC1nYXVnZS5zcmMnO1xyXG5IaWdoY2hhcnRzU29saWRHYXVnZShIaWdoY2hhcnRzKTtcclxuXHJcbmltcG9ydCB7XHJcbiAgICBBbGlnblZhbHVlLFxyXG4gICAgT3B0aW9ucyxcclxuICAgIFBvaW50Q2xpY2tFdmVudE9iamVjdCxcclxuICAgIFBvaW50T3B0aW9uc09iamVjdCxcclxuICAgIFBvaW50LFxyXG4gICAgU2VyaWVzLFxyXG4gICAgU2VyaWVzUGllT3B0aW9ucyxcclxuICAgIFZlcnRpY2FsQWxpZ25WYWx1ZVxyXG59IGZyb20gJ2hpZ2hjaGFydHMnO1xyXG5pbXBvcnQgeyBPYmplY3RVdGlscyB9IGZyb20gJ0Bhc29mdHdhcmV3b3JsZC9jaGFydHMvdXRpbHMnO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgICBzZWxlY3RvcjogJ2Fzdy1zZW1pLWNpcmNsZS1kb251dCcsXHJcbiAgICB0ZW1wbGF0ZVVybDogJy4vc2VtaS1jaXJjbGUtZG9udXQuaHRtbCcsXHJcbiAgICBzdHlsZVVybHM6IFsnLi9zZW1pLWNpcmNsZS1kb251dC5zY3NzJ11cclxufSlcclxuZXhwb3J0IGNsYXNzIEFzd1NlbWlDaXJjbGVEb251dCBpbXBsZW1lbnRzIE9uQ2hhbmdlcywgQWZ0ZXJWaWV3SW5pdCB7XHJcblxyXG4gICAgcHJpdmF0ZSBjbG9uZUNvbmZpZ3VyYXRpb24hOiBPcHRpb25zO1xyXG4gICAgcHVibGljIGRldmljZVNpemU6IEdyaWRPcHRpb25zRW51bSA9IEdyaWRPcHRpb25zRW51bS5MYXJnZTtcclxuICAgIHByaXZhdGUgdmlld0luaXRpYWxpemVkID0gZmFsc2U7XHJcbiAgICBASW5wdXQoKSBjb25maWchOiBPcHRpb25zO1xyXG4gICAgQElucHV0KCkgaXNMZWdlbmRTb3J0ID0gdHJ1ZTtcclxuICAgIEBJbnB1dCgpIGlzTXV0ZSA9IGZhbHNlO1xyXG4gICAgQElucHV0KCkgaXNMZWdlbmREaXNwbGF5ID0gdHJ1ZTtcclxuICAgIEBJbnB1dCgpIGljb24hOiBzdHJpbmc7XHJcbiAgICBASW5wdXQoKSBsYWJlbDogc3RyaW5nIHwgdW5kZWZpbmVkO1xyXG4gICAgQElucHV0KCkgYW1vdW50OiBudW1iZXIgfCBudWxsIHwgdW5kZWZpbmVkO1xyXG4gICAgQElucHV0KCkgdGFyZ2V0ITogc3RyaW5nO1xyXG4gICAgLy8gQElucHV0KCkgY2hhcnRUeXBlOiBDaGFydFR5cGVFbnVtID0gQ2hhcnRUeXBlRW51bS5Eb251dDtcclxuICAgIEBJbnB1dCgpIGN1cnJlbmN5Q29kZTogQ3VycmVuY3lDb2RlRW51bSA9IEN1cnJlbmN5Q29kZUVudW0uSU5SO1xyXG4gICAgLy8gQElucHV0KCkgbGVnZW5kUG9zaXRpb246IExlZ2VuZFBvc2l0aW9uRW51bSA9IExlZ2VuZFBvc2l0aW9uRW51bS5SaWdodDtcclxuICAgIC8vIEBJbnB1dCgpIGxlZ2VuZFR5cGU6IExlZ2VuZFR5cGVFbnVtID0gTGVnZW5kVHlwZUVudW0uQm90aDtcclxuICAgIEBJbnB1dCgpIGxlZ2VuZFdpZHRoUHggPSAyNTA7XHJcblxyXG4gICAgQE91dHB1dCgpIGRvbnV0U2xpY2VDbGljazogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcclxuXHJcbiAgICBAVmlld0NoaWxkKCdzZW1pQ2lyY2xlRG9udXRDaGFydCcsIHsgc3RhdGljOiB0cnVlIH0pIHNlbWlDaXJjbGVEb251dENoYXJ0ITogRWxlbWVudFJlZjtcclxuICAgIEBWaWV3Q2hpbGQoJ2NoYXJ0SWQnLCB7IHN0YXRpYzogdHJ1ZSB9KSBjaGFydElkITogRWxlbWVudFJlZjtcclxuICAgIGNvbnN0cnVjdG9yKFxyXG4gICAgICAgIHByaXZhdGUgcGVyY2VudFBpcGU6IFBlcmNlbnRQaXBlLFxyXG4gICAgICAgIHByaXZhdGUgY3VycmVuY3lQaXBlOiBDdXJyZW5jeVBpcGUpIHsgfVxyXG5cclxuICAgIG5nT25DaGFuZ2VzKCk6IHZvaWQge1xyXG4gICAgICAgIGlmICghdGhpcy52aWV3SW5pdGlhbGl6ZWQpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmluaXRpYWxpemVDaGFydCgpO1xyXG4gICAgfVxyXG5cclxuICAgIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLnZpZXdJbml0aWFsaXplZCA9IHRydWU7XHJcbiAgICAgICAgdGhpcy5pbml0aWFsaXplQ2hhcnQoKTtcclxuICAgIH1cclxuXHJcbiAgICBpbml0aWFsaXplQ2hhcnQoKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKHRoaXMuY29uZmlnKSB7XHJcbiAgICAgICAgICAgIHRoaXMuY2xvbmVDb25maWd1cmF0aW9uID0gdGhpcy5jb25maWc7XHJcbiAgICAgICAgICAgIGNvbnN0IGNvbnRhaW5lcldpZHRoID0gdGhpcy5zZW1pQ2lyY2xlRG9udXRDaGFydC5uYXRpdmVFbGVtZW50LmNsaWVudFdpZHRoO1xyXG4gICAgICAgICAgICB0aGlzLmRldmljZVNpemUgPSBPYmplY3RVdGlscy5maW5kRGV2aWNlU2l6ZShjb250YWluZXJXaWR0aCk7XHJcbiAgICAgICAgICAgIHRoaXMuZmluZERldmljZVNpemUoKTtcclxuICAgICAgICAgICAgdGhpcy5yZW1vdmVDaGFydENyZWRpdCgpO1xyXG4gICAgICAgICAgICB0aGlzLnNldFNlbWlEb251dENoYXJ0VG9vbHRpcCgpO1xyXG4gICAgICAgICAgICAvLyBjb25zdCBzZXJpZXM6IFNlcmllc1BpZU9wdGlvbnNbXSA9IHRoaXMuY2xvbmVDb25maWd1cmF0aW9uLnNlcmllcyBhcyBTZXJpZXNQaWVPcHRpb25zW107XHJcbiAgICAgICAgICAgIC8vIHRoaXMuc2V0RG9udXRDaGFydFNlcmllc09wdGlvbnMoc2VyaWVzKTtcclxuICAgICAgICAgICAgLy8gdGhpcy5zZXREb251dENoYXJ0TGVnZW5kT3B0aW9uKHRoaXMubGVnZW5kV2lkdGhQeCk7XHJcbiAgICAgICAgICAgIC8vIC8vIGlmICh0aGlzLmNoYXJ0VHlwZSA9PT0gQ2hhcnRUeXBlRW51bS5Eb251dCkge1xyXG4gICAgICAgICAgICAvLyAvLyAgICAgdGhpcy5zZXREb251dENoYXJ0SW5uZXJUZXh0KCk7XHJcbiAgICAgICAgICAgIC8vIC8vIH1cclxuICAgICAgICAgICAgdGhpcy5zZW1pRG9udXRDaGFydFNsaWNlQ2xpY2soKTtcclxuICAgICAgICAgICAgdGhpcy5zZXRTZW1pRG9udXRDaGFydFNoYXBlKCk7XHJcbiAgICAgICAgICAgIEhpZ2hjaGFydHMuY2hhcnQodGhpcy5zZW1pQ2lyY2xlRG9udXRDaGFydC5uYXRpdmVFbGVtZW50LCB0aGlzLmNsb25lQ29uZmlndXJhdGlvbik7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgcmVtb3ZlQ2hhcnRDcmVkaXQoKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5jbG9uZUNvbmZpZ3VyYXRpb24uY3JlZGl0cyA9IHtcclxuICAgICAgICAgICAgZW5hYmxlZDogZmFsc2VcclxuICAgICAgICB9O1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgc2V0U2VtaURvbnV0Q2hhcnRUb29sdGlwKCk6IHZvaWQge1xyXG4gICAgICAgIGNvbnN0IHRoaXMkOiB0aGlzID0gdGhpcztcclxuICAgICAgICB0aGlzLmNsb25lQ29uZmlndXJhdGlvbi50b29sdGlwID0ge1xyXG4gICAgICAgICAgICB1c2VIVE1MOiB0cnVlLFxyXG4gICAgICAgICAgICBzcGxpdDogZmFsc2UsXHJcbiAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogQXN3Q2hhcnRDb25zdGFudHMuYmxhY2tDb2xvcixcclxuICAgICAgICAgICAgYm9yZGVyQ29sb3I6IEFzd0NoYXJ0Q29uc3RhbnRzLmJsYWNrQ29sb3IsXHJcbiAgICAgICAgICAgIHN0eWxlOiB7XHJcbiAgICAgICAgICAgICAgICBjb2xvcjogQXN3Q2hhcnRDb25zdGFudHMud2hpdGVDb2xvcixcclxuICAgICAgICAgICAgICAgIGZvbnRXZWlnaHQ6IEFzd0NoYXJ0Q29uc3RhbnRzLmZvbnRXZWlnaHRcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgYm9yZGVyUmFkaXVzOiAwLFxyXG4gICAgICAgICAgICBlbmFibGVkOiB0aGlzLmlzTXV0ZSA/IGZhbHNlIDogdHJ1ZSxcclxuICAgICAgICAgICAgZm9ybWF0dGVyKCk6IHN0cmluZyB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBwZXJjZW50YWdlOiBudW1iZXIgPSB0aGlzLnBvaW50LnBlcmNlbnRhZ2UgYXMgbnVtYmVyO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGBcclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicm93XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICR7IHRoaXMucG9pbnQubmFtZSA/XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGA8ZGl2IGNsYXNzPVwiY29sLW1kLTEyIHRleHQtZW5kXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBzdHlsZT1cImNvbG9yOiAke3RoaXMucG9pbnQuY29sb3J9XCI+XFx1MjVBMDwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdHJvbmc+JHt0aGlzLnBvaW50Lm5hbWV9PC9zdHJvbmc+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PmAgOiBgYFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtMTIgdGV4dC1lbmRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICR7cGVyY2VudGFnZSA/IHRoaXMkLnBlcmNlbnRQaXBlLnRyYW5zZm9ybShwZXJjZW50YWdlIC8gMTAwLCAnLjInKSA6IHRoaXMucG9pbnQub3B0aW9ucy55ICsgJyUnfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICBgO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHNlbWlEb251dENoYXJ0U2xpY2VDbGljaygpOiB2b2lkIHtcclxuICAgICAgICBpZiAodGhpcy5pc011dGUpIHsgcmV0dXJuOyB9XHJcbiAgICAgICAgdGhpcy5jbG9uZUNvbmZpZ3VyYXRpb24ucGxvdE9wdGlvbnMgPSB7XHJcbiAgICAgICAgICAgIHBpZToge1xyXG4gICAgICAgICAgICAgICAgZGF0YUxhYmVsczoge1xyXG4gICAgICAgICAgICAgICAgICAgIGVuYWJsZWQ6IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIHN0YXRlczoge1xyXG4gICAgICAgICAgICAgICAgICAgIGhvdmVyOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVuYWJsZWQ6IGZhbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIHN0YXJ0QW5nbGU6IC05MCxcclxuICAgICAgICAgICAgICAgIGVuZEFuZ2xlOiA5MCxcclxuICAgICAgICAgICAgICAgIGNlbnRlcjogWyc1MCUnLCAnNzUlJ10sXHJcbiAgICAgICAgICAgICAgICBzaXplOiAnMTEwJSdcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgc2VyaWVzOiB7XHJcbiAgICAgICAgICAgICAgICBwb2ludDoge1xyXG4gICAgICAgICAgICAgICAgICAgIGV2ZW50czoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGljazogKChldmVudDogUG9pbnRDbGlja0V2ZW50T2JqZWN0KSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjb25zdCBwb2ludENsaWNrRXZlbnQ6IFBvaW50Q2xpY2tFdmVudCA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgICBuYW1lOiBldmVudC5wb2ludC5uYW1lLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgIGlkOiBldmVudC5wb2ludC5vcHRpb25zLmlkLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgIHBlcmNlbnRhZ2U6IGV2ZW50LnBvaW50LnBlcmNlbnRhZ2UsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgICAgdmFsdWU6IGV2ZW50LnBvaW50Lm9wdGlvbnMudmFsdWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgICAgdGFyZ2V0OiBldmVudC5wb2ludC5vcHRpb25zLnRhcmdldFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoaXMuZG9udXRTbGljZUNsaWNrLmVtaXQocG9pbnRDbGlja0V2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgc2V0U2VtaURvbnV0Q2hhcnRTaGFwZSgpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmNsb25lQ29uZmlndXJhdGlvbi5wYW5lID0ge1xyXG4gICAgICAgICAgICBjZW50ZXI6IFsnNTAlJywgJzcwJSddLFxyXG4gICAgICAgICAgICBzaXplOiAnNzAlJyxcclxuICAgICAgICAgICAgc3RhcnRBbmdsZTogLTkwLFxyXG4gICAgICAgICAgICBlbmRBbmdsZTogOTAsXHJcbiAgICAgICAgICAgIGJhY2tncm91bmQ6IFt7XHJcbiAgICAgICAgICAgICAgICBib3JkZXJXaWR0aDogMCxcclxuICAgICAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogJ25vbmUnLFxyXG4gICAgICAgICAgICAgICAgc2hhcGU6ICdhcmMnLFxyXG4gICAgICAgICAgICB9XSxcclxuICAgICAgICB9O1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgc2V0RG9udXRDaGFydFNlcmllc09wdGlvbnMoc2VyaWVzOiBTZXJpZXNQaWVPcHRpb25zW10pOiB2b2lkIHtcclxuICAgICAgICBzZXJpZXMuZm9yRWFjaCgoc2VyaWVzT3B0aW9uOiBTZXJpZXNQaWVPcHRpb25zKSA9PiB7XHJcbiAgICAgICAgICAgIHNlcmllc09wdGlvbi5hbGxvd1BvaW50U2VsZWN0ID0gdHJ1ZTtcclxuICAgICAgICAgICAgc2VyaWVzT3B0aW9uLnNob3dJbkxlZ2VuZCA9IHRydWU7XHJcbiAgICAgICAgICAgIC8vIGlmICh0aGlzLmNoYXJ0VHlwZSA9PT0gQ2hhcnRUeXBlRW51bS5Eb251dCkge1xyXG4gICAgICAgICAgICAvLyAgICAgc2VyaWVzT3B0aW9uLmlubmVyU2l6ZSA9IEFzd0NoYXJ0Q29uc3RhbnRzLmlubmVyU2l6ZTtcclxuICAgICAgICAgICAgLy8gfVxyXG4gICAgICAgICAgICBpZiAodGhpcy5pc011dGUpIHtcclxuICAgICAgICAgICAgICAgIHNlcmllc09wdGlvbi5vcGFjaXR5ID0gMC4zNTtcclxuICAgICAgICAgICAgICAgIHNlcmllc09wdGlvbi5zdGF0ZXMgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaG92ZXI6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZW5hYmxlZDogZmFsc2VcclxuICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgICAgIGluYWN0aXZlOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVuYWJsZWQ6IGZhbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgIHNlcmllc09wdGlvbi5zbGljZWRPZmZzZXQgPSAwO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHNlcmllc09wdGlvbi5jdXJzb3IgPSBBc3dDaGFydENvbnN0YW50cy5wb2ludGVyO1xyXG4gICAgICAgICAgICBjb25zdCBkYXRhOiBQb2ludE9wdGlvbnNPYmplY3RbXSA9IHNlcmllc09wdGlvbi5kYXRhIGFzIFBvaW50T3B0aW9uc09iamVjdFtdO1xyXG4gICAgICAgICAgICB0aGlzLmhhbmRsZU5lZ2F0aXZlU2VyaWVzRGF0YShkYXRhKTtcclxuICAgICAgICAgICAgY29uc3Qgc29ydGVkU2VyaWVzT3B0aW9uRGF0YTogUG9pbnRPcHRpb25zT2JqZWN0W10gPSB0aGlzLmlzTGVnZW5kU29ydCA/IHRoaXMuc29ydFNlcmllc0RhdGEoZGF0YSkgOiBkYXRhO1xyXG4gICAgICAgICAgICBzZXJpZXNPcHRpb24uZGF0YSA9IHNvcnRlZFNlcmllc09wdGlvbkRhdGE7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBzb3J0U2VyaWVzRGF0YShkYXRhOiBQb2ludE9wdGlvbnNPYmplY3RbXSk6IFBvaW50T3B0aW9uc09iamVjdFtdIHtcclxuICAgICAgICAvLyBpZiAodGhpcy5sZWdlbmRUeXBlID09PSBMZWdlbmRUeXBlRW51bS5EZWZhdWx0KSB7XHJcbiAgICAgICAgLy8gICAgIGRhdGEuc29ydCgoYTogYW55LCBiOiBhbnkpID0+IHtcclxuICAgICAgICAvLyAgICAgICAgIHJldHVybiAoJycgKyBhLm5hbWUpLmxvY2FsZUNvbXBhcmUoYi5uYW1lKTtcclxuICAgICAgICAvLyAgICAgfSk7XHJcbiAgICAgICAgLy8gICAgIHJldHVybiBkYXRhO1xyXG4gICAgICAgIC8vIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGRhdGEuc29ydCgoYTogYW55LCBiOiBhbnkpID0+IHtcclxuICAgICAgICAgICAgICAgIGlmIChhLnkgJiYgYi55KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGEudmFsdWUgLSBiLnZhbHVlO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gMDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIGRhdGEucmV2ZXJzZSgpO1xyXG4gICAgICAgICAgICByZXR1cm4gZGF0YTtcclxuICAgICAgICAvLyB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBoYW5kbGVOZWdhdGl2ZVNlcmllc0RhdGEoZGF0YTogUG9pbnRPcHRpb25zT2JqZWN0W10pOiB2b2lkIHtcclxuICAgICAgICBkYXRhLmZvckVhY2goKGVsZW1lbnQ6IFBvaW50T3B0aW9uc09iamVjdCkgPT4ge1xyXG4gICAgICAgICAgICBlbGVtZW50LnZhbHVlID0gZWxlbWVudC55O1xyXG4gICAgICAgICAgICBlbGVtZW50LnkgPSBlbGVtZW50LnkgPyBNYXRoLmFicyhlbGVtZW50LnkpIDogMC4wMDE7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBzZXREb251dENoYXJ0TGVnZW5kT3B0aW9uKGxlZ2VuZFdpZHRoUHg6IG51bWJlcik6IHZvaWQge1xyXG4gICAgICAgIGNvbnN0IHRoaXMkOiB0aGlzID0gdGhpcztcclxuICAgICAgI