@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
140 lines • 25.2 kB
JavaScript
// © 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 { select } from "d3-selection";
import findIndex from "lodash/findIndex";
import isArray from "lodash/isArray";
import isUndefined from "lodash/isUndefined";
import { DATA_POINT_INTERACTION_RESET, DATA_POINT_NOT_FOUND, } from "../../../constants";
import { isBandScale, } from "../../../core/common/scales/types";
import { UtilityService } from "../../../core/common/utility.service";
import { RenderLayerName, RenderState, } from "../../types";
export class BarHighlightStrategy {
scaleKey;
levels;
selectedDataPointIdxFn;
/**
* @param scaleKey scale that will be used for searching for the data point that will be highlighted
* @param levels for band scales, how many levels deep do we go to compare values
*/
constructor(scaleKey, levels = 1, selectedDataPointIdxFn) {
this.scaleKey = scaleKey;
this.levels = levels;
this.selectedDataPointIdxFn = selectedDataPointIdxFn;
}
getDataPointIndex(renderer, series, values, scales) {
const value = values[this.scaleKey];
if (typeof value === "undefined") {
// if there is no value we're returning -2 (DATA_POINT_INTERACTION_RESET) which helps highlightDataPoint
// to understand that we need to emphasise things when we are moving outside of an interactive area
return DATA_POINT_INTERACTION_RESET;
}
return this.findDataPointByValue(series, value, this.scaleKey, scales);
}
findDataPointByValue(series, value, scaleKey, scales) {
const accessorSuffix = scaleKey.toUpperCase();
const dataAccessors = series.accessors.data;
const startAccessor = dataAccessors["start" + accessorSuffix];
const endAccessor = dataAccessors["end" + accessorSuffix];
if (typeof value === "string") {
return findIndex(series.data, (d, i) => value === startAccessor?.(d, i, series.data, series));
}
if (isArray(value)) {
return findIndex(series.data, (d, i) => {
const start = startAccessor?.(d, i, series.data, series);
const lengthLimit = Math.min(this.levels, value.length, start.length);
// diy efficient array comparison
for (let j = 0; j < lengthLimit; j++) {
if (value[j] !== start[j]) {
return false;
}
}
return true;
});
}
if (value.valueOf) {
const valueOf = value.valueOf();
if (scales && scales[scaleKey]?.isContinuous()) {
let index = findIndex(series.data, (d, i) => valueOf >=
startAccessor?.(d, i, series.data, series).valueOf() &&
valueOf <=
endAccessor?.(d, i, series.data, series).valueOf());
if (index === -1 && typeof endAccessor !== "undefined") {
if (isBandScale(scales[scaleKey])) {
const accessor = (d, i) => startAccessor?.(d, i, series.data, series);
const nearestIndex = UtilityService.findNearestIndex(series.data, value, accessor);
index =
nearestIndex >= series.data.length ||
accessor(series.data[nearestIndex], nearestIndex) >
valueOf
? -1
: nearestIndex;
}
else {
// @ts-ignore
// Needs to catch -1 otherwise typescript errors
index =
UtilityService.getClosestIndex(series.data, (d, i) => endAccessor(d, i, series.data, series), value) ?? -1;
}
}
return index;
}
return findIndex(series.data, (d, i) => valueOf >=
startAccessor?.(d, i, series.data, series).valueOf() &&
valueOf <=
endAccessor?.(d, i, series.data, series).valueOf());
}
return DATA_POINT_INTERACTION_RESET;
}
highlightDataPoint(renderer, renderSeries, dataPointIndex, rendererSubject) {
const target = renderSeries.containers[RenderLayerName.data];
const barStylesFn = renderer.getContainerStateStyles;
const selectedDataPointIdx = !isUndefined(this.selectedDataPointIdxFn)
? this.selectedDataPointIdxFn(renderSeries.dataSeries.id)
: DATA_POINT_NOT_FOUND;
target
.selectAll(`g.${renderer.barContainerClass}`)
.each(function (d, index) {
let renderState;
if (dataPointIndex === DATA_POINT_INTERACTION_RESET) {
if (index === selectedDataPointIdx ||
selectedDataPointIdx === DATA_POINT_NOT_FOUND) {
renderState = RenderState.default;
}
else {
renderState = RenderState.deemphasized;
}
}
else if (dataPointIndex === index ||
index === selectedDataPointIdx) {
renderState = RenderState.emphasized;
}
else {
renderState = RenderState.deemphasized;
}
select(this).attrs(barStylesFn(renderState));
});
// rendererSubject.next({
// eventName: HIGHLIGHT_SERIES_EVENT,
// data: renderer.getDataPoint(renderSeries, renderSeries.dataSeries.data[dataPointIndex], dataPointIndex),
// });
}
draw(renderer, renderSeries, rendererSubject) { }
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFyLWhpZ2hsaWdodC1zdHJhdGVneS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9yZW5kZXJlcnMvYmFyL2hpZ2hsaWdodC1zdHJhdGVnaWVzL2Jhci1oaWdobGlnaHQtc3RyYXRlZ3kudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEseURBQXlEO0FBQ3pELEVBQUU7QUFDRiwrRUFBK0U7QUFDL0UsNEVBQTRFO0FBQzVFLDhFQUE4RTtBQUM5RSwrRUFBK0U7QUFDL0UsOEVBQThFO0FBQzlFLDREQUE0RDtBQUM1RCxFQUFFO0FBQ0YsNkVBQTZFO0FBQzdFLHVEQUF1RDtBQUN2RCxFQUFFO0FBQ0YsNkVBQTZFO0FBQzdFLDRFQUE0RTtBQUM1RSwrRUFBK0U7QUFDL0UsMEVBQTBFO0FBQzFFLGlGQUFpRjtBQUNqRiw2RUFBNkU7QUFDN0UsaUJBQWlCO0FBRWpCLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDdEMsT0FBTyxTQUFTLE1BQU0sa0JBQWtCLENBQUM7QUFDekMsT0FBTyxPQUFPLE1BQU0sZ0JBQWdCLENBQUM7QUFDckMsT0FBTyxXQUFXLE1BQU0sb0JBQW9CLENBQUM7QUFHN0MsT0FBTyxFQUNILDRCQUE0QixFQUM1QixvQkFBb0IsR0FDdkIsTUFBTSxvQkFBb0IsQ0FBQztBQUM1QixPQUFPLEVBQ0gsV0FBVyxHQUdkLE1BQU0sbUNBQW1DLENBQUM7QUFFM0MsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHNDQUFzQyxDQUFDO0FBRXRFLE9BQU8sRUFHSCxlQUFlLEVBQ2YsV0FBVyxHQUNkLE1BQU0sYUFBYSxDQUFDO0FBS3JCLE1BQU0sT0FBTyxvQkFBb0I7SUFRZjtJQUNBO0lBQ0E7SUFQZDs7O09BR0c7SUFDSCxZQUNjLFFBQXlCLEVBQ3pCLFNBQVMsQ0FBQyxFQUNWLHNCQUE4QztRQUY5QyxhQUFRLEdBQVIsUUFBUSxDQUFpQjtRQUN6QixXQUFNLEdBQU4sTUFBTSxDQUFJ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Q0gsV0FBVyxHQUFHLFdBQVcsQ0FBQyxZQUFZLENBQUM7YUFDMUM7WUFDRCxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDO1FBQ2pELENBQUMsQ0FBQyxDQUFDO1FBRVAseUJBQXlCO1FBQ3pCLHlDQUF5QztRQUN6QywrR0FBK0c7UUFDL0csTUFBTTtJQUNWLENBQUM7SUFFTSxJQUFJLENBQ1AsUUFBcUIsRUFDckIsWUFBZ0QsRUFDaEQsZUFBK0MsSUFDMUMsQ0FBQztDQUNiIiwic291cmNlc0NvbnRlbnQiOlsiLy8gwqkgMjAyMiBTb2xhcldpbmRzIFdvcmxkd2lkZSwgTExDLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbi8vICBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0b1xuLy8gIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlXG4vLyAgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yXG4vLyAgc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbi8vICBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4vLyAgYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuLy8gIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuLy8gIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuLy8gIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbi8vICBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuLy8gIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU5cbi8vICBUSEUgU09GVFdBUkUuXG5cbmltcG9ydCB7IHNlbGVjdCB9IGZyb20gXCJkMy1zZWxlY3Rpb25cIjtcbmltcG9ydCBmaW5kSW5kZXggZnJvbSBcImxvZGFzaC9maW5kSW5kZXhcIjtcbmltcG9ydCBpc0FycmF5IGZyb20gXCJsb2Rhc2gvaXNBcnJheVwiO1xuaW1wb3J0IGlzVW5kZWZpbmVkIGZyb20gXCJsb2Rhc2gvaXNVbmRlZmluZWRcIjtcbmltcG9ydCB7IFN1YmplY3QgfSBmcm9tIFwicnhqc1wiO1xuXG5pbXBvcnQge1xuICAgIERBVEFfUE9JTlRfSU5URVJBQ1RJT05fUkVTRVQsXG4gICAgREFUQV9QT0lOVF9OT1RfRk9VTkQsXG59IGZyb20gXCIuLi8uLi8uLi9jb25zdGFudHNcIjtcbmltcG9ydCB7XG4gICAgaXNCYW5kU2NhbGUsXG4gICAgSVhZU2NhbGVzLFxuICAgIFNjYWxlcyxcbn0gZnJvbSBcIi4uLy4uLy4uL2NvcmUvY29tbW9uL3NjYWxlcy90eXBlc1wiO1xuaW1wb3J0IHsgSURhdGFTZXJpZXMsIElSZW5kZXJlckV2ZW50UGF5bG9hZCB9IGZyb20gXCIuLi8uLi8uLi9jb3JlL2NvbW1vbi90eXBlc1wiO1xuaW1wb3J0IHsgVXRpbGl0eVNlcnZpY2UgfSBmcm9tIFwiLi4vLi4vLi4vY29yZS9jb21tb24vdXRpbGl0eS5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBJUmVjdGFuZ2xlQWNjZXNzb3JzIH0gZnJvbSBcIi4uLy4uL2FjY2Vzc29ycy9yZWN0YW5nbGUtYWNjZXNzb3JzXCI7XG5pbXBvcnQge1xuICAgIElIaWdobGlnaHRTdHJhdGVneSxcbiAgICBJUmVuZGVyU2VyaWVzLFxuICAgIFJlbmRlckxheWVyTmFtZSxcbiAgICBSZW5kZXJTdGF0ZSxcbn0gZnJvbSBcIi4uLy4uL3R5cGVzXCI7XG5pbXBvcnQgeyBCYXJSZW5kZXJlciB9IGZyb20gXCIuLi9iYXItcmVuZGVyZXJcIjtcblxuZXhwb3J0IHR5cGUgU2VsZWN0ZWREYXRQb2ludElkeEZuID0gKHNlcmllc0lkOiBzdHJpbmcpID0+IG51bWJlcjtcblxuZXhwb3J0IGNsYXNzIEJhckhpZ2hsaWdodFN0cmF0ZWd5XG4gICAgaW1wbGVtZW50cyBJSGlnaGxpZ2h0U3RyYXRlZ3k8SVJlY3RhbmdsZUFjY2Vzc29ycywgQmFyUmVuZGVyZXI+XG57XG4gICAgLyoqXG4gICAgICogQHBhcmFtIHNjYWxlS2V5IHNjYWxlIHRoYXQgd2lsbCBiZSB1c2VkIGZvciBzZWFyY2hpbmcgZm9yIHRoZSBkYXRhIHBvaW50IHRoYXQgd2lsbCBiZSBoaWdobGlnaHRlZFxuICAgICAqIEBwYXJhbSBsZXZlbHMgZm9yIGJhbmQgc2NhbGVzLCBob3cgbWFueSBsZXZlbHMgZGVlcCBkbyB3ZSBnbyB0byBjb21wYXJlIHZhbHVlc1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBwcm90ZWN0ZWQgc2NhbGVLZXk6IGtleW9mIElYWVNjYWxlcyxcbiAgICAgICAgcHJvdGVjdGVkIGxldmVscyA9IDEsXG4gICAgICAgIHByb3RlY3RlZCBzZWxlY3RlZERhdGFQb2ludElkeEZuPzogU2VsZWN0ZWREYXRQb2ludElkeEZuXG4gICAgKSB7fVxuXG4gICAgcHVibGljIGdldERhdGFQb2ludEluZGV4KFxuICAgICAgICByZW5kZXJlcjogQmFyUmVuZGVyZXIsXG4gICAgICAgIHNlcmllczogSURhdGFTZXJpZXM8SVJlY3RhbmdsZUFjY2Vzc29ycz4sXG4gICAgICAgIHZhbHVlczogeyBbcDogc3RyaW5nXTogYW55IH0sXG4gICAgICAgIHNjYWxlczogU2NhbGVzXG4gICAgKTogbnVtYmVyIHtcbiAgICAgICAgY29uc3QgdmFsdWUgPSB2YWx1ZXNbdGhpcy5zY2FsZUtleV07XG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICAgIC8vIGlmIHRoZXJlIGlzIG5vIHZhbHVlIHdlJ3JlIHJldHVybmluZyAtMiAoREFUQV9QT0lOVF9JTlRFUkFDVElPTl9SRVNFVCkgd2hpY2ggaGVscHMgaGlnaGxpZ2h0RGF0YVBvaW50XG4gICAgICAgICAgICAvLyB0byB1bmRlcnN0YW5kIHRoYXQgd2UgbmVlZCB0byBlbXBoYXNpc2UgdGhpbmdzIHdoZW4gd2UgYXJlIG1vdmluZyBvdXRzaWRlIG9mIGFuIGludGVyYWN0aXZlIGFyZWFcbiAgICAgICAgICAgIHJldHVybiBEQVRBX1BPSU5UX0lOVEVSQUNUSU9OX1JFU0VUO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuZmluZERhdGFQb2ludEJ5VmFsdWUoc2VyaWVzLCB2YWx1ZSwgdGhpcy5zY2FsZUtleSwgc2NhbGVzKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZmluZERhdGFQb2ludEJ5VmFsdWUoXG4gICAgICAgIHNlcmllczogSURhdGFTZXJpZXM8SVJlY3RhbmdsZUFjY2Vzc29ycz4sXG4gICAgICAgIHZhbHVlOiBhbnksXG4gICAgICAgIHNjYWxlS2V5OiBrZXlvZiBJWFlTY2FsZXMsXG4gICAgICAgIHNjYWxlcz86IFNjYWxlc1xuICAgICk6IG51bWJlciB7XG4gICAgICAgIGNvbnN0IGFjY2Vzc29yU3VmZml4ID0gKHNjYWxlS2V5IGFzIHN0cmluZykudG9VcHBlckNhc2UoKTtcbiAgICAgICAgY29uc3QgZGF0YUFjY2Vzc29ycyA9IHNlcmllcy5hY2Nlc3NvcnMuZGF0YTtcblxuICAgICAgICBjb25zdCBzdGFydEFjY2Vzc29yID0gZGF0YUFjY2Vzc29yc1tcInN0YXJ0XCIgKyBhY2Nlc3NvclN1ZmZpeF07XG4gICAgICAgIGNvbnN0IGVuZEFjY2Vzc29yID0gZGF0YUFjY2Vzc29yc1tcImVuZFwiICsgYWNjZXNzb3JTdWZmaXhdO1xuXG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBmaW5kSW5kZXgoXG4gICAgICAgICAgICAgICAgc2VyaWVzLmRhdGEsXG4gICAgICAgICAgICAgICAgKGQsIGkpID0+IHZhbHVlID09PSBzdGFydEFjY2Vzc29yPy4oZCwgaSwgc2VyaWVzLmRhdGEsIHNlcmllcylcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmluZEluZGV4KHNlcmllcy5kYXRhLCAoZCwgaSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0YXJ0ID0gc3RhcnRBY2Nlc3Nvcj8uKGQsIGksIHNlcmllcy5kYXRhLCBzZXJpZXMpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGxlbmd0aExpbWl0ID0gTWF0aC5taW4oXG4gICAgICAgICAgICAgICAgICAgIHRoaXMubGV2ZWxzLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZS5sZW5ndGgsXG4gICAgICAgICAgICAgICAgICAgIHN0YXJ0Lmxlbmd0aFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgLy8gZGl5IGVmZmljaWVudCBhcnJheSBjb21wYXJpc29uXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBsZW5ndGhMaW1pdDsgaisrKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZVtqXSAhPT0gc3RhcnRbal0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmICh2YWx1ZS52YWx1ZU9mKSB7XG4gICAgICAgICAgICBjb25zdCB2YWx1ZU9mID0gdmFsdWUudmFsdWVPZigpO1xuICAgICAgICAgICAgaWYgKHNjYWxlcyAmJiBzY2FsZXNbc2NhbGVLZXldPy5pc0NvbnRpbnVvdXMoKSkge1xuICAgICAgICAgICAgICAgIGxldCBpbmRleCA9IGZpbmRJbmRleChcbiAgICAgICAgICAgICAgICAgICAgc2VyaWVzLmRhdGEsXG4gICAgICAgICAgICAgICAgICAgIChkLCBpKSA9PlxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVPZiA+PVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0QWNjZXNzb3I/LihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VyaWVzLmRhdGEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcmllc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICkudmFsdWVPZigpICYmXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZU9mIDw9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5kQWNjZXNzb3I/LihkLCBpLCBzZXJpZXMuZGF0YSwgc2VyaWVzKS52YWx1ZU9mKClcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIGlmIChpbmRleCA9PT0gLTEgJiYgdHlwZW9mIGVuZEFjY2Vzc29yICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc0JhbmRTY2FsZShzY2FsZXNbc2NhbGVLZXldKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYWNjZXNzb3IgPSAoZDogYW55LCBpOiBhbnkpID0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnRBY2Nlc3Nvcj8uKGQsIGksIHNlcmllcy5kYXRhLCBzZXJpZXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmVhcmVzdEluZGV4ID0gVXRpbGl0eVNlcnZpY2UuZmluZE5lYXJlc3RJbmRleChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXJpZXMuZGF0YSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY2Nlc3NvclxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4ID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZWFyZXN0SW5kZXggPj0gc2VyaWVzLmRhdGEubGVuZ3RoIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWNjZXNzb3Ioc2VyaWVzLmRhdGFbbmVhcmVzdEluZGV4XSwgbmVhcmVzdEluZGV4KSA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlT2ZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyAtMVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IG5lYXJlc3RJbmRleDtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5lZWRzIHRvIGNhdGNoIC0xIG90aGVyd2lzZSB0eXBlc2NyaXB0IGVycm9yc1xuICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXggPVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFV0aWxpdHlTZXJ2aWNlLmdldENsb3Nlc3RJbmRleChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VyaWVzLmRhdGEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChkLCBpKSA9PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5kQWNjZXNzb3IoZCwgaSwgc2VyaWVzLmRhdGEsIHNlcmllcyksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKSA/PyAtMTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gaW5kZXg7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZmluZEluZGV4KFxuICAgICAgICAgICAgICAgIHNlcmllcy5kYXRhLFxuICAgICAgICAgICAgICAgIChkLCBpKSA9PlxuICAgICAgICAgICAgICAgICAgICB2YWx1ZU9mID49XG4gICAgICAgICAgICAgICAgICAgICAgICBzdGFydEFjY2Vzc29yPy4oZCwgaSwgc2VyaWVzLmRhdGEsIHNlcmllcykudmFsdWVPZigpICYmXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlT2YgPD1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVuZEFjY2Vzc29yPy4oZCwgaSwgc2VyaWVzLmRhdGEsIHNlcmllcykudmFsdWVPZigpXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIERBVEFfUE9JTlRfSU5URVJBQ1RJT05fUkVTRVQ7XG4gICAgfVxuXG4gICAgcHVibGljIGhpZ2hsaWdodERhdGFQb2ludChcbiAgICAgICAgcmVuZGVyZXI6IEJhclJlbmRlcmVyLFxuICAgICAgICByZW5kZXJTZXJpZXM6IElSZW5kZXJTZXJpZXM8SVJlY3RhbmdsZUFjY2Vzc29ycz4sXG4gICAgICAgIGRhdGFQb2ludEluZGV4OiBudW1iZXIsXG4gICAgICAgIHJlbmRlcmVyU3ViamVjdDogU3ViamVjdDxJUmVuZGVyZXJFdmVudFBheWxvYWQ+XG4gICAgKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IHRhcmdldCA9IHJlbmRlclNlcmllcy5jb250YWluZXJzW1JlbmRlckxheWVyTmFtZS5kYXRhXTtcbiAgICAgICAgY29uc3QgYmFyU3R5bGVzRm4gPSByZW5kZXJlci5nZXRDb250YWluZXJTdGF0ZVN0eWxlcztcbiAgICAgICAgY29uc3Qgc2VsZWN0ZWREYXRhUG9pbnRJZHggPSAhaXNVbmRlZmluZWQodGhpcy5zZWxlY3RlZERhdGFQb2ludElkeEZuKVxuICAgICAgICAgICAgPyB0aGlzLnNlbGVjdGVkRGF0YVBvaW50SWR4Rm4ocmVuZGVyU2VyaWVzLmRhdGFTZXJpZXMuaWQpXG4gICAgICAgICAgICA6IERBVEFfUE9JTlRfTk9UX0ZPVU5EO1xuXG4gICAgICAgIHRhcmdldFxuICAgICAgICAgICAgLnNlbGVjdEFsbChgZy4ke3JlbmRlcmVyLmJhckNvbnRhaW5lckNsYXNzfWApXG4gICAgICAgICAgICAuZWFjaChmdW5jdGlvbiAoZDogYW55LCBpbmRleDogbnVtYmVyKSB7XG4gICAgICAgICAgICAgICAgbGV0IHJlbmRlclN0YXRlOiBSZW5kZXJTdGF0ZTtcbiAgICAgICAgICAgICAgICBpZiAoZGF0YVBvaW50SW5kZXggPT09IERBVEFfUE9JTlRfSU5URVJBQ1RJT05fUkVTRVQpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXggPT09IHNlbGVjdGVkRGF0YVBvaW50SWR4IHx8XG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZERhdGFQb2ludElkeCA9PT0gREFUQV9QT0lOVF9OT1RfRk9VTkRcbiAgICAgICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZW5kZXJTdGF0ZSA9IFJlbmRlclN0YXRlLmRlZmF1bHQ7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZW5kZXJTdGF0ZSA9IFJlbmRlclN0YXRlLmRlZW1waGFzaXplZDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgICAgICAgICAgIGRhdGFQb2ludEluZGV4ID09PSBpbmRleCB8fFxuICAgICAgICAgICAgICAgICAgICBpbmRleCA9PT0gc2VsZWN0ZWREYXRhUG9pbnRJZHhcbiAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgcmVuZGVyU3RhdGUgPSBSZW5kZXJTdGF0ZS5lbXBoYXNpemVkO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJlbmRlclN0YXRlID0gUmVuZGVyU3RhdGUuZGVlbXBoYXNpemVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBzZWxlY3QodGhpcykuYXR0cnMoYmFyU3R5bGVzRm4ocmVuZGVyU3RhdGUpKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIC8vIHJlbmRlcmVyU3ViamVjdC5uZXh0KHtcbiAgICAgICAgLy8gICAgIGV2ZW50TmFtZTogSElHSExJR0hUX1NFUklFU19FVkVOVCxcbiAgICAgICAgLy8gICAgIGRhdGE6IHJlbmRlcmVyLmdldERhdGFQb2ludChyZW5kZXJTZXJpZXMsIHJlbmRlclNlcmllcy5kYXRhU2VyaWVzLmRhdGFbZGF0YVBvaW50SW5kZXhdLCBkYXRhUG9pbnRJbmRleCksXG4gICAgICAgIC8vIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBkcmF3KFxuICAgICAgICByZW5kZXJlcjogQmFyUmVuZGVyZXIsXG4gICAgICAgIHJlbmRlclNlcmllczogSVJlbmRlclNlcmllczxJUmVjdGFuZ2xlQWNjZXNzb3JzPixcbiAgICAgICAgcmVuZGVyZXJTdWJqZWN0OiBTdWJqZWN0PElSZW5kZXJlckV2ZW50UGF5bG9hZD5cbiAgICApOiB2b2lkIHt9XG59XG4iXX0=