UNPKG

@alauda-fe/common

Version:

Alauda frontend team common codes.

250 lines 34.9 kB
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=