UNPKG

@alauda-fe/common

Version:

Alauda frontend team common codes.

257 lines 35.5 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"; import * as i2 from "@angular/common"; import * as i3 from "../../effect-directive/e2e-attribute-binding.directive"; import * as i4 from "@alauda/ui"; import * as i5 from "../indicator-color.directive"; import * as i6 from "../../core/pipes/field-not-available.pipe"; import * as i7 from "../../core/pipes/pure.pipe"; import * as i8 from "../../translate/translate.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); } }, dependencies: [i2.NgForOf, i2.NgIf, i3.E2eAttributeBindingDirective, i4.TooltipDirective, i4.IconComponent, i4.ButtonComponent, i5.IndicatorColorDirective, i6.FieldNotAvailablePipe, i7.PurePipe, i8.TranslatePipe, i1.NumericalLimitPipe], 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmFkaWFsLWJhci1jaGFydC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9saWJzL2NvbW1vbi9zcmMvcGllLWRlcml2YXRpdmUtY2hhcnQvcmFkaWFsLWJhci9yYWRpYWwtYmFyLWNoYXJ0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvY29tbW9uL3NyYy9waWUtZGVyaXZhdGl2ZS1jaGFydC9yYWRpYWwtYmFyL3JhZGlhbC1iYXItY2hhcnQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixTQUFTLEVBQ1QsWUFBWSxFQUNaLEtBQUssRUFFTCxNQUFNLEdBQ1AsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLElBQUksQ0FBQztBQUV6QixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUM3RCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sVUFBVSxDQUFDOzs7Ozs7Ozs7Ozs7O0lDV2pDLCtCQWNDOztJQUNDLFlBS0Y7Ozs7SUFBQSxpQkFBVzs7Ozs7O0lBUFQsMEdBQTBEOztJQUUxRCxlQUtGO0lBTEUsd0tBS0Y7Ozs7SUFyQ0YseUJBQW1FO0lBT2pFLEFBTkEsMEJBS1ksY0FVQTtJQUNaLHlGQWNDO0lBT0gsaUJBQVE7Ozs7OztJQW5DSixjQUE4QjtJQUM5QixBQURBLCtDQUE4QixnRUFDYzs7SUFJNUMsY0FBeUI7SUFLekIsQUFMQSxxQ0FBeUIsc0NBS2U7SUFIeEMsQUFEQSwrQ0FBOEIsZ0VBQ2M7O0lBUTFCLGNBQWU7SUFBZix1Q0FBZTs7OztJQWtEdkMsK0JBR0M7SUFDQywrQkFHWTtJQUNaLFlBQ0E7O0lBQUEsa0NBR0M7SUFEQywyTEFBUyxrQkFBVyxLQUFDO0lBRXJCLFlBQ0Y7O0lBQ0YsQUFERSxpQkFBUyxFQUNMOztJQVBKLGVBQ0E7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ckMsQ0FBQztJQUNKLENBQUM7d0ZBbktVLHVCQUF1QjtvRUFBdkIsdUJBQXVCLDJVQUZ2QixDQUFDLGtCQUFrQixDQUFDOztZQzlCL0IsQUFKRiwyQkFHQyxRQUNxQztZQUNsQywwRUFBbUU7WUE0Q2pFLEFBSkYsNEJBR0MsY0FPRTtZQUNDLFlBQ0Y7OztZQUFBLGlCQUFXO1lBQ1gsK0JBSUM7WUFDQyxZQUNGOztZQUdOLEFBREUsQUFERSxBQURFLGlCQUFXLEVBQ0wsRUFDRixFQUNKO1lBOEJOLEFBNUJBLDBFQUdDLCtHQTZCQTs7O1lBakdRLGNBQTRCOztZQUNWLGNBQVM7WUFBQSxBQUFULGtDQUFTLGtDQUF1QjtZQTZDbkQsZUFFQztZQUZELHFIQUVDO1lBSUQsY0FDRjtZQURFLDRGQUNGO1lBTUUsZUFDRjtZQURFLHVFQUNGO1lBT0gsZUFBdUI7WUFBdkIsZ0RBQXVCOzs7aUZEbkNiLHVCQUF1QjtjQVBuQyxTQUFTOzJCQUNFLHNCQUFzQixtQkFHZix1QkFBdUIsQ0FBQyxNQUFNLGFBQ3BDLENBQUMsa0JBQWtCLENBQUM7bURBSS9CLGNBQWM7a0JBRGIsS0FBSztZQUlOLGdCQUFnQjtrQkFEZixLQUFLO1lBSU4sUUFBUTtrQkFEUCxLQUFLO1lBSU4sSUFBSTtrQkFESCxLQUFLO1lBU0csSUFBSTtrQkFBWixLQUFLO1lBRUcsS0FBSztrQkFBYixLQUFLO1lBRUcsS0FBSztrQkFBYixLQUFLO1lBRUcsT0FBTztrQkFBZixLQUFLO1lBRUcsT0FBTztrQkFBZixLQUFLO1lBRUcsTUFBTTtrQkFBZCxLQUFLO1lBRUksT0FBTztrQkFBaEIsTUFBTTs7a0ZBL0JJLHVCQUF1QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDb21wb25lbnQsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5wdXQsXG4gIE9uQ2hhbmdlcyxcbiAgT3V0cHV0LFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGFyYyB9IGZyb20gJ2QzJztcblxuaW1wb3J0IHsgTnVtZXJpY2FsTGltaXRQaXBlIH0gZnJvbSAnLi4vbnVtZXJpY2FsLWxpbWl0LnBpcGUnO1xuaW1wb3J0IHsgbWVhc3VyZVRleHQgfSBmcm9tICcuLi91bml0cyc7XG5cbmNvbnN0IE1BWF9WQUxVRSA9IDk5OV85OTk7XG5cbmNvbnN0IERFQ0lNQUxfTUFYX1ZBTFVFID0gOTk5Ljk5O1xuXG5pbnRlcmZhY2UgTm9kZUZyYWN0aW9uQXJjIHtcbiAgYmFja2dyb3VuZEFyY1BhdGg6IGFueTtcbiAgZnJhY3Rpb25BcmNQYXRoOiBhbnk7XG4gIGxhYmVsczogc3RyaW5nW107XG4gIGxhYmVsQ29vcmQ6IGFueTtcbiAgZnJhY3Rpb25BcmNPcGFjaXR5OiBudW1iZXI7XG4gIGZyYWN0aW9uOiBhbnk7XG4gIGNvbG9yOiBzdHJpbmc7XG4gIHZhbHVlOiBzdHJpbmc7XG4gIGhpZGVJbmRpY2F0b3I/OiBib29sZWFuO1xufVxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhY2wtcmFkaWFsLWJhci1jaGFydCcsXG4gIHRlbXBsYXRlVXJsOiAnLi9yYWRpYWwtYmFyLWNoYXJ0LmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vcmFkaWFsLWJhci1jaGFydC5jb21wb25lbnQuc2NzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgcHJvdmlkZXJzOiBbTnVtZXJpY2FsTGltaXRQaXBlXSxcbn0pXG5leHBvcnQgY2xhc3MgUmFkaWFsQmFyQ2hhcnRDb21wb25lbnQgaW1wbGVtZW50cyBPbkNoYW5nZXMge1xuICBASW5wdXQoKVxuICBsaW1pdHNGcmFjdGlvbjogbnVtYmVyO1xuXG4gIEBJbnB1dCgpXG4gIHJlcXVlc3RzRnJhY3Rpb246IG51bWJlcjtcblxuICBASW5wdXQoKVxuICBjYXBhY2l0eTogbnVtYmVyO1xuXG4gIEBJbnB1dCgpXG4gIGRhdGE6IEFycmF5PHtcbiAgICB0aXRsZTogc3RyaW5nO1xuICAgIHZhbHVlOiBzdHJpbmc7XG4gICAgZnJhY3Rpb246IG51bWJlcjtcbiAgICBoaWRlSW5kaWNhdG9yOiBib29sZWFuO1xuICAgIGNvbG9yPzogc3RyaW5nO1xuICB9PjtcblxuICBASW5wdXQoKSB1bml0OiBzdHJpbmc7XG5cbiAgQElucHV0KCkgY29sb3I6IHN0cmluZztcblxuICBASW5wdXQoKSB1c2FnZTogc3RyaW5nO1xuXG4gIEBJbnB1dCgpIHJlcXVlc3Q6IHN0cmluZztcblxuICBASW5wdXQoKSBsb2FkaW5nOiBib29sZWFuO1xuXG4gIEBJbnB1dCgpIGZhaWxlZDogYm9vbGVhbjtcblxuICBAT3V0cHV0KCkgcmVmcmVzaCA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuICByZWFkb25seSBzaXplID0gMTYwO1xuXG4gIHJlYWRvbmx5IG9mZnNldCA9IDEyMDtcblxuICBwcml2YXRlIHJlYWRvbmx5IHBpZVNpemUgPSAxMDtcblxuICBwcml2YXRlIHJlYWRvbmx5IG1hcmdpbiA9IDU7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBpbm5lclNocmluayA9IDE1O1xuXG4gIHJlYWRvbmx5IG1heFZhbHVlID0gTUFYX1ZBTFVFO1xuXG4gIHJlYWRvbmx5IGRlY2ltYWxNYXhWYWx1ZSA9IERFQ0lNQUxfTUFYX1ZBTFVFO1xuXG4gIGFyY3M6IE5vZGVGcmFjdGlvbkFyY1tdO1xuXG4gIG5nT25DaGFuZ2VzKCk6IHZvaWQge1xuICAgIHRoaXMuYXJjcyA9IHRoaXMuZ2V0QXJjcygpO1xuICB9XG5cbiAgZ2V0IHRyYW5zZm9ybSgpIHtcbiAgICByZXR1cm4gYHRyYW5zbGF0ZSgkeyh0aGlzLnNpemUgKyB0aGlzLm9mZnNldCkgLyAyfSwgJHt0aGlzLnNpemUgLyAyfSlgO1xuICB9XG5cbiAgZ2V0IG91dGVyUmFkaXVzKCkge1xuICAgIHJldHVybiB0aGlzLnNpemUgLyAyIC0gdGhpcy5tYXJnaW47XG4gIH1cblxuICBnZXQgaW5uZXJSYWRpdXMoKSB7XG4gICAgcmV0dXJuIHRoaXMub3V0ZXJSYWRpdXMgLSB0aGlzLnBpZVNpemU7XG4gIH1cblxuICBhcmNUcmFja0J5Rm4oaW5kZXg6IG51bWJlcikge1xuICAgIHJldHVybiBpbmRleDtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgbnVtZXJpY2FsTGltaXRQaXBlOiBOdW1lcmljYWxMaW1pdFBpcGUpIHt9XG5cbiAgcHJpdmF0ZSBnZXRBcmNzKCk6IE5vZGVGcmFjdGlvbkFyY1tdIHtcbiAgICBsZXQgYXJjczogTm9kZUZyYWN0aW9uQXJjW10gPSBbXTtcbiAgICBjb25zdCBsaW1pdHNBcmMgPSB0aGlzLmdldEFyYyhcbiAgICAgIDAsXG4gICAgICB0aGlzLnJlcXVlc3RzRnJhY3Rpb24sXG4gICAgICAncmVxdWVzdF9yYXRlJyxcbiAgICAgIDEsXG4gICAgICB0aGlzLnJlcXVlc3QsXG4gICAgKTtcbiAgICBjb25zdCByZXF1ZXN0c0FyYyA9IHRoaXMuZ2V0QXJjKFxuICAgICAgMSxcbiAgICAgIHRoaXMubGltaXRzRnJhY3Rpb24sXG4gICAgICAndXNhZ2VfcmF0ZScsXG4gICAgICAwLjcsXG4gICAgICB0aGlzLnVzYWdlLFxuICAgICk7XG4gICAgYXJjcyA9IFtyZXF1ZXN0c0FyYywgbGltaXRzQXJjXTtcblxuICAgIGlmICh0aGlzLmRhdGEpIHtcbiAgICAgIGFyY3MgPSB0aGlzLmhhbmRlbERhdGEoKTtcbiAgICB9XG4gICAgcmV0dXJuIGFyY3M7XG4gIH1cblxuICBnZXRBcmMgPSAoXG4gICAgbGV2ZWw6IG51bWJlcixcbiAgICBmcmFjdGlvbjogbnVtYmVyLFxuICAgIGxhYmVsOiBzdHJpbmcsXG4gICAgb3BhY2l0eTogbnVtYmVyLFxuICAgIHZhbHVlOiBzdHJpbmcsXG4gICAgaGlkZUluZGljYXRvciA9IGZhbHNlLFxuICAgIGNvbG9yID0gdGhpcy5jb2xvcixcbiAgKTogTm9kZUZyYWN0aW9uQXJjID0+IHtcbiAgICBmcmFjdGlvbiA9IGZyYWN0aW9uIHx8IDA7XG4gICAgcmV0dXJuIHtcbiAgICAgIGJhY2tncm91bmRBcmNQYXRoOiB0aGlzLmdldEJhY2tncm91bmRBcmNQYXRoKGxldmVsKSxcbiAgICAgIGZyYWN0aW9uQXJjUGF0aDogdGhpcy5nZXRGcmFjdGlvbkFyY1BhdGgoZnJhY3Rpb24gfHwgMCwgbGV2ZWwpLFxuICAgICAgbGFiZWxzOiBbZnJhY3Rpb24gPyAnJyArIGZyYWN0aW9uIDogbnVsbCwgbGFiZWxdLFxuICAgICAgbGFiZWxDb29yZDogdGhpcy5nZXRUZXh0Q29vcmQobGV2ZWwpLFxuICAgICAgZnJhY3Rpb25BcmNPcGFjaXR5OiBvcGFjaXR5LFxuICAgICAgZnJhY3Rpb24sXG4gICAgICBjb2xvcixcbiAgICAgIHZhbHVlLFxuICAgICAgaGlkZUluZGljYXRvcixcbiAgICB9O1xuICB9O1xuXG4gIGhhbmRlbERhdGEoKSB7XG4gICAgcmV0dXJuIHRoaXMuZGF0YS5tYXAoKGl0ZW0sIGluZGV4KSA9PlxuICAgICAgdGhpcy5nZXRBcmMoXG4gICAgICAgIGluZGV4LFxuICAgICAgICBpdGVtLmZyYWN0aW9uLFxuICAgICAgICBpdGVtLnRpdGxlLFxuICAgICAgICBpdGVtLmNvbG9yID8gMSA6ICsoMSAvIChpbmRleCArIDEpKS50b0ZpeGVkKDIpLFxuICAgICAgICBpdGVtLnZhbHVlLFxuICAgICAgICBpdGVtLmhpZGVJbmRpY2F0b3IsXG4gICAgICAgIGl0ZW0uY29sb3IsXG4gICAgICApLFxuICAgICk7XG4gIH1cblxuICBnZXRCYWNrZ3JvdW5kQXJjUGF0aChsZXZlbCA9IDApIHtcbiAgICBjb25zdCBzaHJpbmsgPSBsZXZlbCAqIHRoaXMuaW5uZXJTaHJpbms7XG4gICAgcmV0dXJuIGFyYygpLmNvcm5lclJhZGl1cygyMCkoe1xuICAgICAgc3RhcnRBbmdsZTogMCxcbiAgICAgIGVuZEFuZ2xlOiBNYXRoLlBJICogMS41LFxuICAgICAgaW5uZXJSYWRpdXM6IHRoaXMuaW5uZXJSYWRpdXMgLSBzaHJpbmssXG4gICAgICBvdXRlclJhZGl1czogdGhpcy5vdXRlclJhZGl1cyAtIHNocmluayxcbiAgICB9KTtcbiAgfVxuXG4gIG9uUmVmcmVzaCgpIHtcbiAgICB0aGlzLnJlZnJlc2gubmV4dChudWxsKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0RnJhY3Rpb25BcmNQYXRoKGZyYWN0aW9uOiBudW1iZXIsIGxldmVsID0gMCkge1xuICAgIGNvbnN0IHNocmluayA9IGxldmVsICogdGhpcy5pbm5lclNocmluaztcbiAgICBmcmFjdGlvbiA9IE1hdGgubWluKDEwMCwgZnJhY3Rpb24pO1xuICAgIHJldHVybiBhcmMoKS5jb3JuZXJSYWRpdXMoMjApKHtcbiAgICAgIHN0YXJ0QW5nbGU6IDAsXG4gICAgICBlbmRBbmdsZTogKE1hdGguUEkgKiAxLjUgKiBmcmFjdGlvbikgLyAxMDAsXG4gICAgICBpbm5lclJhZGl1czogdGhpcy5pbm5lclJhZGl1cyAtIHNocmluayxcbiAgICAgIG91dGVyUmFkaXVzOiB0aGlzLm91dGVyUmFkaXVzIC0gc2hyaW5rLFxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRUZXh0Q29vcmQobGV2ZWwgPSAwKTogeyBkeDogbnVtYmVyOyBkeTogbnVtYmVyIH0ge1xuICAgIGNvbnN0IHNocmluayA9IGxldmVsICogdGhpcy5pbm5lclNocmluaztcbiAgICByZXR1cm4ge1xuICAgICAgZHg6IC00LFxuICAgICAgZHk6IC0odGhpcy5vdXRlclJhZGl1cyAtIHNocmluayAtIDUpLFxuICAgIH07XG4gIH1cblxuICBnZXRMYWJlbER4ID0gKHg6IG51bWJlciwgdGV4dDogbnVtYmVyLCBpbmRleDogbnVtYmVyKSA9PiB7XG4gICAgcmV0dXJuIGluZGV4XG4gICAgICA/IHggLSAobWVhc3VyZVRleHQodGhpcy5udW1lcmljYWxMaW1pdFBpcGUudHJhbnNmb3JtKCt0ZXh0KSkud2lkdGggKyAyMClcbiAgICAgIDogeDtcbiAgfTtcbn1cbiIsIjxzdmdcbiAgW2F0dHIud2lkdGhdPVwic2l6ZSArIG9mZnNldFwiXG4gIFthdHRyLmhlaWdodF09XCJzaXplXCJcbj5cbiAgPHN2ZzpnIFthdHRyLnRyYW5zZm9ybV09XCJ0cmFuc2Zvcm1cIj5cbiAgICA8c3ZnOmcgKm5nRm9yPVwibGV0IGFyYyBvZiBhcmNzOyB0cmFja0J5OiBhcmNUcmFja0J5Rm47IGluZGV4IGFzIGlcIj5cbiAgICAgIDxzdmc6cGF0aFxuICAgICAgICBjbGFzcz1cImZ1bGwtYXJjLXBhdGhcIlxuICAgICAgICBbYXVpVG9vbHRpcF09XCJ0b29sdGlwVGVtcGxhdGVcIlxuICAgICAgICBbYXVpVG9vbHRpcENvbnRleHRdPVwieyBpbmRleDogaSwgYXJjOiBhcmMgfVwiXG4gICAgICAgIFthdHRyLmRdPVwiYXJjLmJhY2tncm91bmRBcmNQYXRoXCJcbiAgICAgID48L3N2ZzpwYXRoPlxuICAgICAgPHN2ZzpwYXRoXG4gICAgICAgIFtzdHlsZS5jb2xvcl09XCJhcmMuY29sb3JcIlxuICAgICAgICBbYXVpVG9vbHRpcF09XCJ0b29sdGlwVGVtcGxhdGVcIlxuICAgICAgICBbYXVpVG9vbHRpcENvbnRleHRdPVwieyBpbmRleDogaSwgYXJjOiBhcmMgfVwiXG4gICAgICAgIGNsYXNzPVwiZnJhY3Rpb24tYXJjLXBhdGhcIlxuICAgICAgICBbYXR0ci5maWxsXT1cImFyYy5jb2xvclwiXG4gICAgICAgIFtzdHlsZS5vcGFjaXR5XT1cImFyYy5mcmFjdGlvbkFyY09wYWNpdHlcIlxuICAgICAgICBbYXR0ci5kXT1cImFyYy5mcmFjdGlvbkFyY1BhdGhcIlxuICAgICAgICBub2RlTmFtZVxuICAgICAgPjwvc3ZnOnBhdGg+XG4gICAgICA8c3ZnOnRleHRcbiAgICAgICAgKm5nRm9yPVwibGV0IGxhYmVsIG9mIGFyYy5sYWJlbHM7IGluZGV4IGFzIGxhYmVsSW5kZXhcIlxuICAgICAgICBjbGFzcz1cImZyYWN0aW9uLWxhYmVsLXRleHRcIlxuICAgICAgICBbYXR0ci5keF09XCJcbiAgICAgICAgICBhcmMubGFiZWxDb29yZC5keFxuICAgICAgICAgICAgfCBwdXJlXG4gICAgICAgICAgICAgIDogZ2V0TGFiZWxEeFxuICAgICAgICAgICAgICA6ICRhbnkoYXJjLmxhYmVsc1tsYWJlbEluZGV4ID8gbGFiZWxJbmRleCAtIDEgOiBsYWJlbEluZGV4XSlcbiAgICAgICAgICAgICAgOiBsYWJlbEluZGV4XG4gICAgICAgIFwiXG4gICAgICAgIFthdHRyLmR5XT1cImFyYy5sYWJlbENvb3JkLmR5XCJcbiAgICAgICAgdGV4dC1hbmNob3I9XCJlbmRcIlxuICAgICAgICBhY2xJbmRpY2F0b3JDb2xvclxuICAgICAgICBbaW5kaWNhdG9yXT1cImxhYmVsSW5kZXggfHwgYXJjPy5oaWRlSW5kaWNhdG9yID8gMCA6IGxhYmVsXCJcbiAgICAgID5cbiAgICAgICAge3tcbiAgICAgICAgICBsYWJlbEluZGV4XG4gICAgICAgICAgICA/IChsYWJlbCB8IHRyYW5zbGF0ZSlcbiAgICAgICAgICAgIDogKCtsYWJlbCB8IGFjbE51bWVyaWNhbExpbWl0IHwgYWNsRmllbGROb3RBdmFpbGFibGUpXG4gICAgICAgIH19e3sgbGFiZWxJbmRleCA/ICcnIDogJyUnIH19XG4gICAgICA8L3N2Zzp0ZXh0PlxuICAgIDwvc3ZnOmc+XG5cbiAgICA8c3ZnOmdcbiAgICAgIGNsYXNzPVwiY2VudGVyLXRleHRcIlxuICAgICAgZHk9XCItNVwiXG4gICAgPlxuICAgICAgPHN2Zzp0ZXh0XG4gICAgICAgIFtzdHlsZS5mb250LXNpemVdPVwiXG4gICAgICAgICAgY2FwYWNpdHkgPiA5OTk5IHx8IGFyY3M/Lmxlbmd0aCA+IDIgPyAnMTZweCcgOiAnMjRweCdcbiAgICAgICAgXCJcbiAgICAgICAgdGV4dC1hbmNob3I9XCJtaWRkbGVcIlxuICAgICAgICBjbGFzcz1cImNlbnRlci10ZXh0X19tYWluXCJcbiAgICAgID5cbiAgICAgICAge3sgK2NhcGFjaXR5IHwgYWNsTnVtZXJpY2FsTGltaXQgfCBhY2xGaWVsZE5vdEF2YWlsYWJsZSB9fVxuICAgICAgPC9zdmc6dGV4dD5cbiAgICAgIDxzdmc6dGV4dFxuICAgICAgICB0ZXh0LWFuY2hvcj1cIm1pZGRsZVwiXG4gICAgICAgIGR5PVwiMjBcIlxuICAgICAgICBjbGFzcz1cImNlbnRlci10ZXh0X19zdWJcIlxuICAgICAgPlxuICAgICAgICB7eyAndG90YWxfbnVtYmVyJyB8IHRyYW5zbGF0ZSB9fVxuICAgICAgPC9zdmc6dGV4dD5cbiAgICA8L3N2ZzpnPlxuICA8L3N2ZzpnPlxuPC9zdmc+XG5cbjxkaXZcbiAgY2xhc3M9XCJzdGF0dXMtY29udGFpbmVyXCJcbiAgKm5nSWY9XCJsb2FkaW5nIHx8IGZhaWxlZFwiXG4+XG4gIDxkaXZcbiAgICAqbmdJZj1cImZhaWxlZCAmJiAhbG9hZGluZ1wiXG4gICAgY2xhc3M9XCJzdGF0dXMgZmFpbGVkXCJcbiAgPlxuICAgIDxhdWktaWNvblxuICAgICAgaWNvbj1cImV4Y2xhbWF0aW9uX3RyaWFuZ2xlX3NcIlxuICAgICAgYmFja2dyb3VuZD1cInRyaWFuZ2xlXCJcbiAgICA+PC9hdWktaWNvbj5cbiAgICB7eyAnZmFpbGVkX2xvYWRfcGxlYXNlJyB8IHRyYW5zbGF0ZSB9fVxuICAgIDxidXR0b25cbiAgICAgIGF1aS1idXR0b249XCJ0ZXh0XCJcbiAgICAgIChjbGljayk9XCJvblJlZnJlc2goKVwiXG4gICAgPlxuICAgICAge3sgJ3JlZnJlc2gnIHwgdHJhbnNsYXRlIH19XG4gICAgPC9idXR0b24+XG4gIDwvZGl2PlxuICA8ZGl2XG4gICAgKm5nSWY9XCJsb2FkaW5nXCJcbiAgICBjbGFzcz1cInN0YXR1cyBsb2FkaW5nXCJcbiAgPlxuICAgIDxhdWktaWNvbiBpY29uPVwic3Bpbm5lclwiPjwvYXVpLWljb24+IHt7ICdsb2FkaW5nJyB8IHRyYW5zbGF0ZSB9fVxuICA8L2Rpdj5cbjwvZGl2PlxuXG48bmctdGVtcGxhdGVcbiAgI3Rvb2x0aXBUZW1wbGF0ZVxuICBsZXQtaW5kZXg9XCJpbmRleFwiXG4gIGxldC1hcmM9XCJhcmNcIlxuPlxuICA8aVxuICAgIGNsYXNzPVwiZG90XCJcbiAgICBbc3R5bGUuYmFja2dyb3VuZF09XCJhcmMuY29sb3JcIlxuICA+PC9pPlxuICB7eyBhcmMubGFiZWxzWzFdIHwgdHJhbnNsYXRlIH19OlxuICB7eyArYXJjLmxhYmVsc1swXSB8IGFjbE51bWVyaWNhbExpbWl0IHwgYWNsRmllbGROb3RBdmFpbGFibGUgfX0lICh7e1xuICAgICthcmMudmFsdWUgfCBhY2xOdW1lcmljYWxMaW1pdCB8IGFjbEZpZWxkTm90QXZhaWxhYmxlXG4gIH19XG4gIHt7IHVuaXQgfCB0cmFuc2xhdGUgfX0pXG48L25nLXRlbXBsYXRlPlxuIl19