UNPKG

@nova-ui/charts

Version:

Nova Charts is a library created to provide potential consumers with solutions for various data visualizations that conform with the Nova Design Language. It's designed to solve common patterns identified by UX designers, but also be very flexible so that

180 lines 28.6 kB
// © 2022 SolarWinds Worldwide, LLC. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. import { arc } from "d3-shape"; import defaultsDeep from "lodash/defaultsDeep"; import isUndefined from "lodash/isUndefined"; import { DATA_POINT_NOT_FOUND, HIGHLIGHT_DATA_POINT_EVENT, HIGHLIGHT_SERIES_EVENT, INTERACTION_DATA_POINTS_EVENT, SELECT_DATA_POINT_EVENT, } from "../../constants"; import { Renderer } from "../../core/common/renderer"; import { InteractionType, } from "../../core/common/types"; import { RenderLayerName } from "../types"; /** * Default configuration for Radial Renderer */ export const DEFAULT_RADIAL_RENDERER_CONFIG = { annularWidth: 20, annularPadding: 5, maxThickness: 30, annularGrowth: 0.15, cursor: "default", enableSeriesHighlighting: true, enableDataPointHighlighting: true, }; /** * Radial renderer is a generic renderer that is able to draw pie and donut charts */ export class RadialRenderer extends Renderer { config; segmentWidth; /** * Creates an instance of RadialRenderer. * @param {IRadialRendererConfig} [config] * Renderer configuration object. Defaults to `DEFAULT_RADIAL_RENDERER_CONFIG` constant value. */ constructor(config = {}) { super(config); this.config = config; this.config = defaultsDeep(this.config, DEFAULT_RADIAL_RENDERER_CONFIG); } /** See {@link Renderer#draw} */ draw(renderSeries, rendererSubject) { const dataContainer = renderSeries.containers[RenderLayerName.data]; const data = renderSeries.dataSeries.data; const accessors = renderSeries.dataSeries.accessors; // TODO: This handles several data points withing one series as well. Most probably this can be abstracted to other renderer const arcGenerator = (d, index) => { const separateArc = this.getArc(renderSeries.scales.r.range(), arc(), index); return separateArc(d); }; this.segmentWidth = this.getSegmentWidth(renderSeries); const g = dataContainer.selectAll("path.arc").data(data); g.exit().remove(); g.enter() .append("path") .attr("class", "arc pointer-events nui-chart--path__outline") .style("stroke-width", this.config.strokeWidth) .style("cursor", this.config.cursor) .on("mouseenter", (d, i) => { this.emitDataPointHighlight(renderSeries, d, i, rendererSubject); }) .on("mouseleave", (d, i) => { this.emitDataPointHighlight(renderSeries, null, DATA_POINT_NOT_FOUND, rendererSubject); }) // TODO: testing event, remove in favor or generic interaction setup .on("click", (d, i) => { rendererSubject.next({ eventName: SELECT_DATA_POINT_EVENT, data: { seriesId: renderSeries.dataSeries.id, index: i, data: d.data, position: this.getDataPointPosition(renderSeries.dataSeries, i, renderSeries.scales), }, }); }) .merge(g) .attr("d", arcGenerator) .attr("fill", (d, i) => accessors.data.color ? accessors.data.color(d.data, i, data, renderSeries.dataSeries) : accessors.series.color?.(renderSeries.dataSeries.id, renderSeries.dataSeries)); } /** See {@link Renderer#getDataPointPosition} */ getDataPointPosition(dataSeries, index, scales) { if (index < 0) { return undefined; } const pieArcData = dataSeries.data[index]; const dataPointArc = this.getArc(scales.r.range(), arc(), index); const centroid = dataPointArc.centroid(pieArcData); return { x: centroid[0], y: centroid[1], width: 0, height: 0, }; } getInnerRadius(range, index) { if (isUndefined(this.segmentWidth) || isUndefined(this.config.annularPadding)) { throw new Error("Can't compute inner radius"); } const calculatedRadius = range[1] - range[0] - this.segmentWidth - index * (this.config.annularPadding + this.segmentWidth); return calculatedRadius >= 0 ? calculatedRadius : 0; } getOuterRadius(range, index) { if (isUndefined(this.segmentWidth) || isUndefined(this.config.annularPadding)) { throw new Error("Can't compute outer radius"); } const calculatedRadius = range[1] - range[0] - index * (this.config.annularPadding + this.segmentWidth); return calculatedRadius >= 0 ? calculatedRadius : 0; } getArc(range, generatedArc, index) { const innerRadius = this.getInnerRadius(range, index); return generatedArc .outerRadius(this.getOuterRadius(range, index)) .innerRadius(innerRadius); } getSegmentWidth(renderSeries) { if (!(this.config.maxThickness && this.config.annularGrowth)) { return this.config.annularWidth; } return Math.min((renderSeries.scales.r.range()[1] - renderSeries.scales.r.range()[0]) * this.config.annularGrowth, this.config.maxThickness); } emitDataPointHighlight(renderSeries, data, i, rendererSubject) { const position = this.getDataPointPosition(renderSeries.dataSeries, i, renderSeries.scales); const dataPoint = { seriesId: renderSeries.dataSeries.id, dataSeries: renderSeries.dataSeries, index: i, data: data, position: position, }; if (this.config.enableSeriesHighlighting) { rendererSubject.next({ eventName: HIGHLIGHT_SERIES_EVENT, data: dataPoint, }); } if (this.config.enableDataPointHighlighting) { rendererSubject.next({ eventName: HIGHLIGHT_DATA_POINT_EVENT, data: dataPoint, }); } // we're emitting this event manually, because it's not triggered by mouse interactive area in this case rendererSubject.next({ eventName: INTERACTION_DATA_POINTS_EVENT, data: { interactionType: InteractionType.MouseMove, dataPoints: { [renderSeries.dataSeries.id]: dataPoint, }, }, }); } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmFkaWFsLXJlbmRlcmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3JlbmRlcmVycy9yYWRpYWwvcmFkaWFsLXJlbmRlcmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLHlEQUF5RDtBQUN6RCxFQUFFO0FBQ0YsK0VBQStFO0FBQy9FLDRFQUE0RTtBQUM1RSw4RUFBOEU7QUFDOUUsK0VBQStFO0FBQy9FLDhFQUE4RTtBQUM5RSw0REFBNEQ7QUFDNUQsRUFBRTtBQUNGLDZFQUE2RTtBQUM3RSx1REFBdUQ7QUFDdkQsRUFBRTtBQUNGLDZFQUE2RTtBQUM3RSw0RUFBNEU7QUFDNUUsK0VBQStFO0FBQy9FLDBFQUEwRTtBQUMxRSxpRkFBaUY7QUFDakYsNkVBQTZFO0FBQzdFLGlCQUFpQjtBQUVqQixPQUFPLEVBQU8sR0FBRyxFQUFvQixNQUFNLFVBQVUsQ0FBQztBQUN0RCxPQUFPLFlBQVksTUFBTSxxQkFBcUIsQ0FBQztBQUMvQyxPQUFPLFdBQVcsTUFBTSxvQkFBb0IsQ0FBQztBQUc3QyxPQUFPLEVBQ0gsb0JBQW9CLEVBQ3BCLDBCQUEwQixFQUMxQixzQkFBc0IsRUFDdEIsNkJBQTZCLEVBQzdCLHVCQUF1QixHQUMxQixNQUFNLGlCQUFpQixDQUFDO0FBQ3pCLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUV0RCxPQUFPLEVBR0gsZUFBZSxHQUlsQixNQUFNLHlCQUF5QixDQUFDO0FBQ2pDLE9BQU8sRUFBaUIsZUFBZSxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBRzFEOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sOEJBQThCLEdBQTBCO0lBQ2pFLFlBQVksRUFBRSxFQUFFO0lBQ2hCLGNBQWMsRUFBRSxDQUFDO0lBQ2pCLFlBQVksRUFBRSxFQUFFO0lBQ2hCLGFBQWEsRUFBRSxJQUFJO0lBQ25CLE1BQU0sRUFBRSxTQUFTO0lBQ2pCLHdCQUF3QixFQUFFLElBQUk7SUFDOUIsMkJB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UUFFRCxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsMkJBQTJCLEVBQUU7WUFDekMsZUFBZSxDQUFDLElBQUksQ0FBQztnQkFDakIsU0FBUyxFQUFFLDBCQUEwQjtnQkFDckMsSUFBSSxFQUFFLFNBQVM7YUFDbEIsQ0FBQyxDQUFDO1NBQ047UUFFRCx3R0FBd0c7UUFDeEcsZUFBZSxDQUFDLElBQUksQ0FBQztZQUNqQixTQUFTLEVBQUUsNkJBQTZCO1lBQ3hDLElBQUksRUFBRTtnQkFDRixlQUFlLEVBQUUsZUFBZSxDQUFDLFNBQVM7Z0JBQzFDLFVBQVUsRUFBRTtvQkFDUixDQUFDLFlBQVksQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLEVBQUUsU0FBUztpQkFDMUM7YUFDSjtTQUNKLENBQUMsQ0FBQztJQUNQLENBQUM7Q0FDSiIsInNvdXJjZXNDb250ZW50IjpbIi8vIMKpIDIwMjIgU29sYXJXaW5kcyBXb3JsZHdpZGUsIExMQy4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4vLyAgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG9cbi8vICBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZVxuLy8gIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vclxuLy8gIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG4vLyAgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuLy8gIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1Jcbi8vICBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbi8vICBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbi8vICBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4vLyAgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSxcbi8vICBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOXG4vLyAgVEhFIFNPRlRXQVJFLlxuXG5pbXBvcnQgeyBBcmMsIGFyYywgRGVmYXVsdEFyY09iamVjdCB9IGZyb20gXCJkMy1zaGFwZVwiO1xuaW1wb3J0IGRlZmF1bHRzRGVlcCBmcm9tIFwibG9kYXNoL2RlZmF1bHRzRGVlcFwiO1xuaW1wb3J0IGlzVW5kZWZpbmVkIGZyb20gXCJsb2Rhc2gvaXNVbmRlZmluZWRcIjtcbmltcG9ydCB7IFN1YmplY3QgfSBmcm9tIFwicnhqc1wiO1xuXG5pbXBvcnQge1xuICAgIERBVEFfUE9JTlRfTk9UX0ZPVU5ELFxuICAgIEhJR0hMSUdIVF9EQVRBX1BPSU5UX0VWRU5ULFxuICAgIEhJR0hMSUdIVF9TRVJJRVNfRVZFTlQsXG4gICAgSU5URVJBQ1RJT05fREFUQV9QT0lOVFNfRVZFTlQsXG4gICAgU0VMRUNUX0RBVEFfUE9JTlRfRVZFTlQsXG59IGZyb20gXCIuLi8uLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IFJlbmRlcmVyIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29tbW9uL3JlbmRlcmVyXCI7XG5pbXBvcnQgeyBTY2FsZXMgfSBmcm9tIFwiLi4vLi4vY29yZS9jb21tb24vc2NhbGVzL3R5cGVzXCI7XG5pbXBvcnQge1xuICAgIElEYXRhUG9pbnQsXG4gICAgSURhdGFTZXJpZXMsXG4gICAgSW50ZXJhY3Rpb25UeXBlLFxuICAgIElQb3NpdGlvbixcbiAgICBJUmFkaWFsUmVuZGVyZXJDb25maWcsXG4gICAgSVJlbmRlcmVyRXZlbnRQYXlsb2FkLFxufSBmcm9tIFwiLi4vLi4vY29yZS9jb21tb24vdHlwZXNcIjtcbmltcG9ydCB7IElSZW5kZXJTZXJpZXMsIFJlbmRlckxheWVyTmFtZSB9IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHsgSVJhZGlhbEFjY2Vzc29ycyB9IGZyb20gXCIuL2FjY2Vzc29ycy9yYWRpYWwtYWNjZXNzb3JzXCI7XG5cbi8qKlxuICogRGVmYXVsdCBjb25maWd1cmF0aW9uIGZvciBSYWRpYWwgUmVuZGVyZXJcbiAqL1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfUkFESUFMX1JFTkRFUkVSX0NPTkZJRzogSVJhZGlhbFJlbmRlcmVyQ29uZmlnID0ge1xuICAgIGFubnVsYXJXaWR0aDogMjAsXG4gICAgYW5udWxhclBhZGRpbmc6IDUsXG4gICAgbWF4VGhpY2tuZXNzOiAzMCxcbiAgICBhbm51bGFyR3Jvd3RoOiAwLjE1LFxuICAgIGN1cnNvcjogXCJkZWZhdWx0XCIsXG4gICAgZW5hYmxlU2VyaWVzSGlnaGxpZ2h0aW5nOiB0cnVlLFxuICAgIGVuYWJsZURhdGFQb2ludEhpZ2hsaWdodGluZzogdHJ1ZSxcbn07XG5cbi8qKlxuICogUmFkaWFsIHJlbmRlcmVyIGlzIGEgZ2VuZXJpYyByZW5kZXJlciB0aGF0IGlzIGFibGUgdG8gZHJhdyBwaWUgYW5kIGRvbnV0IGNoYXJ0c1xuICovXG5leHBvcnQgY2xhc3MgUmFkaWFsUmVuZGVyZXIgZXh0ZW5kcyBSZW5kZXJlcjxJUmFkaWFsQWNjZXNzb3JzPiB7XG4gICAgcHJvdGVjdGVkIHNlZ21lbnRXaWR0aD86IG51bWJlcjtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgUmFkaWFsUmVuZGVyZXIuXG4gICAgICogQHBhcmFtIHtJUmFkaWFsUmVuZGVyZXJDb25maWd9IFtjb25maWddXG4gICAgICogUmVuZGVyZXIgY29uZmlndXJhdGlvbiBvYmplY3QuIERlZmF1bHRzIHRvIGBERUZBVUxUX1JBRElBTF9SRU5ERVJFUl9DT05GSUdgIGNvbnN0YW50IHZhbHVlLlxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHB1YmxpYyBjb25maWc6IElSYWRpYWxSZW5kZXJlckNvbmZpZyA9IHt9KSB7XG4gICAgICAgIHN1cGVyKGNvbmZpZyk7XG4gICAgICAgIHRoaXMuY29uZmlnID0gZGVmYXVsdHNEZWVwKHRoaXMuY29uZmlnLCBERUZBVUxUX1JBRElBTF9SRU5ERVJFUl9DT05GSUcpO1xuICAgIH1cblxuICAgIC8qKiBTZWUge0BsaW5rIFJlbmRlcmVyI2RyYXd9ICovXG4gICAgcHVibGljIGRyYXcoXG4gICAgICAgIHJlbmRlclNlcmllczogSVJlbmRlclNlcmllczxJUmFkaWFsQWNjZXNzb3JzPixcbiAgICAgICAgcmVuZGVyZXJTdWJqZWN0OiBTdWJqZWN0PElSZW5kZXJlckV2ZW50UGF5bG9hZD5cbiAgICApOiB2b2lkIHtcbiAgICAgICAgY29uc3QgZGF0YUNvbnRhaW5lciA9IHJlbmRlclNlcmllcy5jb250YWluZXJzW1JlbmRlckxheWVyTmFtZS5kYXRhXTtcblxuICAgICAgICBjb25zdCBkYXRhID0gcmVuZGVyU2VyaWVzLmRhdGFTZXJpZXMuZGF0YTtcbiAgICAgICAgY29uc3QgYWNjZXNzb3JzID0gcmVuZGVyU2VyaWVzLmRhdGFTZXJpZXMuYWNjZXNzb3JzO1xuXG4gICAgICAgIC8vIFRPRE86IFRoaXMgaGFuZGxlcyBzZXZlcmFsIGRhdGEgcG9pbnRzIHdpdGhpbmcgb25lIHNlcmllcyBhcyB3ZWxsLiBNb3N0IHByb2JhYmx5IHRoaXMgY2FuIGJlIGFic3RyYWN0ZWQgdG8gb3RoZXIgcmVuZGVyZXJcbiAgICAgICAgY29uc3QgYXJjR2VuZXJhdG9yID0gKGQ6IGFueSwgaW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc2VwYXJhdGVBcmMgPSB0aGlzLmdldEFyYyhcbiAgICAgICAgICAgICAgICByZW5kZXJTZXJpZXMuc2NhbGVzLnIucmFuZ2UoKSxcbiAgICAgICAgICAgICAgICBhcmMoKSxcbiAgICAgICAgICAgICAgICBpbmRleFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHJldHVybiBzZXBhcmF0ZUFyYyhkKTtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5zZWdtZW50V2lkdGggPSB0aGlzLmdldFNlZ21lbnRXaWR0aChyZW5kZXJTZXJpZXMpO1xuXG4gICAgICAgIGNvbnN0IGc6IGFueSA9IGRhdGFDb250YWluZXIuc2VsZWN0QWxsKFwicGF0aC5hcmNcIikuZGF0YShkYXRhKTtcblxuICAgICAgICBnLmV4aXQoKS5yZW1vdmUoKTtcblxuICAgICAgICBnLmVudGVyKClcbiAgICAgICAgICAgIC5hcHBlbmQoXCJwYXRoXCIpXG4gICAgICAgICAgICAuYXR0cihcImNsYXNzXCIsIFwiYXJjIHBvaW50ZXItZXZlbnRzIG51aS1jaGFydC0tcGF0aF9fb3V0bGluZVwiKVxuICAgICAgICAgICAgLnN0eWxlKFwic3Ryb2tlLXdpZHRoXCIsIHRoaXMuY29uZmlnLnN0cm9rZVdpZHRoKVxuICAgICAgICAgICAgLnN0eWxlKFwiY3Vyc29yXCIsIHRoaXMuY29uZmlnLmN1cnNvcilcbiAgICAgICAgICAgIC5vbihcIm1vdXNlZW50ZXJcIiwgKGQ6IGFueSwgaTogbnVtYmVyKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0RGF0YVBvaW50SGlnaGxpZ2h0KFxuICAgICAgICAgICAgICAgICAgICByZW5kZXJTZXJpZXMsXG4gICAgICAgICAgICAgICAgICAgIGQsXG4gICAgICAgICAgICAgICAgICAgIGksXG4gICAgICAgICAgICAgICAgICAgIHJlbmRlcmVyU3ViamVjdFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLm9uKFwibW91c2VsZWF2ZVwiLCAoZDogYW55LCBpOiBudW1iZXIpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXREYXRhUG9pbnRIaWdobGlnaHQoXG4gICAgICAgICAgICAgICAgICAgIHJlbmRlclNlcmllcyxcbiAgICAgICAgICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgREFUQV9QT0lOVF9OT1RfRk9VTkQsXG4gICAgICAgICAgICAgICAgICAgIHJlbmRlcmVyU3ViamVjdFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLy8gVE9ETzogdGVzdGluZyBldmVudCwgcmVtb3ZlIGluIGZhdm9yIG9yIGdlbmVyaWMgaW50ZXJhY3Rpb24gc2V0dXBcbiAgICAgICAgICAgIC5vbihcImNsaWNrXCIsIChkOiBhbnksIGk6IG51bWJlcikgPT4ge1xuICAgICAgICAgICAgICAgIHJlbmRlcmVyU3ViamVjdC5uZXh0KHtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnROYW1lOiBTRUxFQ1RfREFUQV9QT0lOVF9FVkVOVCxcbiAgICAgICAgICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2VyaWVzSWQ6IHJlbmRlclNlcmllcy5kYXRhU2VyaWVzLmlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXg6IGksXG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhOiBkLmRhdGEsXG4gICAgICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbjogdGhpcy5nZXREYXRhUG9pbnRQb3NpdGlvbihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW5kZXJTZXJpZXMuZGF0YVNlcmllcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbmRlclNlcmllcy5zY2FsZXNcbiAgICAgICAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLm1lcmdlKGcpXG4gICAgICAgICAgICAuYXR0cihcImRcIiwgYXJjR2VuZXJhdG9yKVxuICAgICAgICAgICAgLmF0dHIoXCJmaWxsXCIsIChkOiBhbnksIGk6IG51bWJlcikgPT5cbiAgICAgICAgICAgICAgICBhY2Nlc3NvcnMuZGF0YS5jb2xvclxuICAgICAgICAgICAgICAgICAgICA/IGFjY2Vzc29ycy5kYXRhLmNvbG9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgICBkLmRhdGEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGksXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHJlbmRlclNlcmllcy5kYXRhU2VyaWVzXG4gICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICA6IGFjY2Vzc29ycy5zZXJpZXMuY29sb3I/LihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcmVuZGVyU2VyaWVzLmRhdGFTZXJpZXMuaWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHJlbmRlclNlcmllcy5kYXRhU2VyaWVzXG4gICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvKiogU2VlIHtAbGluayBSZW5kZXJlciNnZXREYXRhUG9pbnRQb3NpdGlvbn0gKi9cbiAgICBwdWJsaWMgZ2V0RGF0YVBvaW50UG9zaXRpb24oXG4gICAgICAgIGRhdGFTZXJpZXM6IElEYXRhU2VyaWVzPElSYWRpYWxBY2Nlc3NvcnM+LFxuICAgICAgICBpbmRleDogbnVtYmVyLFxuICAgICAgICBzY2FsZXM6IFNjYWxlc1xuICAgICk6IElQb3NpdGlvbiB8IHVuZGVmaW5lZCB7XG4gICAgICAgIGlmIChpbmRleCA8IDApIHtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcGllQXJjRGF0YTogRGVmYXVsdEFyY09iamVjdCA9IGRhdGFTZXJpZXMuZGF0YVtpbmRleF07XG4gICAgICAgIGNvbnN0IGRhdGFQb2ludEFyYyA9IHRoaXMuZ2V0QXJjKHNjYWxlcy5yLnJhbmdlKCksIGFyYygpLCBpbmRleCk7XG4gICAgICAgIGNvbnN0IGNlbnRyb2lkID0gZGF0YVBvaW50QXJjLmNlbnRyb2lkKHBpZUFyY0RhdGEpO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB4OiBjZW50cm9pZFswXSxcbiAgICAgICAgICAgIHk6IGNlbnRyb2lkWzFdLFxuICAgICAgICAgICAgd2lkdGg6IDAsXG4gICAgICAgICAgICBoZWlnaHQ6IDAsXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHVibGljIGdldElubmVyUmFkaXVzKHJhbmdlOiBudW1iZXJbXSwgaW5kZXg6IG51bWJlcik6IG51bWJlciB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIGlzVW5kZWZpbmVkKHRoaXMuc2VnbWVudFdpZHRoKSB8fFxuICAgICAgICAgICAgaXNVbmRlZmluZWQodGhpcy5jb25maWcuYW5udWxhclBhZGRpbmcpXG4gICAgICAgICkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2FuJ3QgY29tcHV0ZSBpbm5lciByYWRpdXNcIik7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjYWxjdWxhdGVkUmFkaXVzID1cbiAgICAgICAgICAgIHJhbmdlWzFdIC1cbiAgICAgICAgICAgIHJhbmdlWzBdIC1cbiAgICAgICAgICAgIHRoaXMuc2VnbWVudFdpZHRoIC1cbiAgICAgICAgICAgIGluZGV4ICogKHRoaXMuY29uZmlnLmFubnVsYXJQYWRkaW5nICsgdGhpcy5zZWdtZW50V2lkdGgpO1xuICAgICAgICByZXR1cm4gY2FsY3VsYXRlZFJhZGl1cyA+PSAwID8gY2FsY3VsYXRlZFJhZGl1cyA6IDA7XG4gICAgfVxuXG4gICAgcHVibGljIGdldE91dGVyUmFkaXVzKHJhbmdlOiBbbnVtYmVyLCBudW1iZXJdLCBpbmRleDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgaXNVbmRlZmluZWQodGhpcy5zZWdtZW50V2lkdGgpIHx8XG4gICAgICAgICAgICBpc1VuZGVmaW5lZCh0aGlzLmNvbmZpZy5hbm51bGFyUGFkZGluZylcbiAgICAgICAgKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW4ndCBjb21wdXRlIG91dGVyIHJhZGl1c1wiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGNhbGN1bGF0ZWRSYWRpdXMgPVxuICAgICAgICAgICAgcmFuZ2VbMV0gLVxuICAgICAgICAgICAgcmFuZ2VbMF0gLVxuICAgICAgICAgICAgaW5kZXggKiAodGhpcy5jb25maWcuYW5udWxhclBhZGRpbmcgKyB0aGlzLnNlZ21lbnRXaWR0aCk7XG4gICAgICAgIHJldHVybiBjYWxjdWxhdGVkUmFkaXVzID49IDAgPyBjYWxjdWxhdGVkUmFkaXVzIDogMDtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgZ2V0QXJjKFxuICAgICAgICByYW5nZTogW251bWJlciwgbnVtYmVyXSxcbiAgICAgICAgZ2VuZXJhdGVkQXJjOiBBcmM8YW55LCBEZWZhdWx0QXJjT2JqZWN0PixcbiAgICAgICAgaW5kZXg6IG51bWJlclxuICAgICk6IEFyYzxhbnksIERlZmF1bHRBcmNPYmplY3Q+IHtcbiAgICAgICAgY29uc3QgaW5uZXJSYWRpdXMgPSB0aGlzLmdldElubmVyUmFkaXVzKHJhbmdlLCBpbmRleCk7XG4gICAgICAgIHJldHVybiBnZW5lcmF0ZWRBcmNcbiAgICAgICAgICAgIC5vdXRlclJhZGl1cyh0aGlzLmdldE91dGVyUmFkaXVzKHJhbmdlLCBpbmRleCkpXG4gICAgICAgICAgICAuaW5uZXJSYWRpdXMoaW5uZXJSYWRpdXMpO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBnZXRTZWdtZW50V2lkdGgoXG4gICAgICAgIHJlbmRlclNlcmllczogSVJlbmRlclNlcmllczxJUmFkaWFsQWNjZXNzb3JzPlxuICAgICk6IG51bWJlciB8IHVuZGVmaW5lZCB7XG4gICAgICAgIGlmICghKHRoaXMuY29uZmlnLm1heFRoaWNrbmVzcyAmJiB0aGlzLmNvbmZpZy5hbm51bGFyR3Jvd3RoKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29uZmlnLmFubnVsYXJXaWR0aDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gTWF0aC5taW4oXG4gICAgICAgICAgICAocmVuZGVyU2VyaWVzLnNjYWxlcy5yLnJhbmdlKClbMV0gLVxuICAgICAgICAgICAgICAgIHJlbmRlclNlcmllcy5zY2FsZXMuci5yYW5nZSgpWzBdKSAqXG4gICAgICAgICAgICAgICAgdGhpcy5jb25maWcuYW5udWxhckdyb3d0aCxcbiAgICAgICAgICAgIHRoaXMuY29uZmlnLm1heFRoaWNrbmVzc1xuICAgICAgICApO1xuICAgIH1cblxuICAgIHByaXZhdGUgZW1pdERhdGFQb2ludEhpZ2hsaWdodChcbiAgICAgICAgcmVuZGVyU2VyaWVzOiBJUmVuZGVyU2VyaWVzPElSYWRpYWxBY2Nlc3NvcnM+LFxuICAgICAgICBkYXRhOiBhbnksXG4gICAgICAgIGk6IG51bWJlcixcbiAgICAgICAgcmVuZGVyZXJTdWJqZWN0OiBTdWJqZWN0PElSZW5kZXJlckV2ZW50UGF5bG9hZD5cbiAgICApIHtcbiAgICAgICAgY29uc3QgcG9zaXRpb246IElQb3NpdGlvbiB8IHVuZGVmaW5lZCA9IHRoaXMuZ2V0RGF0YVBvaW50UG9zaXRpb24oXG4gICAgICAgICAgICByZW5kZXJTZXJpZXMuZGF0YVNlcmllcyxcbiAgICAgICAgICAgIGksXG4gICAgICAgICAgICByZW5kZXJTZXJpZXMuc2NhbGVzXG4gICAgICAgICk7XG5cbiAgICAgICAgY29uc3QgZGF0YVBvaW50OiBJRGF0YVBvaW50ID0ge1xuICAgICAgICAgICAgc2VyaWVzSWQ6IHJlbmRlclNlcmllcy5kYXRhU2VyaWVzLmlkLFxuICAgICAgICAgICAgZGF0YVNlcmllczogcmVuZGVyU2VyaWVzLmRhdGFTZXJpZXMsXG4gICAgICAgICAgICBpbmRleDogaSxcbiAgICAgICAgICAgIGRhdGE6IGRhdGEsXG4gICAgICAgICAgICBwb3NpdGlvbjogcG9zaXRpb24sXG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKHRoaXMuY29uZmlnLmVuYWJsZVNlcmllc0hpZ2hsaWdodGluZykge1xuICAgICAgICAgICAgcmVuZGVyZXJTdWJqZWN0Lm5leHQoe1xuICAgICAgICAgICAgICAgIGV2ZW50TmFtZTogSElHSExJR0hUX1NFUklFU19FVkVOVCxcbiAgICAgICAgICAgICAgICBkYXRhOiBkYXRhUG9pbnQsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmNvbmZpZy5lbmFibGVEYXRhUG9pbnRIaWdobGlnaHRpbmcpIHtcbiAgICAgICAgICAgIHJlbmRlcmVyU3ViamVjdC5uZXh0KHtcbiAgICAgICAgICAgICAgICBldmVudE5hbWU6IEhJR0hMSUdIVF9EQVRBX1BPSU5UX0VWRU5ULFxuICAgICAgICAgICAgICAgIGRhdGE6IGRhdGFQb2ludCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gd2UncmUgZW1pdHRpbmcgdGhpcyBldmVudCBtYW51YWxseSwgYmVjYXVzZSBpdCdzIG5vdCB0cmlnZ2VyZWQgYnkgbW91c2UgaW50ZXJhY3RpdmUgYXJlYSBpbiB0aGlzIGNhc2VcbiAgICAgICAgcmVuZGVyZXJTdWJqZWN0Lm5leHQoe1xuICAgICAgICAgICAgZXZlbnROYW1lOiBJTlRFUkFDVElPTl9EQVRBX1BPSU5UU19FVkVOVCxcbiAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgICBpbnRlcmFjdGlvblR5cGU6IEludGVyYWN0aW9uVHlwZS5Nb3VzZU1vdmUsXG4gICAgICAgICAgICAgICAgZGF0YVBvaW50czoge1xuICAgICAgICAgICAgICAgICAgICBbcmVuZGVyU2VyaWVzLmRhdGFTZXJpZXMuaWRdOiBkYXRhUG9pbnQsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiJdfQ==