@alauda-fe/common
Version:
Alauda frontend team common codes.
250 lines • 34.9 kB
JavaScript
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output, } from '@angular/core';
import { arc } from 'd3';
import { NumericalLimitPipe } from '../numerical-limit.pipe';
import { measureText } from '../units';
import * as i0 from "@angular/core";
import * as i1 from "../numerical-limit.pipe";
const _c0 = (a0, a1) => ({ index: a0, arc: a1 });
function RadialBarChartComponent__svg_g_2__svg_text_3_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵnamespaceSVG();
i0.ɵɵelementStart(0, "text", 9);
i0.ɵɵpipe(1, "pure");
i0.ɵɵtext(2);
i0.ɵɵpipe(3, "translate");
i0.ɵɵpipe(4, "aclNumericalLimit");
i0.ɵɵpipe(5, "aclFieldNotAvailable");
i0.ɵɵelementEnd();
} if (rf & 2) {
const label_r1 = ctx.$implicit;
const labelIndex_r2 = ctx.index;
const arc_r3 = i0.ɵɵnextContext().$implicit;
const ctx_r3 = i0.ɵɵnextContext();
i0.ɵɵproperty("indicator", labelIndex_r2 || (arc_r3 == null ? null : arc_r3.hideIndicator) ? 0 : label_r1);
i0.ɵɵattribute("dx", i0.ɵɵpipeBind4(1, 5, arc_r3.labelCoord.dx, ctx_r3.getLabelDx, arc_r3.labels[labelIndex_r2 ? labelIndex_r2 - 1 : labelIndex_r2], labelIndex_r2))("dy", arc_r3.labelCoord.dy);
i0.ɵɵadvance(2);
i0.ɵɵtextInterpolate2(" ", labelIndex_r2 ? i0.ɵɵpipeBind1(3, 10, label_r1) : i0.ɵɵpipeBind1(5, 14, i0.ɵɵpipeBind1(4, 12, +label_r1)), "", labelIndex_r2 ? "" : "%", " ");
} }
function RadialBarChartComponent__svg_g_2_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵnamespaceSVG();
i0.ɵɵelementStart(0, "g");
i0.ɵɵelement(1, "path", 6)(2, "path", 7);
i0.ɵɵtemplate(3, RadialBarChartComponent__svg_g_2__svg_text_3_Template, 6, 16, "text", 8);
i0.ɵɵelementEnd();
} if (rf & 2) {
const arc_r3 = ctx.$implicit;
const i_r5 = ctx.index;
i0.ɵɵnextContext();
const tooltipTemplate_r6 = i0.ɵɵreference(13);
i0.ɵɵadvance();
i0.ɵɵproperty("auiTooltip", tooltipTemplate_r6)("auiTooltipContext", i0.ɵɵpureFunction2(12, _c0, i_r5, arc_r3));
i0.ɵɵattribute("d", arc_r3.backgroundArcPath);
i0.ɵɵadvance();
i0.ɵɵstyleProp("color", arc_r3.color)("opacity", arc_r3.fractionArcOpacity);
i0.ɵɵproperty("auiTooltip", tooltipTemplate_r6)("auiTooltipContext", i0.ɵɵpureFunction2(15, _c0, i_r5, arc_r3));
i0.ɵɵattribute("fill", arc_r3.color)("d", arc_r3.fractionArcPath);
i0.ɵɵadvance();
i0.ɵɵproperty("ngForOf", arc_r3.labels);
} }
function RadialBarChartComponent_div_11_div_1_Template(rf, ctx) { if (rf & 1) {
const _r7 = i0.ɵɵgetCurrentView();
i0.ɵɵelementStart(0, "div", 13);
i0.ɵɵelement(1, "aui-icon", 14);
i0.ɵɵtext(2);
i0.ɵɵpipe(3, "translate");
i0.ɵɵelementStart(4, "button", 15);
i0.ɵɵlistener("click", function RadialBarChartComponent_div_11_div_1_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r7); const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.onRefresh()); });
i0.ɵɵtext(5);
i0.ɵɵpipe(6, "translate");
i0.ɵɵelementEnd()();
} if (rf & 2) {
i0.ɵɵadvance(2);
i0.ɵɵtextInterpolate1(" ", i0.ɵɵpipeBind1(3, 2, "failed_load_please"), " ");
i0.ɵɵadvance(3);
i0.ɵɵtextInterpolate1(" ", i0.ɵɵpipeBind1(6, 4, "refresh"), " ");
} }
function RadialBarChartComponent_div_11_div_2_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementStart(0, "div", 16);
i0.ɵɵelement(1, "aui-icon", 17);
i0.ɵɵtext(2);
i0.ɵɵpipe(3, "translate");
i0.ɵɵelementEnd();
} if (rf & 2) {
i0.ɵɵadvance(2);
i0.ɵɵtextInterpolate1(" ", i0.ɵɵpipeBind1(3, 1, "loading"), " ");
} }
function RadialBarChartComponent_div_11_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementStart(0, "div", 10);
i0.ɵɵtemplate(1, RadialBarChartComponent_div_11_div_1_Template, 7, 6, "div", 11)(2, RadialBarChartComponent_div_11_div_2_Template, 4, 3, "div", 12);
i0.ɵɵelementEnd();
} if (rf & 2) {
const ctx_r3 = i0.ɵɵnextContext();
i0.ɵɵadvance();
i0.ɵɵproperty("ngIf", ctx_r3.failed && !ctx_r3.loading);
i0.ɵɵadvance();
i0.ɵɵproperty("ngIf", ctx_r3.loading);
} }
function RadialBarChartComponent_ng_template_12_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelement(0, "i", 18);
i0.ɵɵtext(1);
i0.ɵɵpipe(2, "translate");
i0.ɵɵpipe(3, "aclNumericalLimit");
i0.ɵɵpipe(4, "aclFieldNotAvailable");
i0.ɵɵpipe(5, "aclNumericalLimit");
i0.ɵɵpipe(6, "aclFieldNotAvailable");
i0.ɵɵpipe(7, "translate");
} if (rf & 2) {
const arc_r8 = ctx.arc;
const ctx_r3 = i0.ɵɵnextContext();
i0.ɵɵstyleProp("background", arc_r8.color);
i0.ɵɵadvance();
i0.ɵɵtextInterpolate4(" ", i0.ɵɵpipeBind1(2, 6, arc_r8.labels[1]), ": ", i0.ɵɵpipeBind1(4, 10, i0.ɵɵpipeBind1(3, 8, +arc_r8.labels[0])), "% (", i0.ɵɵpipeBind1(6, 14, i0.ɵɵpipeBind1(5, 12, +arc_r8.value)), " ", i0.ɵɵpipeBind1(7, 16, ctx_r3.unit), ")\n");
} }
const MAX_VALUE = 999_999;
const DECIMAL_MAX_VALUE = 999.99;
export class RadialBarChartComponent {
ngOnChanges() {
this.arcs = this.getArcs();
}
get transform() {
return `translate(${(this.size + this.offset) / 2}, ${this.size / 2})`;
}
get outerRadius() {
return this.size / 2 - this.margin;
}
get innerRadius() {
return this.outerRadius - this.pieSize;
}
arcTrackByFn(index) {
return index;
}
constructor(numericalLimitPipe) {
this.numericalLimitPipe = numericalLimitPipe;
this.refresh = new EventEmitter();
this.size = 160;
this.offset = 120;
this.pieSize = 10;
this.margin = 5;
this.innerShrink = 15;
this.maxValue = MAX_VALUE;
this.decimalMaxValue = DECIMAL_MAX_VALUE;
this.getArc = (level, fraction, label, opacity, value, hideIndicator = false, color = this.color) => {
fraction = fraction || 0;
return {
backgroundArcPath: this.getBackgroundArcPath(level),
fractionArcPath: this.getFractionArcPath(fraction || 0, level),
labels: [fraction ? '' + fraction : null, label],
labelCoord: this.getTextCoord(level),
fractionArcOpacity: opacity,
fraction,
color,
value,
hideIndicator,
};
};
this.getLabelDx = (x, text, index) => {
return index
? x - (measureText(this.numericalLimitPipe.transform(+text)).width + 20)
: x;
};
}
getArcs() {
let arcs = [];
const limitsArc = this.getArc(0, this.requestsFraction, 'request_rate', 1, this.request);
const requestsArc = this.getArc(1, this.limitsFraction, 'usage_rate', 0.7, this.usage);
arcs = [requestsArc, limitsArc];
if (this.data) {
arcs = this.handelData();
}
return arcs;
}
handelData() {
return this.data.map((item, index) => this.getArc(index, item.fraction, item.title, item.color ? 1 : +(1 / (index + 1)).toFixed(2), item.value, item.hideIndicator, item.color));
}
getBackgroundArcPath(level = 0) {
const shrink = level * this.innerShrink;
return arc().cornerRadius(20)({
startAngle: 0,
endAngle: Math.PI * 1.5,
innerRadius: this.innerRadius - shrink,
outerRadius: this.outerRadius - shrink,
});
}
onRefresh() {
this.refresh.next(null);
}
getFractionArcPath(fraction, level = 0) {
const shrink = level * this.innerShrink;
fraction = Math.min(100, fraction);
return arc().cornerRadius(20)({
startAngle: 0,
endAngle: (Math.PI * 1.5 * fraction) / 100,
innerRadius: this.innerRadius - shrink,
outerRadius: this.outerRadius - shrink,
});
}
getTextCoord(level = 0) {
const shrink = level * this.innerShrink;
return {
dx: -4,
dy: -(this.outerRadius - shrink - 5),
};
}
static { this.ɵfac = function RadialBarChartComponent_Factory(t) { return new (t || RadialBarChartComponent)(i0.ɵɵdirectiveInject(i1.NumericalLimitPipe)); }; }
static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: RadialBarChartComponent, selectors: [["acl-radial-bar-chart"]], inputs: { limitsFraction: "limitsFraction", requestsFraction: "requestsFraction", capacity: "capacity", data: "data", unit: "unit", color: "color", usage: "usage", request: "request", loading: "loading", failed: "failed" }, outputs: { refresh: "refresh" }, features: [i0.ɵɵProvidersFeature([NumericalLimitPipe]), i0.ɵɵNgOnChangesFeature], decls: 14, vars: 16, consts: [["tooltipTemplate", ""], [4, "ngFor", "ngForOf", "ngForTrackBy"], ["dy", "-5", 1, "center-text"], ["text-anchor", "middle", 1, "center-text__main"], ["text-anchor", "middle", "dy", "20", 1, "center-text__sub"], ["class", "status-container", 4, "ngIf"], [1, "full-arc-path", 3, "auiTooltip", "auiTooltipContext"], ["nodeName", "", 1, "fraction-arc-path", 3, "auiTooltip", "auiTooltipContext"], ["class", "fraction-label-text", "text-anchor", "end", "aclIndicatorColor", "", 3, "indicator", 4, "ngFor", "ngForOf"], ["text-anchor", "end", "aclIndicatorColor", "", 1, "fraction-label-text", 3, "indicator"], [1, "status-container"], ["class", "status failed", 4, "ngIf"], ["class", "status loading", 4, "ngIf"], [1, "status", "failed"], ["icon", "exclamation_triangle_s", "background", "triangle"], ["aui-button", "text", 3, "click"], [1, "status", "loading"], ["icon", "spinner"], [1, "dot"]], template: function RadialBarChartComponent_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵnamespaceSVG();
i0.ɵɵelementStart(0, "svg")(1, "g");
i0.ɵɵtemplate(2, RadialBarChartComponent__svg_g_2_Template, 4, 18, "g", 1);
i0.ɵɵelementStart(3, "g", 2)(4, "text", 3);
i0.ɵɵtext(5);
i0.ɵɵpipe(6, "aclNumericalLimit");
i0.ɵɵpipe(7, "aclFieldNotAvailable");
i0.ɵɵelementEnd();
i0.ɵɵelementStart(8, "text", 4);
i0.ɵɵtext(9);
i0.ɵɵpipe(10, "translate");
i0.ɵɵelementEnd()()()();
i0.ɵɵtemplate(11, RadialBarChartComponent_div_11_Template, 3, 2, "div", 5)(12, RadialBarChartComponent_ng_template_12_Template, 8, 18, "ng-template", null, 0, i0.ɵɵtemplateRefExtractor);
} if (rf & 2) {
i0.ɵɵattribute("width", ctx.size + ctx.offset)("height", ctx.size);
i0.ɵɵadvance();
i0.ɵɵattribute("transform", ctx.transform);
i0.ɵɵadvance();
i0.ɵɵproperty("ngForOf", ctx.arcs)("ngForTrackBy", ctx.arcTrackByFn);
i0.ɵɵadvance(2);
i0.ɵɵstyleProp("font-size", ctx.capacity > 9999 || (ctx.arcs == null ? null : ctx.arcs.length) > 2 ? "16px" : "24px");
i0.ɵɵadvance();
i0.ɵɵtextInterpolate1(" ", i0.ɵɵpipeBind1(7, 12, i0.ɵɵpipeBind1(6, 10, +ctx.capacity)), " ");
i0.ɵɵadvance(4);
i0.ɵɵtextInterpolate1(" ", i0.ɵɵpipeBind1(10, 14, "total_number"), " ");
i0.ɵɵadvance(2);
i0.ɵɵproperty("ngIf", ctx.loading || ctx.failed);
} }, styles: ["[_nghost-%COMP%]{position:relative}text[_ngcontent-%COMP%]{dominant-baseline:middle}.center-text__main[_ngcontent-%COMP%]{font-size:24px;font-weight:500;fill:rgb(var(--aui-color-main-text))}.center-text__sub[_ngcontent-%COMP%]{font-size:12px;fill:rgb(var(--aui-color-secondary-text))}.full-arc-path[_ngcontent-%COMP%]{fill:rgb(var(--aui-color-n-8))}.fraction-arc-path[_ngcontent-%COMP%]{cursor:pointer}.fraction-arc-path[_ngcontent-%COMP%]:hover{stroke:currentcolor;stroke-width:2px}.fraction-label-text[_ngcontent-%COMP%]{font-size:12px;fill:rgb(var(--aui-color-secondary-text))}.total-text[_ngcontent-%COMP%]{font-size:20px;font-weight:500}.dot[_ngcontent-%COMP%]{width:6px;height:6px;display:inline-block;border-radius:50%;margin-right:5px}.status-container[_ngcontent-%COMP%]{left:50%;position:absolute;top:50%;white-space:nowrap;transform:translate(-50%,-50%)}.status[_ngcontent-%COMP%]{padding:6px 16px;display:flex;align-items:center;justify-content:center;background-color:rgb(var(--aui-color-n-8));color:rgb(var(--aui-color-n-4));border-radius:2px}.status[_ngcontent-%COMP%] aui-icon[_ngcontent-%COMP%]{font-size:14px;margin-right:4px}.loading[_ngcontent-%COMP%] aui-icon[_ngcontent-%COMP%]{color:rgb(var(--aui-color-primary))}.failed[_ngcontent-%COMP%] aui-icon[_ngcontent-%COMP%]{color:rgb(var(--aui-color-red))}.hide[_ngcontent-%COMP%]{display:none}"], changeDetection: 0 }); }
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(RadialBarChartComponent, [{
type: Component,
args: [{ selector: 'acl-radial-bar-chart', changeDetection: ChangeDetectionStrategy.OnPush, providers: [NumericalLimitPipe], template: "<svg\n [attr.width]=\"size + offset\"\n [attr.height]=\"size\"\n>\n <svg:g [attr.transform]=\"transform\">\n <svg:g *ngFor=\"let arc of arcs; trackBy: arcTrackByFn; index as i\">\n <svg:path\n class=\"full-arc-path\"\n [auiTooltip]=\"tooltipTemplate\"\n [auiTooltipContext]=\"{ index: i, arc: arc }\"\n [attr.d]=\"arc.backgroundArcPath\"\n ></svg:path>\n <svg:path\n [style.color]=\"arc.color\"\n [auiTooltip]=\"tooltipTemplate\"\n [auiTooltipContext]=\"{ index: i, arc: arc }\"\n class=\"fraction-arc-path\"\n [attr.fill]=\"arc.color\"\n [style.opacity]=\"arc.fractionArcOpacity\"\n [attr.d]=\"arc.fractionArcPath\"\n nodeName\n ></svg:path>\n <svg:text\n *ngFor=\"let label of arc.labels; index as labelIndex\"\n class=\"fraction-label-text\"\n [attr.dx]=\"\n arc.labelCoord.dx\n | pure\n : getLabelDx\n : $any(arc.labels[labelIndex ? labelIndex - 1 : labelIndex])\n : labelIndex\n \"\n [attr.dy]=\"arc.labelCoord.dy\"\n text-anchor=\"end\"\n aclIndicatorColor\n [indicator]=\"labelIndex || arc?.hideIndicator ? 0 : label\"\n >\n {{\n labelIndex\n ? (label | translate)\n : (+label | aclNumericalLimit | aclFieldNotAvailable)\n }}{{ labelIndex ? '' : '%' }}\n </svg:text>\n </svg:g>\n\n <svg:g\n class=\"center-text\"\n dy=\"-5\"\n >\n <svg:text\n [style.font-size]=\"\n capacity > 9999 || arcs?.length > 2 ? '16px' : '24px'\n \"\n text-anchor=\"middle\"\n class=\"center-text__main\"\n >\n {{ +capacity | aclNumericalLimit | aclFieldNotAvailable }}\n </svg:text>\n <svg:text\n text-anchor=\"middle\"\n dy=\"20\"\n class=\"center-text__sub\"\n >\n {{ 'total_number' | translate }}\n </svg:text>\n </svg:g>\n </svg:g>\n</svg>\n\n<div\n class=\"status-container\"\n *ngIf=\"loading || failed\"\n>\n <div\n *ngIf=\"failed && !loading\"\n class=\"status failed\"\n >\n <aui-icon\n icon=\"exclamation_triangle_s\"\n background=\"triangle\"\n ></aui-icon>\n {{ 'failed_load_please' | translate }}\n <button\n aui-button=\"text\"\n (click)=\"onRefresh()\"\n >\n {{ 'refresh' | translate }}\n </button>\n </div>\n <div\n *ngIf=\"loading\"\n class=\"status loading\"\n >\n <aui-icon icon=\"spinner\"></aui-icon> {{ 'loading' | translate }}\n </div>\n</div>\n\n<ng-template\n #tooltipTemplate\n let-index=\"index\"\n let-arc=\"arc\"\n>\n <i\n class=\"dot\"\n [style.background]=\"arc.color\"\n ></i>\n {{ arc.labels[1] | translate }}:\n {{ +arc.labels[0] | aclNumericalLimit | aclFieldNotAvailable }}% ({{\n +arc.value | aclNumericalLimit | aclFieldNotAvailable\n }}\n {{ unit | translate }})\n</ng-template>\n", styles: [":host{position:relative}text{dominant-baseline:middle}.center-text__main{font-size:24px;font-weight:500;fill:rgb(var(--aui-color-main-text))}.center-text__sub{font-size:12px;fill:rgb(var(--aui-color-secondary-text))}.full-arc-path{fill:rgb(var(--aui-color-n-8))}.fraction-arc-path{cursor:pointer}.fraction-arc-path:hover{stroke:currentcolor;stroke-width:2px}.fraction-label-text{font-size:12px;fill:rgb(var(--aui-color-secondary-text))}.total-text{font-size:20px;font-weight:500}.dot{width:6px;height:6px;display:inline-block;border-radius:50%;margin-right:5px}.status-container{left:50%;position:absolute;top:50%;white-space:nowrap;transform:translate(-50%,-50%)}.status{padding:6px 16px;display:flex;align-items:center;justify-content:center;background-color:rgb(var(--aui-color-n-8));color:rgb(var(--aui-color-n-4));border-radius:2px}.status aui-icon{font-size:14px;margin-right:4px}.loading aui-icon{color:rgb(var(--aui-color-primary))}.failed aui-icon{color:rgb(var(--aui-color-red))}.hide{display:none}\n"] }]
}], () => [{ type: i1.NumericalLimitPipe }], { limitsFraction: [{
type: Input
}], requestsFraction: [{
type: Input
}], capacity: [{
type: Input
}], data: [{
type: Input
}], unit: [{
type: Input
}], color: [{
type: Input
}], usage: [{
type: Input
}], request: [{
type: Input
}], loading: [{
type: Input
}], failed: [{
type: Input
}], refresh: [{
type: Output
}] }); })();
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(RadialBarChartComponent, { className: "RadialBarChartComponent" }); })();
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmFkaWFsLWJhci1jaGFydC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9saWJzL2NvbW1vbi9zcmMvcGllLWRlcml2YXRpdmUtY2hhcnQvcmFkaWFsLWJhci9yYWRpYWwtYmFyLWNoYXJ0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvY29tbW9uL3NyYy9waWUtZGVyaXZhdGl2ZS1jaGFydC9yYWRpYWwtYmFyL3JhZGlhbC1iYXItY2hhcnQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixTQUFTLEVBQ1QsWUFBWSxFQUNaLEtBQUssRUFFTCxNQUFNLEdBQ1AsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLElBQUksQ0FBQztBQUV6QixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUM3RCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sVUFBVSxDQUFDOzs7Ozs7SUNXakMsK0JBY0M7O0lBQ0MsWUFLRjs7OztJQUFBLGlCQUFXOzs7Ozs7SUFQVCwwR0FBMEQ7O0lBRTFELGVBS0Y7SUFMRSx3S0FLRjs7OztJQXJDRix5QkFBbUU7SUFPakUsQUFOQSwwQkFLWSxjQVVBO0lBQ1oseUZBY0M7SUFPSCxpQkFBUTs7Ozs7O0lBbkNKLGNBQThCO0lBQzlCLEFBREEsK0NBQThCLGdFQUNjOztJQUk1QyxjQUF5QjtJQUt6QixBQUxBLHFDQUF5QixzQ0FLZTtJQUh4QyxBQURBLCtDQUE4QixnRUFDYzs7SUFRMUIsY0FBZTtJQUFmLHVDQUFlOzs7O0lBa0R2QywrQkFHQztJQUNDLCtCQUdZO0lBQ1osWUFDQTs7SUFBQSxrQ0FHQztJQURDLDJMQUFTLGtCQUFXLEtBQUM7SUFFckIsWUFDRjs7SUFDRixBQURFLGlCQUFTLEVBQ0w7O0lBUEosZUFDQTtJQURBLDJF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O0lBQ0osQ0FBQzt3RkFuS1UsdUJBQXVCO29FQUF2Qix1QkFBdUIsMlVBRnZCLENBQUMsa0JBQWtCLENBQUM7O1lDOUIvQixBQUpGLDJCQUdDLFFBQ3FDO1lBQ2xDLDBFQUFtRTtZQTRDakUsQUFKRiw0QkFHQyxjQU9FO1lBQ0MsWUFDRjs7O1lBQUEsaUJBQVc7WUFDWCwrQkFJQztZQUNDLFlBQ0Y7O1lBR04sQUFERSxBQURFLEFBREUsaUJBQVcsRUFDTCxFQUNGLEVBQ0o7WUE4Qk4sQUE1QkEsMEVBR0MsK0dBNkJBOzs7WUFqR1EsY0FBNEI7O1lBQ1YsY0FBUztZQUFBLEFBQVQsa0NBQVMsa0NBQXVCO1lBNkNuRCxlQUVDO1lBRkQscUhBRUM7WUFJRCxjQUNGO1lBREUsNEZBQ0Y7WUFNRSxlQUNGO1lBREUsdUVBQ0Y7WUFPSCxlQUF1QjtZQUF2QixnREFBdUI7OztpRkRuQ2IsdUJBQXVCO2NBUG5DLFNBQVM7MkJBQ0Usc0JBQXNCLG1CQUdmLHVCQUF1QixDQUFDLE1BQU0sYUFDcEMsQ0FBQyxrQkFBa0IsQ0FBQzttREFJL0IsY0FBYztrQkFEYixLQUFLO1lBSU4sZ0JBQWdCO2tCQURmLEtBQUs7WUFJTixRQUFRO2tCQURQLEtBQUs7WUFJTixJQUFJO2tCQURILEtBQUs7WUFTRyxJQUFJO2tCQUFaLEtBQUs7WUFFRyxLQUFLO2tCQUFiLEtBQUs7WUFFRyxLQUFLO2tCQUFiLEtBQUs7WUFFRyxPQUFPO2tCQUFmLEtBQUs7WUFFRyxPQUFPO2tCQUFmLEtBQUs7WUFFRyxNQUFNO2tCQUFkLEtBQUs7WUFFSSxPQUFPO2tCQUFoQixNQUFNOztrRkEvQkksdUJBQXVCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENvbXBvbmVudCxcbiAgRXZlbnRFbWl0dGVyLFxuICBJbnB1dCxcbiAgT25DaGFuZ2VzLFxuICBPdXRwdXQsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgYXJjIH0gZnJvbSAnZDMnO1xuXG5pbXBvcnQgeyBOdW1lcmljYWxMaW1pdFBpcGUgfSBmcm9tICcuLi9udW1lcmljYWwtbGltaXQucGlwZSc7XG5pbXBvcnQgeyBtZWFzdXJlVGV4dCB9IGZyb20gJy4uL3VuaXRzJztcblxuY29uc3QgTUFYX1ZBTFVFID0gOTk5Xzk5OTtcblxuY29uc3QgREVDSU1BTF9NQVhfVkFMVUUgPSA5OTkuOTk7XG5cbmludGVyZmFjZSBOb2RlRnJhY3Rpb25BcmMge1xuICBiYWNrZ3JvdW5kQXJjUGF0aDogYW55O1xuICBmcmFjdGlvbkFyY1BhdGg6IGFueTtcbiAgbGFiZWxzOiBzdHJpbmdbXTtcbiAgbGFiZWxDb29yZDogYW55O1xuICBmcmFjdGlvbkFyY09wYWNpdHk6IG51bWJlcjtcbiAgZnJhY3Rpb246IGFueTtcbiAgY29sb3I6IHN0cmluZztcbiAgdmFsdWU6IHN0cmluZztcbiAgaGlkZUluZGljYXRvcj86IGJvb2xlYW47XG59XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2FjbC1yYWRpYWwtYmFyLWNoYXJ0JyxcbiAgdGVtcGxhdGVVcmw6ICcuL3JhZGlhbC1iYXItY2hhcnQuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9yYWRpYWwtYmFyLWNoYXJ0LmNvbXBvbmVudC5zY3NzJ10sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBwcm92aWRlcnM6IFtOdW1lcmljYWxMaW1pdFBpcGVdLFxufSlcbmV4cG9ydCBjbGFzcyBSYWRpYWxCYXJDaGFydENvbXBvbmVudCBpbXBsZW1lbnRzIE9uQ2hhbmdlcyB7XG4gIEBJbnB1dCgpXG4gIGxpbWl0c0ZyYWN0aW9uOiBudW1iZXI7XG5cbiAgQElucHV0KClcbiAgcmVxdWVzdHNGcmFjdGlvbjogbnVtYmVyO1xuXG4gIEBJbnB1dCgpXG4gIGNhcGFjaXR5OiBudW1iZXI7XG5cbiAgQElucHV0KClcbiAgZGF0YTogQXJyYXk8e1xuICAgIHRpdGxlOiBzdHJpbmc7XG4gICAgdmFsdWU6IHN0cmluZztcbiAgICBmcmFjdGlvbjogbnVtYmVyO1xuICAgIGhpZGVJbmRpY2F0b3I6IGJvb2xlYW47XG4gICAgY29sb3I/OiBzdHJpbmc7XG4gIH0+O1xuXG4gIEBJbnB1dCgpIHVuaXQ6IHN0cmluZztcblxuICBASW5wdXQoKSBjb2xvcjogc3RyaW5nO1xuXG4gIEBJbnB1dCgpIHVzYWdlOiBzdHJpbmc7XG5cbiAgQElucHV0KCkgcmVxdWVzdDogc3RyaW5nO1xuXG4gIEBJbnB1dCgpIGxvYWRpbmc6IGJvb2xlYW47XG5cbiAgQElucHV0KCkgZmFpbGVkOiBib29sZWFuO1xuXG4gIEBPdXRwdXQoKSByZWZyZXNoID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gIHJlYWRvbmx5IHNpemUgPSAxNjA7XG5cbiAgcmVhZG9ubHkgb2Zmc2V0ID0gMTIwO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgcGllU2l6ZSA9IDEwO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgbWFyZ2luID0gNTtcblxuICBwcml2YXRlIHJlYWRvbmx5IGlubmVyU2hyaW5rID0gMTU7XG5cbiAgcmVhZG9ubHkgbWF4VmFsdWUgPSBNQVhfVkFMVUU7XG5cbiAgcmVhZG9ubHkgZGVjaW1hbE1heFZhbHVlID0gREVDSU1BTF9NQVhfVkFMVUU7XG5cbiAgYXJjczogTm9kZUZyYWN0aW9uQXJjW107XG5cbiAgbmdPbkNoYW5nZXMoKTogdm9pZCB7XG4gICAgdGhpcy5hcmNzID0gdGhpcy5nZXRBcmNzKCk7XG4gIH1cblxuICBnZXQgdHJhbnNmb3JtKCkge1xuICAgIHJldHVybiBgdHJhbnNsYXRlKCR7KHRoaXMuc2l6ZSArIHRoaXMub2Zmc2V0KSAvIDJ9LCAke3RoaXMuc2l6ZSAvIDJ9KWA7XG4gIH1cblxuICBnZXQgb3V0ZXJSYWRpdXMoKSB7XG4gICAgcmV0dXJuIHRoaXMuc2l6ZSAvIDIgLSB0aGlzLm1hcmdpbjtcbiAgfVxuXG4gIGdldCBpbm5lclJhZGl1cygpIHtcbiAgICByZXR1cm4gdGhpcy5vdXRlclJhZGl1cyAtIHRoaXMucGllU2l6ZTtcbiAgfVxuXG4gIGFyY1RyYWNrQnlGbihpbmRleDogbnVtYmVyKSB7XG4gICAgcmV0dXJuIGluZGV4O1xuICB9XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBudW1lcmljYWxMaW1pdFBpcGU6IE51bWVyaWNhbExpbWl0UGlwZSkge31cblxuICBwcml2YXRlIGdldEFyY3MoKTogTm9kZUZyYWN0aW9uQXJjW10ge1xuICAgIGxldCBhcmNzOiBOb2RlRnJhY3Rpb25BcmNbXSA9IFtdO1xuICAgIGNvbnN0IGxpbWl0c0FyYyA9IHRoaXMuZ2V0QXJjKFxuICAgICAgMCxcbiAgICAgIHRoaXMucmVxdWVzdHNGcmFjdGlvbixcbiAgICAgICdyZXF1ZXN0X3JhdGUnLFxuICAgICAgMSxcbiAgICAgIHRoaXMucmVxdWVzdCxcbiAgICApO1xuICAgIGNvbnN0IHJlcXVlc3RzQXJjID0gdGhpcy5nZXRBcmMoXG4gICAgICAxLFxuICAgICAgdGhpcy5saW1pdHNGcmFjdGlvbixcbiAgICAgICd1c2FnZV9yYXRlJyxcbiAgICAgIDAuNyxcbiAgICAgIHRoaXMudXNhZ2UsXG4gICAgKTtcbiAgICBhcmNzID0gW3JlcXVlc3RzQXJjLCBsaW1pdHNBcmNdO1xuXG4gICAgaWYgKHRoaXMuZGF0YSkge1xuICAgICAgYXJjcyA9IHRoaXMuaGFuZGVsRGF0YSgpO1xuICAgIH1cbiAgICByZXR1cm4gYXJjcztcbiAgfVxuXG4gIGdldEFyYyA9IChcbiAgICBsZXZlbDogbnVtYmVyLFxuICAgIGZyYWN0aW9uOiBudW1iZXIsXG4gICAgbGFiZWw6IHN0cmluZyxcbiAgICBvcGFjaXR5OiBudW1iZXIsXG4gICAgdmFsdWU6IHN0cmluZyxcbiAgICBoaWRlSW5kaWNhdG9yID0gZmFsc2UsXG4gICAgY29sb3IgPSB0aGlzLmNvbG9yLFxuICApOiBOb2RlRnJhY3Rpb25BcmMgPT4ge1xuICAgIGZyYWN0aW9uID0gZnJhY3Rpb24gfHwgMDtcbiAgICByZXR1cm4ge1xuICAgICAgYmFja2dyb3VuZEFyY1BhdGg6IHRoaXMuZ2V0QmFja2dyb3VuZEFyY1BhdGgobGV2ZWwpLFxuICAgICAgZnJhY3Rpb25BcmNQYXRoOiB0aGlzLmdldEZyYWN0aW9uQXJjUGF0aChmcmFjdGlvbiB8fCAwLCBsZXZlbCksXG4gICAgICBsYWJlbHM6IFtmcmFjdGlvbiA/ICcnICsgZnJhY3Rpb24gOiBudWxsLCBsYWJlbF0sXG4gICAgICBsYWJlbENvb3JkOiB0aGlzLmdldFRleHRDb29yZChsZXZlbCksXG4gICAgICBmcmFjdGlvbkFyY09wYWNpdHk6IG9wYWNpdHksXG4gICAgICBmcmFjdGlvbixcbiAgICAgIGNvbG9yLFxuICAgICAgdmFsdWUsXG4gICAgICBoaWRlSW5kaWNhdG9yLFxuICAgIH07XG4gIH07XG5cbiAgaGFuZGVsRGF0YSgpIHtcbiAgICByZXR1cm4gdGhpcy5kYXRhLm1hcCgoaXRlbSwgaW5kZXgpID0+XG4gICAgICB0aGlzLmdldEFyYyhcbiAgICAgICAgaW5kZXgsXG4gICAgICAgIGl0ZW0uZnJhY3Rpb24sXG4gICAgICAgIGl0ZW0udGl0bGUsXG4gICAgICAgIGl0ZW0uY29sb3IgPyAxIDogKygxIC8gKGluZGV4ICsgMSkpLnRvRml4ZWQoMiksXG4gICAgICAgIGl0ZW0udmFsdWUsXG4gICAgICAgIGl0ZW0uaGlkZUluZGljYXRvcixcbiAgICAgICAgaXRlbS5jb2xvcixcbiAgICAgICksXG4gICAgKTtcbiAgfVxuXG4gIGdldEJhY2tncm91bmRBcmNQYXRoKGxldmVsID0gMCkge1xuICAgIGNvbnN0IHNocmluayA9IGxldmVsICogdGhpcy5pbm5lclNocmluaztcbiAgICByZXR1cm4gYXJjKCkuY29ybmVyUmFkaXVzKDIwKSh7XG4gICAgICBzdGFydEFuZ2xlOiAwLFxuICAgICAgZW5kQW5nbGU6IE1hdGguUEkgKiAxLjUsXG4gICAgICBpbm5lclJhZGl1czogdGhpcy5pbm5lclJhZGl1cyAtIHNocmluayxcbiAgICAgIG91dGVyUmFkaXVzOiB0aGlzLm91dGVyUmFkaXVzIC0gc2hyaW5rLFxuICAgIH0pO1xuICB9XG5cbiAgb25SZWZyZXNoKCkge1xuICAgIHRoaXMucmVmcmVzaC5uZXh0KG51bGwpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRGcmFjdGlvbkFyY1BhdGgoZnJhY3Rpb246IG51bWJlciwgbGV2ZWwgPSAwKSB7XG4gICAgY29uc3Qgc2hyaW5rID0gbGV2ZWwgKiB0aGlzLmlubmVyU2hyaW5rO1xuICAgIGZyYWN0aW9uID0gTWF0aC5taW4oMTAwLCBmcmFjdGlvbik7XG4gICAgcmV0dXJuIGFyYygpLmNvcm5lclJhZGl1cygyMCkoe1xuICAgICAgc3RhcnRBbmdsZTogMCxcbiAgICAgIGVuZEFuZ2xlOiAoTWF0aC5QSSAqIDEuNSAqIGZyYWN0aW9uKSAvIDEwMCxcbiAgICAgIGlubmVyUmFkaXVzOiB0aGlzLmlubmVyUmFkaXVzIC0gc2hyaW5rLFxuICAgICAgb3V0ZXJSYWRpdXM6IHRoaXMub3V0ZXJSYWRpdXMgLSBzaHJpbmssXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGdldFRleHRDb29yZChsZXZlbCA9IDApOiB7IGR4OiBudW1iZXI7IGR5OiBudW1iZXIgfSB7XG4gICAgY29uc3Qgc2hyaW5rID0gbGV2ZWwgKiB0aGlzLmlubmVyU2hyaW5rO1xuICAgIHJldHVybiB7XG4gICAgICBkeDogLTQsXG4gICAgICBkeTogLSh0aGlzLm91dGVyUmFkaXVzIC0gc2hyaW5rIC0gNSksXG4gICAgfTtcbiAgfVxuXG4gIGdldExhYmVsRHggPSAoeDogbnVtYmVyLCB0ZXh0OiBudW1iZXIsIGluZGV4OiBudW1iZXIpID0+IHtcbiAgICByZXR1cm4gaW5kZXhcbiAgICAgID8geCAtIChtZWFzdXJlVGV4dCh0aGlzLm51bWVyaWNhbExpbWl0UGlwZS50cmFuc2Zvcm0oK3RleHQpKS53aWR0aCArIDIwKVxuICAgICAgOiB4O1xuICB9O1xufVxuIiwiPHN2Z1xuICBbYXR0ci53aWR0aF09XCJzaXplICsgb2Zmc2V0XCJcbiAgW2F0dHIuaGVpZ2h0XT1cInNpemVcIlxuPlxuICA8c3ZnOmcgW2F0dHIudHJhbnNmb3JtXT1cInRyYW5zZm9ybVwiPlxuICAgIDxzdmc6ZyAqbmdGb3I9XCJsZXQgYXJjIG9mIGFyY3M7IHRyYWNrQnk6IGFyY1RyYWNrQnlGbjsgaW5kZXggYXMgaVwiPlxuICAgICAgPHN2ZzpwYXRoXG4gICAgICAgIGNsYXNzPVwiZnVsbC1hcmMtcGF0aFwiXG4gICAgICAgIFthdWlUb29sdGlwXT1cInRvb2x0aXBUZW1wbGF0ZVwiXG4gICAgICAgIFthdWlUb29sdGlwQ29udGV4dF09XCJ7IGluZGV4OiBpLCBhcmM6IGFyYyB9XCJcbiAgICAgICAgW2F0dHIuZF09XCJhcmMuYmFja2dyb3VuZEFyY1BhdGhcIlxuICAgICAgPjwvc3ZnOnBhdGg+XG4gICAgICA8c3ZnOnBhdGhcbiAgICAgICAgW3N0eWxlLmNvbG9yXT1cImFyYy5jb2xvclwiXG4gICAgICAgIFthdWlUb29sdGlwXT1cInRvb2x0aXBUZW1wbGF0ZVwiXG4gICAgICAgIFthdWlUb29sdGlwQ29udGV4dF09XCJ7IGluZGV4OiBpLCBhcmM6IGFyYyB9XCJcbiAgICAgICAgY2xhc3M9XCJmcmFjdGlvbi1hcmMtcGF0aFwiXG4gICAgICAgIFthdHRyLmZpbGxdPVwiYXJjLmNvbG9yXCJcbiAgICAgICAgW3N0eWxlLm9wYWNpdHldPVwiYXJjLmZyYWN0aW9uQXJjT3BhY2l0eVwiXG4gICAgICAgIFthdHRyLmRdPVwiYXJjLmZyYWN0aW9uQXJjUGF0aFwiXG4gICAgICAgIG5vZGVOYW1lXG4gICAgICA+PC9zdmc6cGF0aD5cbiAgICAgIDxzdmc6dGV4dFxuICAgICAgICAqbmdGb3I9XCJsZXQgbGFiZWwgb2YgYXJjLmxhYmVsczsgaW5kZXggYXMgbGFiZWxJbmRleFwiXG4gICAgICAgIGNsYXNzPVwiZnJhY3Rpb24tbGFiZWwtdGV4dFwiXG4gICAgICAgIFthdHRyLmR4XT1cIlxuICAgICAgICAgIGFyYy5sYWJlbENvb3JkLmR4XG4gICAgICAgICAgICB8IHB1cmVcbiAgICAgICAgICAgICAgOiBnZXRMYWJlbER4XG4gICAgICAgICAgICAgIDogJGFueShhcmMubGFiZWxzW2xhYmVsSW5kZXggPyBsYWJlbEluZGV4IC0gMSA6IGxhYmVsSW5kZXhdKVxuICAgICAgICAgICAgICA6IGxhYmVsSW5kZXhcbiAgICAgICAgXCJcbiAgICAgICAgW2F0dHIuZHldPVwiYXJjLmxhYmVsQ29vcmQuZHlcIlxuICAgICAgICB0ZXh0LWFuY2hvcj1cImVuZFwiXG4gICAgICAgIGFjbEluZGljYXRvckNvbG9yXG4gICAgICAgIFtpbmRpY2F0b3JdPVwibGFiZWxJbmRleCB8fCBhcmM/LmhpZGVJbmRpY2F0b3IgPyAwIDogbGFiZWxcIlxuICAgICAgPlxuICAgICAgICB7e1xuICAgICAgICAgIGxhYmVsSW5kZXhcbiAgICAgICAgICAgID8gKGxhYmVsIHwgdHJhbnNsYXRlKVxuICAgICAgICAgICAgOiAoK2xhYmVsIHwgYWNsTnVtZXJpY2FsTGltaXQgfCBhY2xGaWVsZE5vdEF2YWlsYWJsZSlcbiAgICAgICAgfX17eyBsYWJlbEluZGV4ID8gJycgOiAnJScgfX1cbiAgICAgIDwvc3ZnOnRleHQ+XG4gICAgPC9zdmc6Zz5cblxuICAgIDxzdmc6Z1xuICAgICAgY2xhc3M9XCJjZW50ZXItdGV4dFwiXG4gICAgICBkeT1cIi01XCJcbiAgICA+XG4gICAgICA8c3ZnOnRleHRcbiAgICAgICAgW3N0eWxlLmZvbnQtc2l6ZV09XCJcbiAgICAgICAgICBjYXBhY2l0eSA+IDk5OTkgfHwgYXJjcz8ubGVuZ3RoID4gMiA/ICcxNnB4JyA6ICcyNHB4J1xuICAgICAgICBcIlxuICAgICAgICB0ZXh0LWFuY2hvcj1cIm1pZGRsZVwiXG4gICAgICAgIGNsYXNzPVwiY2VudGVyLXRleHRfX21haW5cIlxuICAgICAgPlxuICAgICAgICB7eyArY2FwYWNpdHkgfCBhY2xOdW1lcmljYWxMaW1pdCB8IGFjbEZpZWxkTm90QXZhaWxhYmxlIH19XG4gICAgICA8L3N2Zzp0ZXh0PlxuICAgICAgPHN2Zzp0ZXh0XG4gICAgICAgIHRleHQtYW5jaG9yPVwibWlkZGxlXCJcbiAgICAgICAgZHk9XCIyMFwiXG4gICAgICAgIGNsYXNzPVwiY2VudGVyLXRleHRfX3N1YlwiXG4gICAgICA+XG4gICAgICAgIHt7ICd0b3RhbF9udW1iZXInIHwgdHJhbnNsYXRlIH19XG4gICAgICA8L3N2Zzp0ZXh0PlxuICAgIDwvc3ZnOmc+XG4gIDwvc3ZnOmc+XG48L3N2Zz5cblxuPGRpdlxuICBjbGFzcz1cInN0YXR1cy1jb250YWluZXJcIlxuICAqbmdJZj1cImxvYWRpbmcgfHwgZmFpbGVkXCJcbj5cbiAgPGRpdlxuICAgICpuZ0lmPVwiZmFpbGVkICYmICFsb2FkaW5nXCJcbiAgICBjbGFzcz1cInN0YXR1cyBmYWlsZWRcIlxuICA+XG4gICAgPGF1aS1pY29uXG4gICAgICBpY29uPVwiZXhjbGFtYXRpb25fdHJpYW5nbGVfc1wiXG4gICAgICBiYWNrZ3JvdW5kPVwidHJpYW5nbGVcIlxuICAgID48L2F1aS1pY29uPlxuICAgIHt7ICdmYWlsZWRfbG9hZF9wbGVhc2UnIHwgdHJhbnNsYXRlIH19XG4gICAgPGJ1dHRvblxuICAgICAgYXVpLWJ1dHRvbj1cInRleHRcIlxuICAgICAgKGNsaWNrKT1cIm9uUmVmcmVzaCgpXCJcbiAgICA+XG4gICAgICB7eyAncmVmcmVzaCcgfCB0cmFuc2xhdGUgfX1cbiAgICA8L2J1dHRvbj5cbiAgPC9kaXY+XG4gIDxkaXZcbiAgICAqbmdJZj1cImxvYWRpbmdcIlxuICAgIGNsYXNzPVwic3RhdHVzIGxvYWRpbmdcIlxuICA+XG4gICAgPGF1aS1pY29uIGljb249XCJzcGlubmVyXCI+PC9hdWktaWNvbj4ge3sgJ2xvYWRpbmcnIHwgdHJhbnNsYXRlIH19XG4gIDwvZGl2PlxuPC9kaXY+XG5cbjxuZy10ZW1wbGF0ZVxuICAjdG9vbHRpcFRlbXBsYXRlXG4gIGxldC1pbmRleD1cImluZGV4XCJcbiAgbGV0LWFyYz1cImFyY1wiXG4+XG4gIDxpXG4gICAgY2xhc3M9XCJkb3RcIlxuICAgIFtzdHlsZS5iYWNrZ3JvdW5kXT1cImFyYy5jb2xvclwiXG4gID48L2k+XG4gIHt7IGFyYy5sYWJlbHNbMV0gfCB0cmFuc2xhdGUgfX06XG4gIHt7ICthcmMubGFiZWxzWzBdIHwgYWNsTnVtZXJpY2FsTGltaXQgfCBhY2xGaWVsZE5vdEF2YWlsYWJsZSB9fSUgKHt7XG4gICAgK2FyYy52YWx1ZSB8IGFjbE51bWVyaWNhbExpbWl0IHwgYWNsRmllbGROb3RBdmFpbGFibGVcbiAgfX1cbiAge3sgdW5pdCB8IHRyYW5zbGF0ZSB9fSlcbjwvbmctdGVtcGxhdGU+XG4iXX0=