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

164 lines 30.9 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 { max, min } from "d3-array"; import { area, curveLinear } from "d3-shape"; import defaultsDeep from "lodash/defaultsDeep"; import { STANDARD_RENDER_LAYERS } from "../../constants"; import { EMPTY_CONTINUOUS_DOMAIN, } from "../../core/common/scales/types"; import { DEFAULT_MARKER_INTERACTION_CONFIG } from "../constants"; import { MarkerUtils } from "../marker-utils"; import { RenderLayerName } from "../types"; import { XYRenderer } from "../xy-renderer"; /** * Renderer that is able to draw line chart */ export class AreaRenderer extends XYRenderer { config; DEFAULT_CONFIG = { curveType: curveLinear, interactive: true, areaClass: "nui-chart-area", markerInteraction: DEFAULT_MARKER_INTERACTION_CONFIG, }; /** * Creates an instance of AreaRenderer. * @param {IAreaRendererConfig} [config={}] Renderer configuration object */ constructor(config = {}) { super(config); this.config = config; // setting default values to the properties that were not set by user this.config = defaultsDeep(this.config, this.DEFAULT_CONFIG); } /** See {@link Renderer#draw} */ draw(renderSeries, rendererSubject) { const target = renderSeries.containers[RenderLayerName.data]; const accessors = renderSeries.dataSeries.accessors; let path = target.select(`path.${this.config.areaClass}`); if (path.empty()) { if (!this.config.areaClass) { throw new Error("areaClass is not defined"); } path = target .append("path") .classed(this.config.areaClass, true) .attrs({ fill: accessors.series.color?.(renderSeries.dataSeries.id, renderSeries.dataSeries), }) .style("stroke-width", this.config.strokeWidth ?? 1); } this.drawArea(renderSeries, path); } /** * Renders the line in prepared <path> element * * @param {IRenderSeries<IAreaAccessors>} renderSeries * @param {D3Selection} path D3 Selection with <path> element pre-created and pre-styled */ drawArea(renderSeries, path) { const dataSeries = renderSeries.dataSeries; const accessors = dataSeries.accessors; let warned = false; const validatedData = dataSeries.data.filter((d, i) => { const valid = typeof accessors.data.absoluteX0?.(d, i, dataSeries.data, dataSeries) !== "undefined" && typeof accessors.data.absoluteX1?.(d, i, dataSeries.data, dataSeries) !== "undefined" && typeof accessors.data.absoluteY0?.(d, i, dataSeries.data, dataSeries) !== "undefined" && typeof accessors.data.absoluteY1?.(d, i, dataSeries.data, dataSeries) !== "undefined"; if (!valid && !warned) { console.warn("Data point", d, "was skipped as accessors didn't manage to extract any data."); console.warn(" -> accessors.data.x0:", accessors.data.x0); console.warn(" -> accessors.data.y0:", accessors.data.y0); console.warn(" -> accessors.data.x1:", accessors.data.x1); console.warn(" -> accessors.data.y1:", accessors.data.y1); warned = true; } return valid; }); if (!this.config.curveType) { throw new Error("curveType is not defined"); } const areaFunc = area() .x0((d, i) => this.safetyCheck(renderSeries.scales.x.convert(accessors.data.absoluteX0?.(d, i, dataSeries.data, dataSeries)))) .x1((d, i) => this.safetyCheck(renderSeries.scales.x.convert(accessors.data.absoluteX1?.(d, i, dataSeries.data, dataSeries)))) .y0((d, i) => this.safetyCheck(renderSeries.scales.y.convert(accessors.data.absoluteY0?.(d, i, dataSeries.data, dataSeries)))) .y1((d, i) => this.safetyCheck(renderSeries.scales.y.convert(accessors.data.absoluteY1?.(d, i, dataSeries.data, dataSeries)))) .curve(this.config.curveType); path.attr("d", areaFunc(validatedData) ?? ""); } getDomain(data, dataSeries, scaleName, scale) { if (!data || data.length === 0) { return EMPTY_CONTINUOUS_DOMAIN; } const dataAccessors = dataSeries.accessors.data; if (scaleName !== "x" && scaleName !== "y") { return [undefined, undefined]; } const accessor0 = dataAccessors[`absolute${scaleName.toUpperCase()}0`]; const accessor1 = dataAccessors[`absolute${scaleName.toUpperCase()}1`]; return [ min(data, (datum, index, arr) => min([ accessor0?.(datum, index, arr, dataSeries), accessor1?.(datum, index, arr, dataSeries), ])), max(data, (datum, index, arr) => max([ accessor0?.(datum, index, arr, dataSeries), accessor1?.(datum, index, arr, dataSeries), ])), ]; } /** See {@link Renderer#getRequiredLayers} */ getRequiredLayers() { return [ STANDARD_RENDER_LAYERS[RenderLayerName.data], STANDARD_RENDER_LAYERS[RenderLayerName.foreground], ]; } /** * Filters given dataset by domain of provided scale * * @param data * @param dataSeries * @param scaleName * @param domain */ filterDataByDomain(data, dataSeries, scaleName, domain) { const accessor0 = dataSeries.accessors.data[scaleName + "0"]; const accessor1 = dataSeries.accessors.data[scaleName + "1"]; return data.filter((d, i) => { const value0 = accessor0?.(d, i, data, dataSeries); const value1 = accessor1?.(d, i, data, dataSeries); return (Math.max(value0, value1) >= domain[0] && Math.min(value0, value1) <= domain[1]); }); } highlightDataPoint(renderSeries, dataPointIndex, rendererSubject) { const dataSeries = renderSeries.dataSeries; const accessors = dataSeries.accessors; if (!accessors.series.marker || !this.config.interactive) { return; } const container = renderSeries.containers[RenderLayerName.foreground]; MarkerUtils.manageMarker(renderSeries.dataSeries, renderSeries.scales, dataPointIndex, container, rendererSubject, this.config.markerInteraction); } safetyCheck(value) { return typeof value === "undefined" || isNaN(value) ? 0 : value; } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXJlYS1yZW5kZXJlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9yZW5kZXJlcnMvYXJlYS9hcmVhLXJlbmRlcmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLHlEQUF5RDtBQUN6RCxFQUFFO0FBQ0YsK0VBQStFO0FBQy9FLDRFQUE0RTtBQUM1RSw4RUFBOEU7QUFDOUUsK0VBQStFO0FBQy9FLDhFQUE4RTtBQUM5RSw0REFBNEQ7QUFDNUQsRUFBRTtBQUNGLDZFQUE2RTtBQUM3RSx1REFBdUQ7QUFDdkQsRUFBRTtBQUNGLDZFQUE2RTtBQUM3RSw0RUFBNEU7QUFDNUUsK0VBQStFO0FBQy9FLDBFQUEwRTtBQUMxRSxpRkFBaUY7QUFDakYsNkVBQTZFO0FBQzdFLGlCQUFpQjtBQUVqQixPQUFPLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUNwQyxPQUFPLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUM3QyxPQUFPLFlBQVksTUFBTSxxQkFBcUIsQ0FBQztBQUcvQyxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN6RCxPQUFPLEVBQ0gsdUJBQXVCLEdBRzFCLE1BQU0sZ0NBQWdDLENBQUM7QUFPeEMsT0FBTyxFQUFFLGlDQUFpQyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ2pFLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUM5QyxPQUFPLEVBQXNDLGVBQWUsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUMvRSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFHNUM7O0dBRUc7QUFDSCxNQUFNLE9BQU8sWUFBYSxTQUFRLFVBQTBCO0lBWXJDO0lBWFgsY0FBYyxHQUF3QjtRQUMxQyxTQUFTLEVBQUUsV0FBVztRQUN0QixXQUFXLEVBQUUsSUFBSTtRQUNqQixTQUFTLEVBQUUsZ0JB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QXlCO1FBQ3hDLE9BQU8sT0FBTyxLQUFLLEtBQUssV0FBVyxJQUFJLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUM7SUFDcEUsQ0FBQztDQUNKIiwic291cmNlc0NvbnRlbnQiOlsiLy8gwqkgMjAyMiBTb2xhcldpbmRzIFdvcmxkd2lkZSwgTExDLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbi8vICBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0b1xuLy8gIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlXG4vLyAgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yXG4vLyAgc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbi8vICBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4vLyAgYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuLy8gIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuLy8gIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuLy8gIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbi8vICBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuLy8gIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU5cbi8vICBUSEUgU09GVFdBUkUuXG5cbmltcG9ydCB7IG1heCwgbWluIH0gZnJvbSBcImQzLWFycmF5XCI7XG5pbXBvcnQgeyBhcmVhLCBjdXJ2ZUxpbmVhciB9IGZyb20gXCJkMy1zaGFwZVwiO1xuaW1wb3J0IGRlZmF1bHRzRGVlcCBmcm9tIFwibG9kYXNoL2RlZmF1bHRzRGVlcFwiO1xuaW1wb3J0IHsgU3ViamVjdCB9IGZyb20gXCJyeGpzXCI7XG5cbmltcG9ydCB7IFNUQU5EQVJEX1JFTkRFUl9MQVlFUlMgfSBmcm9tIFwiLi4vLi4vY29uc3RhbnRzXCI7XG5pbXBvcnQge1xuICAgIEVNUFRZX0NPTlRJTlVPVVNfRE9NQUlOLFxuICAgIElTY2FsZSxcbiAgICBJWFlTY2FsZXMsXG59IGZyb20gXCIuLi8uLi9jb3JlL2NvbW1vbi9zY2FsZXMvdHlwZXNcIjtcbmltcG9ydCB7XG4gICAgRDNTZWxlY3Rpb24sXG4gICAgSURhdGFTZXJpZXMsXG4gICAgSUxhc2FnbmFMYXllcixcbiAgICBJUmVuZGVyZXJFdmVudFBheWxvYWQsXG59IGZyb20gXCIuLi8uLi9jb3JlL2NvbW1vbi90eXBlc1wiO1xuaW1wb3J0IHsgREVGQVVMVF9NQVJLRVJfSU5URVJBQ1RJT05fQ09ORklHIH0gZnJvbSBcIi4uL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgTWFya2VyVXRpbHMgfSBmcm9tIFwiLi4vbWFya2VyLXV0aWxzXCI7XG5pbXBvcnQgeyBJQXJlYVJlbmRlcmVyQ29uZmlnLCBJUmVuZGVyU2VyaWVzLCBSZW5kZXJMYXllck5hbWUgfSBmcm9tIFwiLi4vdHlwZXNcIjtcbmltcG9ydCB7IFhZUmVuZGVyZXIgfSBmcm9tIFwiLi4veHktcmVuZGVyZXJcIjtcbmltcG9ydCB7IElBcmVhQWNjZXNzb3JzIH0gZnJvbSBcIi4vYXJlYS1hY2Nlc3NvcnNcIjtcblxuLyoqXG4gKiBSZW5kZXJlciB0aGF0IGlzIGFibGUgdG8gZHJhdyBsaW5lIGNoYXJ0XG4gKi9cbmV4cG9ydCBjbGFzcyBBcmVhUmVuZGVyZXIgZXh0ZW5kcyBYWVJlbmRlcmVyPElBcmVhQWNjZXNzb3JzPiB7XG4gICAgcHJpdmF0ZSBERUZBVUxUX0NPTkZJRzogSUFyZWFSZW5kZXJlckNvbmZpZyA9IHtcbiAgICAgICAgY3VydmVUeXBlOiBjdXJ2ZUxpbmVhcixcbiAgICAgICAgaW50ZXJhY3RpdmU6IHRydWUsXG4gICAgICAgIGFyZWFDbGFzczogXCJudWktY2hhcnQtYXJlYVwiLFxuICAgICAgICBtYXJrZXJJbnRlcmFjdGlvbjogREVGQVVMVF9NQVJLRVJfSU5URVJBQ1RJT05fQ09ORklHLFxuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGluc3RhbmNlIG9mIEFyZWFSZW5kZXJlci5cbiAgICAgKiBAcGFyYW0ge0lBcmVhUmVuZGVyZXJDb25maWd9IFtjb25maWc9e31dIFJlbmRlcmVyIGNvbmZpZ3VyYXRpb24gb2JqZWN0XG4gICAgICovXG4gICAgY29uc3RydWN0b3IocHVibGljIGNvbmZpZzogSUFyZWFSZW5kZXJlckNvbmZpZyA9IHt9KSB7XG4gICAgICAgIHN1cGVyKGNvbmZpZyk7XG4gICAgICAgIC8vIHNldHRpbmcgZGVmYXVsdCB2YWx1ZXMgdG8gdGhlIHByb3BlcnRpZXMgdGhhdCB3ZXJlIG5vdCBzZXQgYnkgdXNlclxuICAgICAgICB0aGlzLmNvbmZpZyA9IGRlZmF1bHRzRGVlcCh0aGlzLmNvbmZpZywgdGhpcy5ERUZBVUxUX0NPTkZJRyk7XG4gICAgfVxuXG4gICAgLyoqIFNlZSB7QGxpbmsgUmVuZGVyZXIjZHJhd30gKi9cbiAgICBwdWJsaWMgZHJhdyhcbiAgICAgICAgcmVuZGVyU2VyaWVzOiBJUmVuZGVyU2VyaWVzPElBcmVhQWNjZXNzb3JzPixcbiAgICAgICAgcmVuZGVyZXJTdWJqZWN0OiBTdWJqZWN0PElSZW5kZXJlckV2ZW50UGF5bG9hZD5cbiAgICApOiB2b2lkIHtcbiAgICAgICAgY29uc3QgdGFyZ2V0ID0gcmVuZGVyU2VyaWVzLmNvbnRhaW5lcnNbUmVuZGVyTGF5ZXJOYW1lLmRhdGFdO1xuXG4gICAgICAgIGNvbnN0IGFjY2Vzc29ycyA9IHJlbmRlclNlcmllcy5kYXRhU2VyaWVzLmFjY2Vzc29ycztcbiAgICAgICAgbGV0IHBhdGg6IEQzU2VsZWN0aW9uPFNWR1BhdGhFbGVtZW50PiA9IHRhcmdldC5zZWxlY3QoXG4gICAgICAgICAgICBgcGF0aC4ke3RoaXMuY29uZmlnLmFyZWFDbGFzc31gXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKHBhdGguZW1wdHkoKSkge1xuICAgICAgICAgICAgaWYgKCF0aGlzLmNvbmZpZy5hcmVhQ2xhc3MpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJhcmVhQ2xhc3MgaXMgbm90IGRlZmluZWRcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwYXRoID0gdGFyZ2V0XG4gICAgICAgICAgICAgICAgLmFwcGVuZChcInBhdGhcIilcbiAgICAgICAgICAgICAgICAuY2xhc3NlZCh0aGlzLmNvbmZpZy5hcmVhQ2xhc3MsIHRydWUpXG4gICAgICAgICAgICAgICAgLmF0dHJzKHtcbiAgICAgICAgICAgICAgICAgICAgZmlsbDogYWNjZXNzb3JzLnNlcmllcy5jb2xvcj8uKFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVuZGVyU2VyaWVzLmRhdGFTZXJpZXMuaWQsXG4gICAgICAgICAgICAgICAgICAgICAgICByZW5kZXJTZXJpZXMuZGF0YVNlcmllc1xuICAgICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLnN0eWxlKFwic3Ryb2tlLXdpZHRoXCIsIHRoaXMuY29uZmlnLnN0cm9rZVdpZHRoID8/IDEpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZHJhd0FyZWEocmVuZGVyU2VyaWVzLCBwYXRoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW5kZXJzIHRoZSBsaW5lIGluIHByZXBhcmVkIDxwYXRoPiBlbGVtZW50XG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0lSZW5kZXJTZXJpZXM8SUFyZWFBY2Nlc3NvcnM+fSByZW5kZXJTZXJpZXNcbiAgICAgKiBAcGFyYW0ge0QzU2VsZWN0aW9ufSBwYXRoIEQzIFNlbGVjdGlvbiB3aXRoIDxwYXRoPiBlbGVtZW50IHByZS1jcmVhdGVkIGFuZCBwcmUtc3R5bGVkXG4gICAgICovXG4gICAgcHVibGljIGRyYXdBcmVhKFxuICAgICAgICByZW5kZXJTZXJpZXM6IElSZW5kZXJTZXJpZXM8SUFyZWFBY2Nlc3NvcnM+LFxuICAgICAgICBwYXRoOiBEM1NlbGVjdGlvbjxTVkdQYXRoRWxlbWVudD5cbiAgICApOiB2b2lkIHtcbiAgICAgICAgY29uc3QgZGF0YVNlcmllcyA9IHJlbmRlclNlcmllcy5kYXRhU2VyaWVzO1xuICAgICAgICBjb25zdCBhY2Nlc3NvcnMgPSBkYXRhU2VyaWVzLmFjY2Vzc29ycztcblxuICAgICAgICBsZXQgd2FybmVkID0gZmFsc2U7XG4gICAgICAgIGNvbnN0IHZhbGlkYXRlZERhdGEgPSBkYXRhU2VyaWVzLmRhdGEuZmlsdGVyKChkLCBpKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB2YWxpZCA9XG4gICAgICAgICAgICAgICAgdHlwZW9mIGFjY2Vzc29ycy5kYXRhLmFic29sdXRlWDA/LihcbiAgICAgICAgICAgICAgICAgICAgZCxcbiAgICAgICAgICAgICAgICAgICAgaSxcbiAgICAgICAgICAgICAgICAgICAgZGF0YVNlcmllcy5kYXRhLFxuICAgICAgICAgICAgICAgICAgICBkYXRhU2VyaWVzXG4gICAgICAgICAgICAgICAgKSAhPT0gXCJ1bmRlZmluZWRcIiAmJlxuICAgICAgICAgICAgICAgIHR5cGVvZiBhY2Nlc3NvcnMuZGF0YS5hYnNvbHV0ZVgxPy4oXG4gICAgICAgICAgICAgICAgICAgIGQsXG4gICAgICAgICAgICAgICAgICAgIGksXG4gICAgICAgICAgICAgICAgICAgIGRhdGFTZXJpZXMuZGF0YSxcbiAgICAgICAgICAgICAgICAgICAgZGF0YVNlcmllc1xuICAgICAgICAgICAgICAgICkgIT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICAgICAgICAgICAgICB0eXBlb2YgYWNjZXNzb3JzLmRhdGEuYWJzb2x1dGVZMD8uKFxuICAgICAgICAgICAgICAgICAgICBkLFxuICAgICAgICAgICAgICAgICAgICBpLFxuICAgICAgICAgICAgICAgICAgICBkYXRhU2VyaWVzLmRhdGEsXG4gICAgICAgICAgICAgICAgICAgIGRhdGFTZXJpZXNcbiAgICAgICAgICAgICAgICApICE9PSBcInVuZGVmaW5lZFwiICYmXG4gICAgICAgICAgICAgICAgdHlwZW9mIGFjY2Vzc29ycy5kYXRhLmFic29sdXRlWTE/LihcbiAgICAgICAgICAgICAgICAgICAgZCxcbiAgICAgICAgICAgICAgICAgICAgaSxcbiAgICAgICAgICAgICAgICAgICAgZGF0YVNlcmllcy5kYXRhLFxuICAgICAgICAgICAgICAgICAgICBkYXRhU2VyaWVzXG4gICAgICAgICAgICAgICAgKSAhPT0gXCJ1bmRlZmluZWRcIjtcbiAgICAgICAgICAgIGlmICghdmFsaWQgJiYgIXdhcm5lZCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICAgICAgICAgICAgXCJEYXRhIHBvaW50XCIsXG4gICAgICAgICAgICAgICAgICAgIGQsXG4gICAgICAgICAgICAgICAgICAgIFwid2FzIHNraXBwZWQgYXMgYWNjZXNzb3JzIGRpZG4ndCBtYW5hZ2UgdG8gZXh0cmFjdCBhbnkgZGF0YS5cIlxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKFwiIC0+IGFjY2Vzc29ycy5kYXRhLngwOlwiLCBhY2Nlc3NvcnMuZGF0YS54MCk7XG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKFwiIC0+IGFjY2Vzc29ycy5kYXRhLnkwOlwiLCBhY2Nlc3NvcnMuZGF0YS55MCk7XG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKFwiIC0+IGFjY2Vzc29ycy5kYXRhLngxOlwiLCBhY2Nlc3NvcnMuZGF0YS54MSk7XG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKFwiIC0+IGFjY2Vzc29ycy5kYXRhLnkxOlwiLCBhY2Nlc3NvcnMuZGF0YS55MSk7XG4gICAgICAgICAgICAgICAgd2FybmVkID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB2YWxpZDtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKCF0aGlzLmNvbmZpZy5jdXJ2ZVR5cGUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImN1cnZlVHlwZSBpcyBub3QgZGVmaW5lZFwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGFyZWFGdW5jID0gYXJlYSgpXG4gICAgICAgICAgICAueDAoKGQ6IGFueSwgaTogbnVtYmVyKSA9PlxuICAgICAgICAgICAgICAgIHRoaXMuc2FmZXR5Q2hlY2soXG4gICAgICAgICAgICAgICAgICAgIHJlbmRlclNlcmllcy5zY2FsZXMueC5jb252ZXJ0KFxuICAgICAgICAgICAgICAgICAgICAgICAgYWNjZXNzb3JzLmRhdGEuYWJzb2x1dGVYMD8uKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhU2VyaWVzLmRhdGEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVNlcmllc1xuICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgLngxKChkOiBhbnksIGk6IG51bWJlcikgPT5cbiAgICAgICAgICAgICAgICB0aGlzLnNhZmV0eUNoZWNrKFxuICAgICAgICAgICAgICAgICAgICByZW5kZXJTZXJpZXMuc2NhbGVzLnguY29udmVydChcbiAgICAgICAgICAgICAgICAgICAgICAgIGFjY2Vzc29ycy5kYXRhLmFic29sdXRlWDE/LihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVNlcmllcy5kYXRhLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFTZXJpZXNcbiAgICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIC55MCgoZDogYW55LCBpOiBudW1iZXIpID0+XG4gICAgICAgICAgICAgICAgdGhpcy5zYWZldHlDaGVjayhcbiAgICAgICAgICAgICAgICAgICAgcmVuZGVyU2VyaWVzLnNjYWxlcy55LmNvbnZlcnQoXG4gICAgICAgICAgICAgICAgICAgICAgICBhY2Nlc3NvcnMuZGF0YS5hYnNvbHV0ZVkwPy4oXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFTZXJpZXMuZGF0YSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhU2VyaWVzXG4gICAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICApXG4gICAgICAgICAgICAueTEoKGQ6IGFueSwgaTogbnVtYmVyKSA9PlxuICAgICAgICAgICAgICAgIHRoaXMuc2FmZXR5Q2hlY2soXG4gICAgICAgICAgICAgICAgICAgIHJlbmRlclNlcmllcy5zY2FsZXMueS5jb252ZXJ0KFxuICAgICAgICAgICAgICAgICAgICAgICAgYWNjZXNzb3JzLmRhdGEuYWJzb2x1dGVZMT8uKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhU2VyaWVzLmRhdGEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVNlcmllc1xuICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgLmN1cnZlKHRoaXMuY29uZmlnLmN1cnZlVHlwZSk7XG5cbiAgICAgICAgcGF0aC5hdHRyKFwiZFwiLCBhcmVhRnVuYyh2YWxpZGF0ZWREYXRhKSA/PyBcIlwiKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0RG9tYWluKFxuICAgICAgICBkYXRhOiBhbnlbXSxcbiAgICAgICAgZGF0YVNlcmllczogSURhdGFTZXJpZXM8SUFyZWFBY2Nlc3NvcnM+LFxuICAgICAgICBzY2FsZU5hbWU6IHN0cmluZyxcbiAgICAgICAgc2NhbGU6IElTY2FsZTxhbnk+XG4gICAgKTogYW55W10ge1xuICAgICAgICBpZiAoIWRhdGEgfHwgZGF0YS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiBFTVBUWV9DT05USU5VT1VTX0RPTUFJTjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBkYXRhQWNjZXNzb3JzID0gZGF0YVNlcmllcy5hY2Nlc3NvcnMuZGF0YTtcblxuICAgICAgICBpZiAoc2NhbGVOYW1lICE9PSBcInhcIiAmJiBzY2FsZU5hbWUgIT09IFwieVwiKSB7XG4gICAgICAgICAgICByZXR1cm4gW3VuZGVmaW5lZCwgdW5kZWZpbmVkXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGFjY2Vzc29yMCA9IGRhdGFBY2Nlc3NvcnNbYGFic29sdXRlJHtzY2FsZU5hbWUudG9VcHBlckNhc2UoKX0wYF07XG4gICAgICAgIGNvbnN0IGFjY2Vzc29yMSA9IGRhdGFBY2Nlc3NvcnNbYGFic29sdXRlJHtzY2FsZU5hbWUudG9VcHBlckNhc2UoKX0xYF07XG5cbiAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgIG1pbihkYXRhLCAoZGF0dW0sIGluZGV4LCBhcnIpID0+XG4gICAgICAgICAgICAgICAgbWluKFtcbiAgICAgICAgICAgICAgICAgICAgYWNjZXNzb3IwPy4oZGF0dW0sIGluZGV4LCBhcnIgYXMgYW55W10sIGRhdGFTZXJpZXMpLFxuICAgICAgICAgICAgICAgICAgICBhY2Nlc3NvcjE/LihkYXR1bSwgaW5kZXgsIGFyciBhcyBhbnlbXSwgZGF0YVNlcmllcyksXG4gICAgICAgICAgICAgICAgXSlcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICBtYXgoZGF0YSwgKGRhdHVtLCBpbmRleCwgYXJyKSA9PlxuICAgICAgICAgICAgICAgIG1heChbXG4gICAgICAgICAgICAgICAgICAgIGFjY2Vzc29yMD8uKGRhdHVtLCBpbmRleCwgYXJyIGFzIGFueVtdLCBkYXRhU2VyaWVzKSxcbiAgICAgICAgICAgICAgICAgICAgYWNjZXNzb3IxPy4oZGF0dW0sIGluZGV4LCBhcnIgYXMgYW55W10sIGRhdGFTZXJpZXMpLFxuICAgICAgICAgICAgICAgIF0pXG4gICAgICAgICAgICApLFxuICAgICAgICBdO1xuICAgIH1cblxuICAgIC8qKiBTZWUge0BsaW5rIFJlbmRlcmVyI2dldFJlcXVpcmVkTGF5ZXJzfSAqL1xuICAgIHB1YmxpYyBnZXRSZXF1aXJlZExheWVycygpOiBJTGFzYWduYUxheWVyW10ge1xuICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgU1RBTkRBUkRfUkVOREVSX0xBWUVSU1tSZW5kZXJMYXllck5hbWUuZGF0YV0sXG4gICAgICAgICAgICBTVEFOREFSRF9SRU5ERVJfTEFZRVJTW1JlbmRlckxheWVyTmFtZS5mb3JlZ3JvdW5kXSxcbiAgICAgICAgXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGaWx0ZXJzIGdpdmVuIGRhdGFzZXQgYnkgZG9tYWluIG9mIHByb3ZpZGVkIHNjYWxlXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZGF0YVxuICAgICAqIEBwYXJhbSBkYXRhU2VyaWVzXG4gICAgICogQHBhcmFtIHNjYWxlTmFtZVxuICAgICAqIEBwYXJhbSBkb21haW5cbiAgICAgKi9cbiAgICBwdWJsaWMgZmlsdGVyRGF0YUJ5RG9tYWluKFxuICAgICAgICBkYXRhOiBhbnlbXSxcbiAgICAgICAgZGF0YVNlcmllczogSURhdGFTZXJpZXM8SUFyZWFBY2Nlc3NvcnM+LFxuICAgICAgICBzY2FsZU5hbWU6IHN0cmluZyxcbiAgICAgICAgZG9tYWluOiBhbnlbXVxuICAgICk6IGFueVtdIHtcbiAgICAgICAgY29uc3QgYWNjZXNzb3IwID0gZGF0YVNlcmllcy5hY2Nlc3NvcnMuZGF0YVtzY2FsZU5hbWUgKyBcIjBcIl07XG4gICAgICAgIGNvbnN0IGFjY2Vzc29yMSA9IGRhdGFTZXJpZXMuYWNjZXNzb3JzLmRhdGFbc2NhbGVOYW1lICsgXCIxXCJdO1xuXG4gICAgICAgIHJldHVybiBkYXRhLmZpbHRlcigoZCwgaSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgdmFsdWUwID0gYWNjZXNzb3IwPy4oZCwgaSwgZGF0YSwgZGF0YVNlcmllcyk7XG4gICAgICAgICAgICBjb25zdCB2YWx1ZTEgPSBhY2Nlc3NvcjE/LihkLCBpLCBkYXRhLCBkYXRhU2VyaWVzKTtcblxuICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICBNYXRoLm1heCh2YWx1ZTAsIHZhbHVlMSkgPj0gZG9tYWluWzBdICYmXG4gICAgICAgICAgICAgICAgTWF0aC5taW4odmFsdWUwLCB2YWx1ZTEpIDw9IGRvbWFpblsxXVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIGhpZ2hsaWdodERhdGFQb2ludChcbiAgICAgICAgcmVuZGVyU2VyaWVzOiBJUmVuZGVyU2VyaWVzPElBcmVhQWNjZXNzb3JzPixcbiAgICAgICAgZGF0YVBvaW50SW5kZXg6IG51bWJlcixcbiAgICAgICAgcmVuZGVyZXJTdWJqZWN0OiBTdWJqZWN0PElSZW5kZXJlckV2ZW50UGF5bG9hZD5cbiAgICApOiB2b2lkIHtcbiAgICAgICAgY29uc3QgZGF0YVNlcmllcyA9IHJlbmRlclNlcmllcy5kYXRhU2VyaWVzO1xuICAgICAgICBjb25zdCBhY2Nlc3NvcnMgPSBkYXRhU2VyaWVzLmFjY2Vzc29ycztcbiAgICAgICAgaWYgKCFhY2Nlc3NvcnMuc2VyaWVzLm1hcmtlciB8fCAhdGhpcy5jb25maWcuaW50ZXJhY3RpdmUpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGNvbnRhaW5lciA9IHJlbmRlclNlcmllcy5jb250YWluZXJzW1JlbmRlckxheWVyTmFtZS5mb3JlZ3JvdW5kXTtcbiAgICAgICAgTWFya2VyVXRpbHMubWFuYWdlTWFya2VyKFxuICAgICAgICAgICAgcmVuZGVyU2VyaWVzLmRhdGFTZXJpZXMsXG4gICAgICAgICAgICByZW5kZXJTZXJpZXMuc2NhbGVzIGFzIElYWVNjYWxlcyxcbiAgICAgICAgICAgIGRhdGFQb2ludEluZGV4LFxuICAgICAgICAgICAgY29udGFpbmVyLFxuICAgICAgICAgICAgcmVuZGVyZXJTdWJqZWN0LFxuICAgICAgICAgICAgdGhpcy5jb25maWcubWFya2VySW50ZXJhY3Rpb25cbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgc2FmZXR5Q2hlY2sodmFsdWU6IG51bWJlciB8IHVuZGVmaW5lZCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT09IFwidW5kZWZpbmVkXCIgfHwgaXNOYU4odmFsdWUpID8gMCA6IHZhbHVlO1xuICAgIH1cbn1cbiJdfQ==