@apptane/react-ui-charts
Version:
Chart components in Apptane React UI framework
516 lines (463 loc) • 65.1 kB
JavaScript
import _defineProperty from "@babel/runtime/helpers/defineProperty";
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
import { useComponentId, warning } from "@apptane/react-ui-core";
import { useColorMode, useTheme } from "@apptane/react-ui-theme";
import { css } from "@emotion/react";
import { Children, cloneElement, Fragment, isValidElement, useMemo, useState } from "react";
import { scaleBand, scaleLinear, scaleTime } from "d3-scale";
import { timeFormat } from "d3-time-format";
import { ChartNumericDataContext, ChartOrdinalDataContext, ChartTimeDataContext } from "../parts/ChartDataContext.js";
import { ChartEmptyBlock } from "../parts/ChartEmptyBlock.js";
import { ChartLinearAxis } from "../parts/ChartLinearAxis.js";
import { ChartLinearGrid } from "../parts/ChartLinearGrid.js";
import { ChartOrdinalAxis } from "../parts/ChartOrdinalAxis.js";
import { ChartOrdinalGrid } from "../parts/ChartOrdinalGrid.js";
import { ChartSliceContext } from "../parts/ChartSliceContext.js";
import { ChartTimeAxis } from "../parts/ChartTimeAxis.js";
import { ChartTimeGrid } from "../parts/ChartTimeGrid.js";
import { scaleBandInvert } from "./common.js";
import { XYBarChartPane } from "./XYBarChartPane.js";
import { XYBubbleChartPane } from "./XYBubbleChartPane.js";
import { XYLineChartPane } from "./XYLineChartPane.js";
import { XYScatterChartPane } from "./XYScatterChartPane.js";
import { jsx as _jsx } from "@emotion/react/jsx-runtime";
import { jsxs as _jsxs } from "@emotion/react/jsx-runtime";
const StyleContainer = (back, gap) => /*#__PURE__*/css("background:", back, ";position:relative;display:flex;flex-direction:column;align-items:stretch;align-content:stretch;justify-content:center;overflow:visible;svg{display:block;overflow:visible;}>div+div{margin-top:", gap, "px;}" + (process.env.NODE_ENV === "production" ? "" : ";label:StyleContainer;"), process.env.NODE_ENV === "production" ? "" : "/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy94eS9YWUNoYXJ0LnRzeCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFxQ3dEIiwiZmlsZSI6Ii4uLy4uL3NyYy94eS9YWUNoYXJ0LnRzeCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbG9yLCBDb2xvck1vZGUsIFBhbGV0dGUsIHVzZUNvbXBvbmVudElkLCB3YXJuaW5nIH0gZnJvbSBcIkBhcHB0YW5lL3JlYWN0LXVpLWNvcmVcIjtcbmltcG9ydCB7IFRoZW1lLCB1c2VDb2xvck1vZGUsIHVzZVRoZW1lIH0gZnJvbSBcIkBhcHB0YW5lL3JlYWN0LXVpLXRoZW1lXCI7XG5pbXBvcnQgeyBjc3MgfSBmcm9tIFwiQGVtb3Rpb24vcmVhY3RcIjtcbmltcG9ydCB7IENoaWxkcmVuLCBjbG9uZUVsZW1lbnQsIEZyYWdtZW50LCBpc1ZhbGlkRWxlbWVudCwgdXNlTWVtbywgdXNlU3RhdGUgfSBmcm9tIFwicmVhY3RcIjtcbmltcG9ydCB7IHNjYWxlQmFuZCwgc2NhbGVMaW5lYXIsIHNjYWxlVGltZSB9IGZyb20gXCJkMy1zY2FsZVwiO1xuaW1wb3J0IHsgdGltZUZvcm1hdCB9IGZyb20gXCJkMy10aW1lLWZvcm1hdFwiO1xuaW1wb3J0IHsgRG9tYWluVHlwZSwgRG9tYWluWFZhbHVlIH0gZnJvbSBcIi4uL2NvbW1vbi9UeXBlcy5qc1wiO1xuaW1wb3J0IHtcbiAgQ2hhcnREYXRhLFxuICBDaGFydE51bWVyaWNEYXRhQ29udGV4dCxcbiAgQ2hhcnRPcmRpbmFsRGF0YUNvbnRleHQsXG4gIENoYXJ0VGltZURhdGFDb250ZXh0LFxufSBmcm9tIFwiLi4vcGFydHMvQ2hhcnREYXRhQ29udGV4dC5qc1wiO1xuaW1wb3J0IHsgQ2hhcnRFbXB0eUJsb2NrIH0gZnJvbSBcIi4uL3BhcnRzL0NoYXJ0RW1wdHlCbG9jay5qc1wiO1xuaW1wb3J0IHsgQ2hhcnRMaW5lYXJBeGlzIH0gZnJvbSBcIi4uL3BhcnRzL0NoYXJ0TGluZWFyQXhpcy5qc1wiO1xuaW1wb3J0IHsgQ2hhcnRMaW5lYXJHcmlkIH0gZnJvbSBcIi4uL3BhcnRzL0NoYXJ0TGluZWFyR3JpZC5qc1wiO1xuaW1wb3J0IHsgQ2hhcnRPcmRpbmFsQXhpcyB9IGZyb20gXCIuLi9wYXJ0cy9DaGFydE9yZGluYWxBeGlzLmpzXCI7XG5pbXBvcnQgeyBDaGFydE9yZGluYWxHcmlkIH0gZnJvbSBcIi4uL3BhcnRzL0NoYXJ0T3JkaW5hbEdyaWQuanNcIjtcbmltcG9ydCB7IENoYXJ0U2xpY2UgfSBmcm9tIFwiLi4vcGFydHMvQ2hhcnRTbGljZS5qc1wiO1xuaW1wb3J0IHsgQ2hhcnRTbGljZUNvbnRleHQgfSBmcm9tIFwiLi4vcGFydHMvQ2hhcnRTbGljZUNvbnRleHQuanNcIjtcbmltcG9ydCB7IENoYXJ0VGltZUF4aXMgfSBmcm9tIFwiLi4vcGFydHMvQ2hhcnRUaW1lQXhpcy5qc1wiO1xuaW1wb3J0IHsgQ2hhcnRUaW1lR3JpZCB9IGZyb20gXCIuLi9wYXJ0cy9DaGFydFRpbWVHcmlkLmpzXCI7XG5pbXBvcnQgeyBzY2FsZUJhbmRJbnZlcnQgfSBmcm9tIFwiLi9jb21tb24uanNcIjtcbmltcG9ydCB7IFhZQmFyQ2hhcnRQYW5lIH0gZnJvbSBcIi4vWFlCYXJDaGFydFBhbmUuanNcIjtcbmltcG9ydCB7IFhZQnViYmxlQ2hhcnRQYW5lIH0gZnJvbSBcIi4vWFlCdWJibGVDaGFydFBhbmUuanNcIjtcbmltcG9ydCB7XG4gIFhZQ2hhcnRQYW5lUHJvcHMsXG4gIFhZQ2hhcnRQYW5lUHJvcHNFeCxcbiAgWFlDaGFydFBhbmVQcm9wc0V4QmFzZSxcbiAgWFlDaGFydFByb3BzLFxuICBYWU51bWVyaWNDaGFydFByb3BzLFxuICBYWU9yZGluYWxDaGFydFByb3BzLFxuICBYWVRpbWVDaGFydFByb3BzLFxufSBmcm9tIFwiLi9YWUNoYXJ0LnR5cGVzLmpzXCI7XG5pbXBvcnQgeyBYWUxpbmVDaGFydFBhbmUgfSBmcm9tIFwiLi9YWUxpbmVDaGFydFBhbmUuanNcIjtcbmltcG9ydCB7IFhZU2NhdHRlckNoYXJ0UGFuZSB9IGZyb20gXCIuL1hZU2NhdHRlckNoYXJ0UGFuZS5qc1wiO1xuXG5jb25zdCBTdHlsZUNvbnRhaW5lciA9IChiYWNrOiBDb2xvciwgZ2FwOiBudW1iZXIpID0+IGNzc2BcbiAgYmFja2dyb3VuZDogJHtiYWNrfTtcblxuICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gIGFsaWduLWl0ZW1zOiBzdHJldGNoO1xuICBhbGlnbi1jb250ZW50OiBzdHJldGNoO1xuICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgb3ZlcmZsb3c6IHZpc2libGU7XG5cbiAgLy8gcmVxdWlyZWQgdG8gZm9yY2UgY29ycmVjdCBoZWlnaHQgb24gdGhlIHdyYXBwZXIgZGl2XG4gIHN2ZyB7XG4gICAgZGlzcGxheTogYmxvY2s7XG4gICAgb3ZlcmZsb3c6IHZpc2libGU7XG4gIH1cblxuICA+IGRpdiArIGRpdiB7XG4gICAgbWFyZ2luLXRvcDogJHtnYXB9cHg7XG4gIH1cbmA7XG5cbmZ1bmN0aW9uIGNvbXB1dGVQYW5lSGVpZ2h0cyhwYW5lczogUmVhY3QuUmVhY3ROb2RlLCBnYXA6IG51bWJlcikge1xuICBsZXQgdG90YWxQYW5lSGVpZ2h0ID0gMDtcbiAgbGV0IHRvdGFsUGFuZUNvdW50ID0gMDtcbiAgbGV0IGR5bmFtaWNQYW5lQ291bnQgPSAwO1xuXG4gIENoaWxkcmVuLmZvckVhY2gocGFuZXMsIChwYW5lKSA9PiB7XG4gICAgaWYgKGlzVmFsaWRFbGVtZW50KHBhbmUpKSB7XG4gICAgICBjb25zdCBpdGVtID0gcGFuZSBhcyBSZWFjdC5SZWFjdEVsZW1lbnQ8WFlDaGFydFBhbmVQcm9wcz47XG4gICAgICB0b3RhbFBhbmVDb3VudCsrO1xuXG4gICAgICBpZiAoaXRlbS5wcm9wcy5oZWlnaHQgIT0gbnVsbCkge1xuICAgICAgICB0b3RhbFBhbmVIZWlnaHQgKz0gaXRlbS5wcm9wcy5oZWlnaHQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkeW5hbWljUGFuZUNvdW50Kys7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICB0b3RhbFBhbmVIZWlnaHQgKz0gKHRvdGFsUGFuZUNvdW50IC0gMSkgKiBnYXA7XG4gIHJldHVybiB7IHRvdGFsUGFuZUhlaWdodCwgdG90YWxQYW5lQ291bnQsIGR5bmFtaWNQYW5lQ291bnQgfTtcbn1cblxudHlwZSBTdmdXcmFwcGVyUHJvcHMgPSB7XG4gIGNoaWxkcmVuOiBSZWFjdC5SZWFjdE5vZGU7XG4gIHdpZHRoOiBudW1iZXI7XG4gIGhlaWdodDogbnVtYmVyO1xuICBjb21wb25lbnRJZDogc3RyaW5nO1xuICBiYWNrZ3JvdW5kOiBDb2xvcjtcbn07XG5cbmNvbnN0IFN2Z1dyYXBwZXIgPSAoeyBjaGlsZHJlbiwgd2lkdGgsIGhlaWdodCwgY29tcG9uZW50SWQsIGJhY2tncm91bmQgfTogU3ZnV3JhcHBlclByb3BzKSA9PiAoXG4gIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHJvbGU9XCJpbWdcIiBoZWlnaHQ9e2hlaWdodH0gd2lkdGg9e3dpZHRofT5cbiAgICA8ZGVmcz5cbiAgICAgIDxmaWx0ZXIgeD17LTAuMn0geT17MH0gd2lkdGg9ezEuMn0gaGVpZ2h0PXsxfSBpZD17YCR7Y29tcG9uZW50SWR9LWF4aXMtdGl0bGUtYmFja2B9PlxuICAgICAgICA8ZmVGbG9vZCBmbG9vZENvbG9yPXtiYWNrZ3JvdW5kfSByZXN1bHQ9XCJiZ1wiIC8+XG4gICAgICAgIDxmZU1lcmdlPlxuICAgICAgICAgIDxmZU1lcmdlTm9kZSBpbj1cImJnXCIgLz5cbiAgICAgICAgICA8ZmVNZXJnZU5vZGUgaW49XCJTb3VyY2VHcmFwaGljXCIgLz5cbiAgICAgICAgPC9mZU1lcmdlPlxuICAgICAgPC9maWx0ZXI+XG4gICAgPC9kZWZzPlxuICAgIHtjaGlsZHJlbn1cbiAgPC9zdmc+XG4pO1xuXG50eXBlIFhZQ2hhcnRQcm9wc0V4ID0ge1xuICBjaGFydElkOiBzdHJpbmc7XG4gIHRoZW1lOiBUaGVtZTtcbiAgcGFsZXR0ZTogUGFsZXR0ZTtcbiAgY29sb3JNb2RlOiBDb2xvck1vZGU7XG4gIGJhY2tncm91bmQ6IENvbG9yO1xuICBkb21haW5YVHlwZTogRG9tYWluVHlwZTtcbiAgZXh0ZW50OiBudW1iZXI7XG4gIHBhbmVHYXA6IG51bWJlcjtcbiAgYXhpc1hIZWlnaHQ6IG51bWJlcjtcbiAgYXhpc1hWaXNpYmxlOiBib29sZWFuO1xuICBheGlzWVdpZHRoOiBudW1iZXI7XG4gIGF4aXNQYWRkaW5nOiBudW1iZXI7XG4gIHNldFNsaWNlOiBSZWFjdC5EaXNwYXRjaDxSZWFjdC5TZXRTdGF0ZUFjdGlvbjxDaGFydFNsaWNlIHwgdW5kZWZpbmVkPj47XG59O1xuXG50eXBlIFhZQ2hhcnRQYW5lczxYIGV4dGVuZHMgRG9tYWluWFZhbHVlPiA9IFhZQ2hhcnRQcm9wcyAmXG4gIFhZQ2hhcnRQcm9wc0V4ICYge1xuICAgIGZvcm1hdERvbWFpbj86ICh2YWx1ZTogWCkgPT4gc3RyaW5nO1xuICAgIGZvcm1hdFRvb2x0aXA/OiAodmFsdWU6IFgpID0+IHN0cmluZztcbiAgICBncmlkWDogKHA6IFhZQ2hhcnRQYW5lUHJvcHNFeEJhc2UpID0+IFJlYWN0LlJlYWN0Tm9kZTtcbiAgfTtcblxuLyoqXG4gKiBDb21wdXRlcyBhbmQgc2V0cyBpbmRpdmlkdWFsIHBhbmVzIGdlb21ldHJ5ICh3aWR0aCBhbmQgaGVpZ2h0KS5cbiAqL1xuY29uc3QgWFlDaGFydFBhbmVzID0gPFggZXh0ZW5kcyBEb21haW5YVmFsdWU+KHtcbiAgY2hpbGRyZW4sXG4gIHRoZW1lLFxuICBwYWxldHRlLFxuICBjb2xvck1vZGUsXG4gIGNvbG9yU2NoZW1lLFxuICBkb21haW5YVHlwZSxcbiAgd2lkdGgsXG4gIGhlaWdodCxcbiAgZXh0ZW50LFxuICBwYW5lR2FwLFxuICBheGlzWEhlaWdodCxcbiAgYXhpc1hWaXNpYmxlLFxuICBncmlkWFZpc2libGUsXG4gIGF4aXNZV2lkdGgsXG4gIGF4aXNQYWRkaW5nLFxuICBncmlkWCxcbiAgYXhpc1hUaXRsZSxcbiAgc2V0U2xpY2UsXG4gIGZvcm1hdERvbWFpbixcbiAgZm9ybWF0VG9vbHRpcCxcbiAgZW1wdHlUZXh0LFxuICBvdmVybGF5cyxcbiAgYmFja2dyb3VuZCxcbn06IFhZQ2hhcnRQYW5lczxYPikgPT4ge1xuICBjb25zdCB7IHRvdGFsUGFuZUhlaWdodCwgZHluYW1pY1BhbmVDb3VudCB9ID0gY29tcHV0ZVBhbmVIZWlnaHRzKGNoaWxkcmVuLCBwYW5lR2FwKTtcblxuICBsZXQgZHluYW1pY1BhbmVIZWlnaHQgPSAwO1xuICBpZiAoZHluYW1pY1BhbmVDb3VudCA+IDApIHtcbiAgICBpZiAoaGVpZ2h0ID09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcImBoZWlnaHRgIGlzIHJlcXVpcmVkIHVubGVzcyBhbGwgcGFuZXMgaGF2ZSB0aGVpciBoZWlnaHQgc3BlY2lmaWVkLlwiKTtcbiAgICB9XG5cbiAgICBkeW5hbWljUGFuZUhlaWdodCA9IChoZWlnaHQgLSB0b3RhbFBhbmVIZWlnaHQgLSAoYXhpc1hWaXNpYmxlID8gYXhpc1hIZWlnaHQgOiAwKSkgLyBkeW5hbWljUGFuZUNvdW50O1xuICB9XG5cbiAgY29uc3QgdmlzdWFsU3R5bGUgPSB0aGVtZS5jaGFydHMueHkuc3R5bGU7XG4gIGNvbnN0IHBhbmVzOiBKU1guRWxlbWVudFtdID0gW107XG4gIENoaWxkcmVuLmZvckVhY2goY2hpbGRyZW4sIChjaGlsZCkgPT4ge1xuICAgIGlmIChpc1ZhbGlkRWxlbWVudChjaGlsZCkpIHtcbiAgICAgIGNvbnN0IGl0ZW0gPSBjaGlsZCBhcyBSZWFjdC5SZWFjdEVsZW1lbnQ8WFlDaGFydFBhbmVQcm9wcz47XG4gICAgICBjb25zdCBwYW5lQWN0dWFsSGVpZ2h0ID0gaXRlbS5wcm9wcy5oZWlnaHQgPz8gZHluYW1pY1BhbmVIZWlnaHQ7XG5cbiAgICAgIC8vIGhlaWdodCBvY2N1cGllZCBieSB0aGUgaGVhZGVyIGFuZCBZIGF4aXMgdGl0bGUgd2hlbiBzcGVjaWZpZWRcbiAgICAgIGNvbnN0IGxlZ2VuZFZpc2libGUgPSBpdGVtLnByb3BzLmxlZ2VuZFZpc2libGUgJiYgaXRlbS5wcm9wcy5kYXRhICE9IG51bGwgJiYgaXRlbS5wcm9wcy5kYXRhLmxlbmd0aCA+IDA7XG5cbiAgICAgIGxldCBoZWFkZXJIZWlnaHQgPSBpdGVtLnByb3BzLmhlYWRlciB8fCBsZWdlbmRWaXNpYmxlID8gdmlzdWFsU3R5bGUuaGVhZGVyLmhlaWdodCA6IDA7XG4gICAgICBpZiAoaXRlbS5wcm9wcy5heGlzWVRpdGxlKSB7XG4gICAgICAgIGhlYWRlckhlaWdodCArPSB2aXN1YWxTdHlsZS55QXhpcy50aXRsZUhlaWdodCArIHZpc3VhbFN0eWxlLnlBeGlzLnRpdGxlU3BhY2luZztcbiAgICAgIH1cblxuICAgICAgaWYgKGhlYWRlckhlaWdodCA+IDApIHtcbiAgICAgICAgaGVhZGVySGVpZ2h0ICs9IHZpc3VhbFN0eWxlLmhlYWRlci5zcGFjaW5nO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBtZXJnZWRPdmVybGF5cyA9XG4gICAgICAgIG92ZXJsYXlzICE9IG51bGxcbiAgICAgICAgICA/IGNoaWxkLnByb3BzLm92ZXJsYXlzICE9IG51bGxcbiAgICAgICAgICAgID8gWy4uLm92ZXJsYXlzLCAuLi5jaGlsZC5wcm9wcy5vdmVybGF5c11cbiAgICAgICAgICAgIDogb3ZlcmxheXNcbiAgICAgICAgICA6IGNoaWxkLnByb3BzLm92ZXJsYXlzO1xuXG4gICAgICBwYW5lcy5wdXNoKFxuICAgICAgICBjbG9uZUVsZW1lbnQ8WFlDaGFydFBhbmVQcm9wc0V4PFg+PihjaGlsZCwge1xuICAgICAgICAgIGtleTogY2hpbGQua2V5ID8/IGBwYW5lLSR7cGFuZXMubGVuZ3RofWAsXG4gICAgICAgICAgdGhlbWU6IHRoZW1lLFxuICAgICAgICAgIHBhbGV0dGU6IHBhbGV0dGUsXG4gICAgICAgICAgYmFja2dyb3VuZDogYmFja2dyb3VuZCxcbiAgICAgICAgICBjb2xvck1vZGU6IGNvbG9yTW9kZSxcbiAgICAgICAgICBjb2xvclNjaGVtZTogY2hpbGQucHJvcHMuY29sb3JTY2hlbWUgPz8gY29sb3JTY2hlbWUsXG4gICAgICAgICAgZW1wdHlUZXh0OiBjaGlsZC5wcm9wcy5lbXB0eVRleHQgPz8gZW1wdHlUZXh0LFxuICAgICAgICAgIGRvbWFpblhUeXBlOiBkb21haW5YVHlwZSxcbiAgICAgICAgICBoZWlnaHQ6IHBhbmVBY3R1YWxIZWlnaHQsXG4gICAgICAgICAgd2lkdGg6IHdpZHRoLFxuICAgICAgICAgIGF4aXNQYWRkaW5nOiBheGlzUGFkZGluZyxcbiAgICAgICAgICBheGlzWVdpZHRoOiBheGlzWVdpZHRoLFxuICAgICAgICAgIGdyaWRYVmlzaWJsZTogY2hpbGQucHJvcHMuZ3JpZFhWaXNpYmxlID8/IGdyaWRYVmlzaWJsZSxcbiAgICAgICAgICBoZWFkZXJIZWlnaHQ6IGhlYWRlckhlaWdodCxcbiAgICAgICAgICBleHRlbnRYOiBleHRlbnQsXG4gICAgICAgICAgZXh0ZW50WTogTWF0aC5tYXgoMCwgcGFuZUFjdHVhbEhlaWdodCAtIGhlYWRlckhlaWdodCksXG4gICAgICAgICAgc2V0U2xpY2U6IHNldFNsaWNlLFxuICAgICAgICAgIGF4aXNYVGl0bGU6IGF4aXNYVGl0bGUsXG4gICAgICAgICAgZm9ybWF0WFRvb2x0aXA6IGZvcm1hdFRvb2x0aXAgPz8gZm9ybWF0RG9tYWluLFxuICAgICAgICAgIGdyaWRYOiBncmlkWCxcbiAgICAgICAgICBvdmVybGF5czogbWVyZ2VkT3ZlcmxheXMsXG4gICAgICAgIH0pXG4gICAgICApO1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIDxGcmFnbWVudD57cGFuZXN9PC9GcmFnbWVudD47XG59O1xuXG5jb25zdCBEZWZhdWx0Rm9ybWF0VGltZVRvb2x0aXAgPSB0aW1lRm9ybWF0KFwiJWQgJWIgJVksICVJOiVNICVwIChVVEMgJVopXCIpO1xuXG5jb25zdCBYWVRpbWVDaGFydCA9IChwcm9wczogWFlUaW1lQ2hhcnRQcm9wcyAmIFhZQ2hhcnRQcm9wc0V4KSA9PiB7XG4gIGNvbnN0IHsgZG9tYWluVHlwZSwgZG9tYWluLCBkb21haW5OaWNlLCB3aWR0aCwgZXh0ZW50LCBheGlzWEhlaWdodCwgYXhpc1hWaXNpYmxlIH0gPSBwcm9wcztcbiAgY29uc3QgW3NjYWxlLCBjb250ZXh0LCBncmlkWF0gPSB1c2VNZW1vKCgpID0+IHtcbiAgICBjb25zdCBzY2FsZSA9IHNjYWxlVGltZSgpXG4gICAgICAucmFuZ2VSb3VuZChbMCwgZXh0ZW50XSlcbiAgICAgIC5kb21haW4oZG9tYWluID8/IFtdKTtcblxuICAgIGlmIChkb21haW5OaWNlKSB7XG4gICAgICBzY2FsZS5uaWNlKCk7XG4gICAgfVxuXG4gICAgY29uc3QgY29udGV4dDogQ2hhcnREYXRhPERhdGU+ID0ge1xuICAgICAgZG9tYWluVHlwZTogZG9tYWluVHlwZSxcbiAgICAgIHNjYWxlWDogc2NhbGUsXG4gICAgICBpbnZlcnRYOiBzY2FsZS5pbnZlcnQsXG4gICAgICBjb21wYXJlWDogKGEsIGIpID0+IHtcbiAgICAgICAgY29uc3QgZCA9IGEuZ2V0VGltZSgpIC0gYi5nZXRUaW1lKCk7XG4gICAgICAgIHJldHVybiBkIDwgMCA/IC0xIDogZCA+IDAgPyAxIDogMDtcbiAgICAgIH0sXG4gICAgfTtcblxuICAgIGNvbnN0IGdyaWRYID0gKHA6IFhZQ2hhcnRQYW5lUHJvcHNFeEJhc2UpID0+IChcbiAgICAgIDxDaGFydFRpbWVHcmlkXG4gICAgICAgIGtleT1cImdyaWRYXCJcbiAgICAgICAgb3JpZW50YXRpb249XCJ2ZXJ0aWNhbFwiXG4gICAgICAgIGNvbXBvbmVudElkPXtwLmNvbXBvbmVudElkfVxuICAgICAgICB0aGVtZT17cC50aGVtZX1cbiAgICAgICAgY29sb3JNb2RlPXtwLmNvbG9yTW9kZX1cbiAgICAgICAgbGVmdD17cC5heGlzWVdpZHRofVxuICAgICAgICB3aWR0aD17cC5leHRlbnRYfVxuICAgICAgICBoZWlnaHQ9e3AuZXh0ZW50WX1cbiAgICAgICAgdGlja1ZhbHVlcz17cHJvcHMuYXhpc1hWYWx1ZXN9XG4gICAgICAgIHNjYWxlPXtzY2FsZX1cbiAgICAgIC8+XG4gICAgKTtcblxuICAgIHJldHVybiBbc2NhbGUsIGNvbnRleHQsIGdyaWRYXTtcbiAgfSwgW2RvbWFpblR5cGUsIGRvbWFpbiwgZG9tYWluTmljZSwgZXh0ZW50LCBwcm9wcy5heGlzWFZhbHVlc10pO1xuXG4gIHJldHVybiAoXG4gICAgPENoYXJ0VGltZURhdGFDb250ZXh0LlByb3ZpZGVyIHZhbHVlPXtjb250ZXh0fT5cbiAgICAgIDxYWUNoYXJ0UGFuZXM8RGF0ZT4gey4uLnByb3BzfSBmb3JtYXRUb29sdGlwPXtwcm9wcy5mb3JtYXRUb29sdGlwID8/IERlZmF1bHRGb3JtYXRUaW1lVG9vbHRpcH0gZ3JpZFg9e2dyaWRYfSAvPlxuICAgICAge2F4aXNYVmlzaWJsZSAmJiAoXG4gICAgICAgIDxTdmdXcmFwcGVyIHdpZHRoPXt3aWR0aH0gaGVpZ2h0PXtheGlzWEhlaWdodH0gY29tcG9uZW50SWQ9e3Byb3BzLmNoYXJ0SWR9IGJhY2tncm91bmQ9e3Byb3BzLmJhY2tncm91bmR9PlxuICAgICAgICAgIDxDaGFydFRpbWVBeGlzXG4gICAgICAgICAgICBjb21wb25lbnRJZD17cHJvcHMuY2hhcnRJZH1cbiAgICAgICAgICAgIHRoZW1lPXtwcm9wcy50aGVtZX1cbiAgICAgICAgICAgIGNvbG9yTW9kZT17cHJvcHMuY29sb3JNb2RlfVxuICAgICAgICAgICAgb3JpZW50YXRpb249XCJ4XCJcbiAgICAgICAgICAgIG9mZnNldD17cHJvcHMuYXhpc1lXaWR0aH1cbiAgICAgICAgICAgIHNwYW49e2F4aXNYSGVpZ2h0fVxuICAgICAgICAgICAgdGV4dE9mZnNldD17OH1cbiAgICAgICAgICAgIHRpY2tTaXplPXs0fVxuICAgICAgICAgICAgdGlja1ZhbHVlcz17cHJvcHMuYXhpc1hWYWx1ZXN9XG4gICAgICAgICAgICBmb3JtYXQ9e3Byb3BzLmZvcm1hdERvbWFpbn1cbiAgICAgICAgICAgIHNjYWxlPXtzY2FsZX1cbiAgICAgICAgICAgIHRpdGxlPXtwcm9wcy5heGlzWFRpdGxlfVxuICAgICAgICAgIC8+XG4gICAgICAgIDwvU3ZnV3JhcHBlcj5cbiAgICAgICl9XG4gICAgPC9DaGFydFRpbWVEYXRhQ29udGV4dC5Qcm92aWRlcj5cbiAgKTtcbn07XG5cbmNvbnN0IERlZmF1bHRGb3JtYXROdW1lcmljVG9vbHRpcCA9ICh2OiBudW1iZXIpID0+IHYudG9Mb2NhbGVTdHJpbmcoKTtcblxuY29uc3QgWFlOdW1lcmljQ2hhcnQgPSAocHJvcHM6IFhZTnVtZXJpY0NoYXJ0UHJvcHMgJiBYWUNoYXJ0UHJvcHNFeCkgPT4ge1xuICBjb25zdCB7IGRvbWFpblR5cGUsIGRvbWFpbiwgZG9tYWluTmljZSwgd2lkdGgsIGV4dGVudCwgYXhpc1hIZWlnaHQsIGF4aXNYVmlzaWJsZSB9ID0gcHJvcHM7XG4gIGNvbnN0IFtzY2FsZSwgY29udGV4dCwgZ3JpZFhdID0gdXNlTWVtbygoKSA9PiB7XG4gICAgY29uc3Qgc2NhbGUgPSBzY2FsZUxpbmVhcigpXG4gICAgICAucmFuZ2VSb3VuZChbMCwgZXh0ZW50XSlcbiAgICAgIC5kb21haW4oZG9tYWluID8/IFtdKTtcblxuICAgIGlmIChkb21haW5OaWNlKSB7XG4gICAgICBzY2FsZS5uaWNlKCk7XG4gICAgfVxuXG4gICAgY29uc3QgY29udGV4dDogQ2hhcnREYXRhPG51bWJlcj4gPSB7XG4gICAgICBkb21haW5UeXBlOiBkb21haW5UeXBlLFxuICAgICAgc2NhbGVYOiBzY2FsZSxcbiAgICAgIGludmVydFg6IHNjYWxlLmludmVydCxcbiAgICAgIGNvbXBhcmVYOiAoYSwgYikgPT4gKGEgPT09IGIgPyAwIDogYSA8IGIgPyAtMSA6IDEpLFxuICAgIH07XG5cbiAgICBjb25zdCBncmlkWCA9IChwOiBYWUNoYXJ0UGFuZVByb3BzRXhCYXNlKSA9PiAoXG4gICAgICA8Q2hhcnRMaW5lYXJHcmlkXG4gICAgICAgIGtleT1cImdyaWRYXCJcbiAgICAgICAgb3JpZW50YXRpb249XCJ2ZXJ0aWNhbFwiXG4gICAgICAgIGNvbXBvbmVudElkPXtwLmNvbXBvbmVudElkfVxuICAgICAgICB0aGVtZT17cC50aGVtZX1cbiAgICAgICAgY29sb3JNb2RlPXtwLmNvbG9yTW9kZX1cbiAgICAgICAgbGVmdD17cC5heGlzWVdpZHRofVxuICAgICAgICB3aWR0aD17cC5leHRlbnRYfVxuICAgICAgICBoZWlnaHQ9e3AuZXh0ZW50WX1cbiAgICAgICAgdGlja1ZhbHVlcz17cHJvcHMuYXhpc1hWYWx1ZXN9XG4gICAgICAgIHNjYWxlPXtzY2FsZX1cbiAgICAgIC8+XG4gICAgKTtcblxuICAgIHJldHVybiBbc2NhbGUsIGNvbnRleHQsIGdyaWRYXTtcbiAgfSwgW2RvbWFpblR5cGUsIGRvbWFpbiwgZG9tYWluTmljZSwgZXh0ZW50LCBwcm9wcy5heGlzWFZhbHVlc10pO1xuXG4gIHJldHVybiAoXG4gICAgPENoYXJ0TnVtZXJpY0RhdGFDb250ZXh0LlByb3ZpZGVyIHZhbHVlPXtjb250ZXh0fT5cbiAgICAgIDxYWUNoYXJ0UGFuZXM8bnVtYmVyPlxuICAgICAgICB7Li4ucHJvcHN9XG4gICAgICAgIGZvcm1hdFRvb2x0aXA9e3Byb3BzLmZvcm1hdFRvb2x0aXAgPz8gRGVmYXVsdEZvcm1hdE51bWVyaWNUb29sdGlwfVxuICAgICAgICBncmlkWD17Z3JpZFh9XG4gICAgICAvPlxuICAgICAge2F4aXNYVmlzaWJsZSAmJiAoXG4gICAgICAgIDxTdmdXcmFwcGVyIHdpZHRoPXt3aWR0aH0gaGVpZ2h0PXtheGlzWEhlaWdodH0gY29tcG9uZW50SWQ9e3Byb3BzLmNoYXJ0SWR9IGJhY2tncm91bmQ9e3Byb3BzLmJhY2tncm91bmR9PlxuICAgICAgICAgIDxDaGFydExpbmVhckF4aXNcbiAgICAgICAgICAgIGNvbXBvbmVudElkPXtwcm9wcy5jaGFydElkfVxuICAgICAgICAgICAgdGhlbWU9e3Byb3BzLnRoZW1lfVxuICAgICAgICAgICAgY29sb3JNb2RlPXtwcm9wcy5jb2xvck1vZGV9XG4gICAgICAgICAgICBvcmllbnRhdGlvbj1cInhcIlxuICAgICAgICAgICAgb2Zmc2V0PXtwcm9wcy5heGlzWVdpZHRofVxuICAgICAgICAgICAgc3Bhbj17YXhpc1hIZWlnaHR9XG4gICAgICAgICAgICB0ZXh0T2Zmc2V0PXs4fVxuICAgICAgICAgICAgdGlja1NpemU9ezR9XG4gICAgICAgICAgICB0aWNrVmFsdWVzPXtwcm9wcy5heGlzWFZhbHVlc31cbiAgICAgICAgICAgIGZvcm1hdD17cHJvcHMuZm9ybWF0RG9tYWlufVxuICAgICAgICAgICAgc2NhbGU9e3NjYWxlfVxuICAgICAgICAgICAgdGl0bGU9e3Byb3BzLmF4aXNYVGl0bGV9XG4gICAgICAgICAgLz5cbiAgICAgICAgPC9TdmdXcmFwcGVyPlxuICAgICAgKX1cbiAgICA8L0NoYXJ0TnVtZXJpY0RhdGFDb250ZXh0LlByb3ZpZGVyPlxuICApO1xufTtcblxuY29uc3QgWFlPcmRpbmFsQ2hhcnQgPSAocHJvcHM6IFhZT3JkaW5hbENoYXJ0UHJvcHMgJiBYWUNoYXJ0UHJvcHNFeCkgPT4ge1xuICBjb25zdCB7IGRvbWFpblR5cGUsIGRvbWFpbiwgd2lkdGgsIGV4dGVudCwgYXhpc1hIZWlnaHQsIGF4aXNQYWRkaW5nLCBheGlzWFZpc2libGUgfSA9IHByb3BzO1xuICBjb25zdCBbc2NhbGUsIGNvbnRleHQsIGdyaWRYXSA9IHVzZU1lbW8oKCkgPT4ge1xuICAgIGNvbnN0IGRvbWFpblggPSBkb21haW4gPz8gW107XG5cbiAgICBjb25zdCBwYWRkaW5nID0gYXhpc1BhZGRpbmcgPz8gMDtcbiAgICBjb25zdCBzY2FsZSA9IHNjYWxlQmFuZCgpXG4gICAgICAucmFuZ2VSb3VuZChbMCwgZXh0ZW50XSlcbiAgICAgIC5kb21haW4oZG9tYWluWClcbiAgICAgIC5wYWRkaW5nT3V0ZXIocGFkZGluZyAqIDAuNSlcbiAgICAgIC5wYWRkaW5nSW5uZXIocGFkZGluZyk7XG5cbiAgICBjb25zdCBiYW5kd2lkdGggPSBzY2FsZS5iYW5kd2lkdGgoKTtcbiAgICBjb25zdCBoYWxmID0gYmFuZHdpZHRoICogMC41O1xuICAgIGNvbnN0IHNjYWxlWCA9ICh2OiBzdHJpbmcpID0+IHtcbiAgICAgIGNvbnN0IHggPSBzY2FsZSh2KTtcbiAgICAgIHJldHVybiB4ICE9IG51bGwgPyB4ICsgaGFsZiA6IHVuZGVmaW5lZDtcbiAgICB9O1xuXG4gICAgLy8gYnVpbGQgYSBsb29rdXAgbWFwIHVzaW5nIG9yaWdpbmFsIGRvbWFpbiBvcmRlciBmb3Igc29ydGluZ1xuICAgIGNvbnN0IGxvb2t1cCA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7XG4gICAgZG9tYWluWC5tYXAoKHZhbHVlLCBpbmRleCkgPT4gbG9va3VwLnNldCh2YWx1ZSwgaW5kZXgpKTtcbiAgICBjb25zdCBjb21wYXJlID0gKGE6IHN0cmluZywgYjogc3RyaW5nKSA9PiB7XG4gICAgICBjb25zdCBkID0gKGxvb2t1cC5nZXQoYSkgPz8gLTEpIC0gKGxvb2t1cC5nZXQoYikgPz8gLTEpO1xuICAgICAgcmV0dXJuIGQgPCAwID8gLTEgOiBkID4gMCA/IDEgOiAwO1xuICAgIH07XG5cbiAgICBjb25zdCBjb250ZXh0OiBDaGFydERhdGE8c3RyaW5nPiA9IHtcbiAgICAgIGRvbWFpblR5cGU6IGRvbWFpblR5cGUsXG4gICAgICBzY2FsZVg6IHNjYWxlWCxcbiAgICAgIGludmVydFg6IHNjYWxlQmFuZEludmVydChzY2FsZSksXG4gICAgICBjb21wYXJlWDogY29tcGFyZSxcbiAgICAgIGJhbmR3aWR0aDogYmFuZHdpZHRoLFxuICAgIH07XG5cbiAgICBjb25zdCBncmlkWCA9IChwOiBYWUNoYXJ0UGFuZVByb3BzRXhCYXNlKSA9PiAoXG4gICAgICA8Q2hhcnRPcmRpbmFsR3JpZFxuICAgICAgICBrZXk9XCJncmlkWFwiXG4gICAgICAgIG9yaWVudGF0aW9uPVwidmVydGljYWxcIlxuICAgICAgICBjb21wb25lbnRJZD17cC5jb21wb25lbnRJZH1cbiAgICAgICAgdGhlbWU9e3AudGhlbWV9XG4gICAgICAgIGNvbG9yTW9kZT17cC5jb2xvck1vZGV9XG4gICAgICAgIGxlZnQ9e3AuYXhpc1lXaWR0aH1cbiAgICAgICAgd2lkdGg9e3AuZXh0ZW50WH1cbiAgICAgICAgaGVpZ2h0PXtwLmV4dGVudFl9XG4gICAgICAgIHNjYWxlPXtzY2FsZX1cbiAgICAgIC8+XG4gICAgKTtcblxuICAgIHJldHVybiBbc2NhbGUsIGNvbnRleHQsIGdyaWRYXTtcbiAgfSwgW2RvbWFpblR5cGUsIGRvbWFpbiwgZXh0ZW50LCBheGlzUGFkZGluZ10pO1xuXG4gIHJldHVybiAoXG4gICAgPENoYXJ0T3JkaW5hbERhdGFDb250ZXh0LlByb3ZpZGVyIHZhbHVlPXtjb250ZXh0fT5cbiAgICAgIDxYWUNoYXJ0UGFuZXM8c3RyaW5nPiB7Li4ucHJvcHN9IGdyaWRYPXtncmlkWH0gLz5cbiAgICAgIHtheGlzWFZpc2libGUgJiYgKFxuICAgICAgICA8U3ZnV3JhcHBlciB3aWR0aD17d2lkdGh9IGhlaWdodD17YXhpc1hIZWlnaHR9IGNvbXBvbmVudElkPXtwcm9wcy5jaGFydElkfSBiYWNrZ3JvdW5kPXtwcm9wcy5iYWNrZ3JvdW5kfT5cbiAgICAgICAgICA8Q2hhcnRPcmRpbmFsQXhpc1xuICAgICAgICAgICAgY29tcG9uZW50SWQ9e3Byb3BzLmNoYXJ0SWR9XG4gICAgICAgICAgICB0aGVtZT17cHJvcHMudGhlbWV9XG4gICAgICAgICAgICBjb2xvck1vZGU9e3Byb3BzLmNvbG9yTW9kZX1cbiAgICAgICAgICAgIG9yaWVudGF0aW9uPVwieFwiXG4gICAgICAgICAgICBvZmZzZXQ9e3Byb3BzLmF4aXNZV2lkdGh9XG4gICAgICAgICAgICBzcGFuPXtheGlzWEhlaWdodH1cbiAgICAgICAgICAgIHRleHRPZmZzZXQ9ezh9XG4gICAgICAgICAgICB0aWNrU2l6ZT17MH1cbiAgICAgICAgICAgIHRpY2tWaXNpYmxlPXtmYWxzZX1cbiAgICAgICAgICAgIHRpY2tWYWx1ZXM9e3Byb3BzLmF4aXNYVmFsdWVzfVxuICAgICAgICAgICAgZm9ybWF0PXtwcm9wcy5mb3JtYXREb21haW59XG4gICAgICAgICAgICBzY2FsZT17c2NhbGV9XG4gICAgICAgICAgICB0aXRsZT17cHJvcHMuYXhpc1hUaXRsZX1cbiAgICAgICAgICAvPlxuICAgICAgICA8L1N2Z1dyYXBwZXI+XG4gICAgICApfVxuICAgIDwvQ2hhcnRPcmRpbmFsRGF0YUNvbnRleHQuUHJvdmlkZXI+XG4gICk7XG59O1xuXG4vKipcbiAqIGBYWUNoYXJ0YCBjb21wb25lbnQg4oCUIHByZXNlbnRzIG1ldHJpY3Mgb24gWFkgcGxhbmUgdGhhdCBhcmUgYmFzZWRcbiAqIGluIGNvbnRpbnVvdXMgZG9tYWluICh0aW1lIGFuZCBudW1lcmljKSBvciBvcmRpbmFsIGRvbWFpbi5cbiAqIE1ldHJpY3MgY2FuIGJlIHZpc3VhbGl6ZWQgYXMgbGluZS9hcmVhLCBiYXIsIG9yIGJ1YmJsZSBzZXJpZXMuXG4gKiBTdXBwb3J0cyBvbmUgb3IgbW9yZSBwYW5lcyBzaGFyaW5nIHRoZSBzYW1lIHByaW1hcnkgWCBkb21haW4sIGJ1dFxuICogaGF2aW5nIGluZGVwZW5kZW50IFksIGFuZCBvcHRpb25hbGx5IFosIHJhbmdlcyBhbmQgdmlzdWFsaXphdGlvblxuICogcHJvcGVydGllcy5cbiAqL1xuZnVuY3Rpb24gWFlDaGFydChwcm9wczogWFlDaGFydFByb3BzKSB7XG4gIGNvbnN0IHsgYXhpc1hWaXNpYmxlID0gdHJ1ZSwgYXhpc1lXaWR0aCA9IDQwLCBheGlzUGFkZGluZyA9IDAuMiB9ID0gcHJvcHM7XG5cbiAgY29uc3QgdGhlbWUgPSB1c2VUaGVtZSgpO1xuICBjb25zdCBjb2xvck1vZGUgPSB1c2VDb2xvck1vZGUocHJvcHMuY29sb3JNb2RlKTtcbiAgY29uc3QgcGFsZXR0ZSA9IHRoZW1lLnBhbGV0dGVbY29sb3JNb2RlXTtcbiAgY29uc3QgdmlzdWFsQXBwZWFyYW5jZSA9IHRoZW1lLmNoYXJ0cy54eS5hcHBlYXJhbmNlKHBhbGV0dGUsIGNvbG9yTW9kZSwgdW5kZWZpbmVkLCBcIm5vbmVcIik7XG4gIGNvbnN0IHZpc3VhbFN0eWxlID0gdGhlbWUuY2hhcnRzLnh5LnN0eWxlO1xuXG4gIGNvbnN0IFtzbGljZSwgc2V0U2xpY2VdID0gdXNlU3RhdGU8Q2hhcnRTbGljZSB8IHVuZGVmaW5lZD4odW5kZWZpbmVkKTtcblxuICBjb25zdCBwcm9wc0V4OiBPbWl0PFhZQ2hhcnRQcm9wc0V4LCBcImRvbWFpblhUeXBlXCI+ID0ge1xuICAgIGNoYXJ0SWQ6IHVzZUNvbXBvbmVudElkKFwiLS1hcHB0YW5lLWNoYXJ0XCIpLFxuICAgIHRoZW1lOiB0aGVtZSxcbiAgICBjb2xvck1vZGU6IGNvbG9yTW9kZSxcbiAgICBwYWxldHRlOiBwYWxldHRlLFxuICAgIGJhY2tncm91bmQ6IHByb3BzLmJhY2tncm91bmQgPz8gdmlzdWFsQXBwZWFyYW5jZS5iYWNrLFxuICAgIGV4dGVudDogTWF0aC5tYXgoMCwgcHJvcHMud2lkdGggLSBheGlzWVdpZHRoKSwgLy8gdmlld3BvcnQgZXh0ZW50IGZvciBkYXRhIHNlcmllcywgaS5lLiBYIGRvbWFpblxuICAgIGF4aXNZV2lkdGg6IGF4aXNZV2lkdGgsXG4gICAgcGFuZUdhcDogdmlzdWFsU3R5bGUuZ2FwLFxuICAgIGF4aXNYSGVpZ2h0OiB2aXN1YWxTdHlsZS54QXhpcy5oZWlnaHQsXG4gICAgYXhpc1hWaXNpYmxlOiBheGlzWFZpc2libGUsXG4gICAgYXhpc1BhZGRpbmc6IGF4aXNQYWRkaW5nLFxuICAgIHNldFNsaWNlOiBzZXRTbGljZSxcbiAgfTtcblxuICBsZXQgY2hhcnQ6IFJlYWN0LlJlYWN0Tm9kZTtcbiAgaWYgKHByb3BzLmRvbWFpbiAhPSBudWxsICYmIHByb3BzLmRvbWFpbi5sZW5ndGggPiAwKSB7XG4gICAgc3dpdGNoIChwcm9wcy5kb21haW5UeXBlKSB7XG4gICAgICBjYXNlIFwidGltZVwiOlxuICAgICAgICBpZiAocHJvcHMuZG9tYWluLmxlbmd0aCAhPT0gMikge1xuICAgICAgICAgIHdhcm5pbmcoZmFsc2UsIFwiYGRvbWFpbmAgbXVzdCBjb250YWluIGV4YWN0bHkgdHdvIGVsZW1lbnRzLCBwcm9wZXJ0eSBpZ25vcmVkXCIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNoYXJ0ID0gPFhZVGltZUNoYXJ0IHsuLi5wcm9wc30gey4uLnByb3BzRXh9IGRvbWFpblhUeXBlPVwidGltZVwiIC8+O1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIFwibnVtZXJpY1wiOlxuICAgICAgICBpZiAocHJvcHMuZG9tYWluLmxlbmd0aCAhPT0gMikge1xuICAgICAgICAgIHdhcm5pbmcoZmFsc2UsIFwiYGRvbWFpbmAgbXVzdCBjb250YWluIGV4YWN0bHkgdHdvIGVsZW1lbnRzLCBwcm9wZXJ0eSBpZ25vcmVkYFwiKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjaGFydCA9IDxYWU51bWVyaWNDaGFydCB7Li4ucHJvcHN9IHsuLi5wcm9wc0V4fSBkb21haW5YVHlwZT1cIm51bWVyaWNcIiAvPjtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBcIm9yZGluYWxcIjpcbiAgICAgICAgY2hhcnQgPSA8WFlPcmRpbmFsQ2hhcnQgey4uLnByb3BzfSB7Li4ucHJvcHNFeH0gZG9tYWluWFR5cGU9XCJvcmRpbmFsXCIgLz47XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIGlmIChjaGFydCA9PSBudWxsKSB7XG4gICAgbGV0IGhlaWdodCA9IHByb3BzLmhlaWdodDtcbiAgICBpZiAoaGVpZ2h0ID09IG51bGwpIHtcbiAgICAgIGNvbnN0IHsgdG90YWxQYW5lSGVpZ2h0LCBkeW5hbWljUGFuZUNvdW50IH0gPSBjb21wdXRlUGFuZUhlaWdodHMocHJvcHMuY2hpbGRyZW4sIHByb3BzRXgucGFuZUdhcCk7XG4gICAgICBpZiAoZHluYW1pY1BhbmVDb3VudCA+IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiYGhlaWdodGAgaXMgcmVxdWlyZWQgdW5sZXNzIGFsbCBwYW5lcyBoYXZlIHRoZWlyIGhlaWdodCBzcGVjaWZpZWQuXCIpO1xuICAgICAgfVxuICAgICAgaGVpZ2h0ID0gdG90YWxQYW5lSGVpZ2h0O1xuICAgIH1cblxuICAgIGNoYXJ0ID0gKFxuICAgICAgPENoYXJ0RW1wdHlCbG9ja1xuICAgICAgICB0aGVtZT17dGhlbWV9XG4gICAgICAgIGNvbG9yTW9kZT17Y29sb3JNb2RlfVxuICAgICAgICBiYWNrZ3JvdW5kPXtwcm9wcy5iYWNrZ3JvdW5kfVxuICAgICAgICB3aWR0aD17cHJvcHMud2lkdGh9XG4gICAgICAgIGhlaWdodD17aGVpZ2h0fVxuICAgICAgICB0b3A9ezB9XG4gICAgICAgIGxlZnQ9ezB9PlxuICAgICAgICB7cHJvcHMuZW1wdHlUZXh0fVxuICAgICAgPC9DaGFydEVtcHR5QmxvY2s+XG4gICAgKTtcbiAgfVxuXG4gIHJldHVybiAoXG4gICAgPENoYXJ0U2xpY2VDb250ZXh0LlByb3ZpZGVyIHZhbHVlPXtzbGljZX0+XG4gICAgICA8ZGl2XG4gICAgICAgIGNzcz17W1xuICAgICAgICAgIFN0eWxlQ29udGFpbmVyKHByb3BzLmJhY2tncm91bmQgPz8gdmlzdWFsQXBwZWFyYW5jZS5iYWNrLCB2aXN1YWxTdHlsZS5nYXApLFxuICAgICAgICAgIHsgd2lkdGg6IHByb3BzLndpZHRoLCBoZWlnaHQ6IHByb3BzLmhlaWdodCB9LFxuICAgICAgICBdfT5cbiAgICAgICAge2NoYXJ0fVxuICAgICAgPC9kaXY+XG4gICAgPC9DaGFydFNsaWNlQ29udGV4dC5Qcm92aWRlcj5cbiAgKTtcbn1cblxuLyoqXG4gKiBgTGluZWAg4oCUIGEgcGFuZSBpbiB0aGUgY2hhcnQgZGlzcGxheWluZyBvbmUgb3IgbW9yZSBtZXRyaWNzIGFzIGxpbmUgb3IgYXJlYSBwbG90cy5cbiAqL1xuWFlDaGFydC5MaW5lID0gWFlMaW5lQ2hhcnRQYW5lO1xuXG4vKipcbiAqIGBCYXJgIOKAlCBhIHBhbmUgaW4gdGhlIGNoYXJ0IGRpc3BsYXlpbmcgb25lIG9yIG1vcmUgbWV0cmljcyBhcyBiYXJzLlxuICovXG5YWUNoYXJ0LkJhciA9IFhZQmFyQ2hhcnRQYW5lO1xuXG4vKipcbiAqIGBCdWJibGVgIOKAlCBhIHBhbmUgaW4gdGhlIGNoYXJ0IGRpc3BsYXlpbmcgb25lIG9yIG1vcmUgbWV0cmljcyBhcyBidWJibGVzLlxuICogQWxsb3dzIHJlcHJlc2VudGluZyBkYXRhIHRoYXQgcmVzaWRlcyB3aXRoaW4gdHdvIGRvbWFpbnMuXG4gKi9cblhZQ2hhcnQuQnViYmxlID0gWFlCdWJibGVDaGFydFBhbmU7XG5cbi8qKlxuICogYFNjYXR0ZXJgIOKAlCBhIHBhbmUgaW4gdGhlIGNoYXJ0IGRpc3BsYXlpbmcgb25lIG9yIG1vcmUgbWV0cmljcyBhcyBidWJibGVzLlxuICogQWxsb3dzIHJlcHJlc2VudGluZyBkYXRhIHRoYXQgcmVzaWRlcyB3aXRoaW4gdHdvIGRvbWFpbnMuXG4gKi9cblhZQ2hhcnQuU2NhdHRlciA9IFhZU2NhdHRlckNoYXJ0UGFuZTtcblxuWFlDaGFydC5kaXNwbGF5TmFtZSA9IFwiWFlDaGFydFwiO1xuZXhwb3J0IGRlZmF1bHQgWFlDaGFydDtcbiJdfQ== */");
function computePaneHeights(panes, gap) {
let totalPaneHeight = 0;
let totalPaneCount = 0;
let dynamicPaneCount = 0;
Children.forEach(panes, pane => {
if ( /*#__PURE__*/isValidElement(pane)) {
const item = pane;
totalPaneCount++;
if (item.props.height != null) {
totalPaneHeight += item.props.height;
} else {
dynamicPaneCount++;
}
}
});
totalPaneHeight += (totalPaneCount - 1) * gap;
return {
totalPaneHeight,
totalPaneCount,
dynamicPaneCount
};
}
const SvgWrapper = _ref => {
let {
children,
width,
height,
componentId,
background
} = _ref;
return _jsxs("svg", {
xmlns: "http://www.w3.org/2000/svg",
role: "img",
height: height,
width: width,
children: [_jsx("defs", {
children: _jsxs("filter", {
x: -0.2,
y: 0,
width: 1.2,
height: 1,
id: "".concat(componentId, "-axis-title-back"),
children: [_jsx("feFlood", {
floodColor: background,
result: "bg"
}), _jsxs("feMerge", {
children: [_jsx("feMergeNode", {
in: "bg"
}), _jsx("feMergeNode", {
in: "SourceGraphic"
})]
})]
})
}), children]
});
};
/**
* Computes and sets individual panes geometry (width and height).
*/
const XYChartPanes = _ref2 => {
let {
children,
theme,
palette,
colorMode,
colorScheme,
domainXType,
width,
height,
extent,
paneGap,
axisXHeight,
axisXVisible,
gridXVisible,
axisYWidth,
axisPadding,
gridX,
axisXTitle,
setSlice,
formatDomain,
formatTooltip,
emptyText,
overlays,
background
} = _ref2;
const {
totalPaneHeight,
dynamicPaneCount
} = computePaneHeights(children, paneGap);
let dynamicPaneHeight = 0;
if (dynamicPaneCount > 0) {
if (height == null) {
throw new Error("`height` is required unless all panes have their height specified.");
}
dynamicPaneHeight = (height - totalPaneHeight - (axisXVisible ? axisXHeight : 0)) / dynamicPaneCount;
}
const visualStyle = theme.charts.xy.style;
const panes = [];
Children.forEach(children, child => {
if ( /*#__PURE__*/isValidElement(child)) {
var _item$props$height, _child$key, _child$props$colorSch, _child$props$emptyTex, _child$props$gridXVis;
const item = child;
const paneActualHeight = (_item$props$height = item.props.height) !== null && _item$props$height !== void 0 ? _item$props$height : dynamicPaneHeight; // height occupied by the header and Y axis title when specified
const legendVisible = item.props.legendVisible && item.props.data != null && item.props.data.length > 0;
let headerHeight = item.props.header || legendVisible ? visualStyle.header.height : 0;
if (item.props.axisYTitle) {
headerHeight += visualStyle.yAxis.titleHeight + visualStyle.yAxis.titleSpacing;
}
if (headerHeight > 0) {
headerHeight += visualStyle.header.spacing;
}
const mergedOverlays = overlays != null ? child.props.overlays != null ? [...overlays, ...child.props.overlays] : overlays : child.props.overlays;
panes.push( /*#__PURE__*/cloneElement(child, {
key: (_child$key = child.key) !== null && _child$key !== void 0 ? _child$key : "pane-".concat(panes.length),
theme: theme,
palette: palette,
background: background,
colorMode: colorMode,
colorScheme: (_child$props$colorSch = child.props.colorScheme) !== null && _child$props$colorSch !== void 0 ? _child$props$colorSch : colorScheme,
emptyText: (_child$props$emptyTex = child.props.emptyText) !== null && _child$props$emptyTex !== void 0 ? _child$props$emptyTex : emptyText,
domainXType: domainXType,
height: paneActualHeight,
width: width,
axisPadding: axisPadding,
axisYWidth: axisYWidth,
gridXVisible: (_child$props$gridXVis = child.props.gridXVisible) !== null && _child$props$gridXVis !== void 0 ? _child$props$gridXVis : gridXVisible,
headerHeight: headerHeight,
extentX: extent,
extentY: Math.max(0, paneActualHeight - headerHeight),
setSlice: setSlice,
axisXTitle: axisXTitle,
formatXTooltip: formatTooltip !== null && formatTooltip !== void 0 ? formatTooltip : formatDomain,
gridX: gridX,
overlays: mergedOverlays
}));
}
});
return _jsx(Fragment, {
children: panes
});
};
const DefaultFormatTimeTooltip = timeFormat("%d %b %Y, %I:%M %p (UTC %Z)");
const XYTimeChart = props => {
var _props$formatTooltip;
const {
domainType,
domain,
domainNice,
width,
extent,
axisXHeight,
axisXVisible
} = props;
const [scale, context, gridX] = useMemo(() => {
const scale = scaleTime().rangeRound([0, extent]).domain(domain !== null && domain !== void 0 ? domain : []);
if (domainNice) {
scale.nice();
}
const context = {
domainType: domainType,
scaleX: scale,
invertX: scale.invert,
compareX: (a, b) => {
const d = a.getTime() - b.getTime();
return d < 0 ? -1 : d > 0 ? 1 : 0;
}
};
const gridX = p => _jsx(ChartTimeGrid, {
orientation: "vertical",
componentId: p.componentId,
theme: p.theme,
colorMode: p.colorMode,
left: p.axisYWidth,
width: p.extentX,
height: p.extentY,
tickValues: props.axisXValues,
scale: scale
}, "gridX");
return [scale, context, gridX];
}, [domainType, domain, domainNice, extent, props.axisXValues]);
return _jsxs(ChartTimeDataContext.Provider, {
value: context,
children: [_jsx(XYChartPanes, _objectSpread(_objectSpread({}, props), {}, {
formatTooltip: (_props$formatTooltip = props.formatTooltip) !== null && _props$formatTooltip !== void 0 ? _props$formatTooltip : DefaultFormatTimeTooltip,
gridX: gridX
})), axisXVisible && _jsx(SvgWrapper, {
width: width,
height: axisXHeight,
componentId: props.chartId,
background: props.background,
children: _jsx(ChartTimeAxis, {
componentId: props.chartId,
theme: props.theme,
colorMode: props.colorMode,
orientation: "x",
offset: props.axisYWidth,
span: axisXHeight,
textOffset: 8,
tickSize: 4,
tickValues: props.axisXValues,
format: props.formatDomain,
scale: scale,
title: props.axisXTitle
})
})]
});
};
const DefaultFormatNumericTooltip = v => v.toLocaleString();
const XYNumericChart = props => {
var _props$formatTooltip2;
const {
domainType,
domain,
domainNice,
width,
extent,
axisXHeight,
axisXVisible
} = props;
const [scale, context, gridX] = useMemo(() => {
const scale = scaleLinear().rangeRound([0, extent]).domain(domain !== null && domain !== void 0 ? domain : []);
if (domainNice) {
scale.nice();
}
const context = {
domainType: domainType,
scaleX: scale,
invertX: scale.invert,
compareX: (a, b) => a === b ? 0 : a < b ? -1 : 1
};
const gridX = p => _jsx(ChartLinearGrid, {
orientation: "vertical",
componentId: p.componentId,
theme: p.theme,
colorMode: p.colorMode,
left: p.axisYWidth,
width: p.extentX,
height: p.extentY,
tickValues: props.axisXValues,
scale: scale
}, "gridX");
return [scale, context, gridX];
}, [domainType, domain, domainNice, extent, props.axisXValues]);
return _jsxs(ChartNumericDataContext.Provider, {
value: context,
children: [_jsx(XYChartPanes, _objectSpread(_objectSpread({}, props), {}, {
formatTooltip: (_props$formatTooltip2 = props.formatTooltip) !== null && _props$formatTooltip2 !== void 0 ? _props$formatTooltip2 : DefaultFormatNumericTooltip,
gridX: gridX
})), axisXVisible && _jsx(SvgWrapper, {
width: width,
height: axisXHeight,
componentId: props.chartId,
background: props.background,
children: _jsx(ChartLinearAxis, {
componentId: props.chartId,
theme: props.theme,
colorMode: props.colorMode,
orientation: "x",
offset: props.axisYWidth,
span: axisXHeight,
textOffset: 8,
tickSize: 4,
tickValues: props.axisXValues,
format: props.formatDomain,
scale: scale,
title: props.axisXTitle
})
})]
});
};
const XYOrdinalChart = props => {
const {
domainType,
domain,
width,
extent,
axisXHeight,
axisPadding,
axisXVisible
} = props;
const [scale, context, gridX] = useMemo(() => {
const domainX = domain !== null && domain !== void 0 ? domain : [];
const padding = axisPadding !== null && axisPadding !== void 0 ? axisPadding : 0;
const scale = scaleBand().rangeRound([0, extent]).domain(domainX).paddingOuter(padding * 0.5).paddingInner(padding);
const bandwidth = scale.bandwidth();
const half = bandwidth * 0.5;
const scaleX = v => {
const x = scale(v);
return x != null ? x + half : undefined;
}; // build a lookup map using original domain order for sorting
const lookup = new Map();
domainX.map((value, index) => lookup.set(value, index));
const compare = (a, b) => {
var _lookup$get, _lookup$get2;
const d = ((_lookup$get = lookup.get(a)) !== null && _lookup$get !== void 0 ? _lookup$get : -1) - ((_lookup$get2 = lookup.get(b)) !== null && _lookup$get2 !== void 0 ? _lookup$get2 : -1);
return d < 0 ? -1 : d > 0 ? 1 : 0;
};
const context = {
domainType: domainType,
scaleX: scaleX,
invertX: scaleBandInvert(scale),
compareX: compare,
bandwidth: bandwidth
};
const gridX = p => _jsx(ChartOrdinalGrid, {
orientation: "vertical",
componentId: p.componentId,
theme: p.theme,
colorMode: p.colorMode,
left: p.axisYWidth,
width: p.extentX,
height: p.extentY,
scale: scale
}, "gridX");
return [scale, context, gridX];
}, [domainType, domain, extent, axisPadding]);
return _jsxs(ChartOrdinalDataContext.Provider, {
value: context,
children: [_jsx(XYChartPanes, _objectSpread(_objectSpread({}, props), {}, {
gridX: gridX
})), axisXVisible && _jsx(SvgWrapper, {
width: width,
height: axisXHeight,
componentId: props.chartId,
background: props.background,
children: _jsx(ChartOrdinalAxis, {
componentId: props.chartId,
theme: props.theme,
colorMode: props.colorMode,
orientation: "x",
offset: props.axisYWidth,
span: axisXHeight,
textOffset: 8,
tickSize: 0,
tickVisible: false,
tickValues: props.axisXValues,
format: props.formatDomain,
scale: scale,
title: props.axisXTitle
})
})]
});
};
/**
* `XYChart` component — presents metrics on XY plane that are based
* in continuous domain (time and numeric) or ordinal domain.
* Metrics can be visualized as line/area, bar, or bubble series.
* Supports one or more panes sharing the same primary X domain, but
* having independent Y, and optionally Z, ranges and visualization
* properties.
*/
function XYChart(props) {
var _props$background, _props$background2;
const {
axisXVisible = true,
axisYWidth = 40,
axisPadding = 0.2
} = props;
const theme = useTheme();
const colorMode = useColorMode(props.colorMode);
const palette = theme.palette[colorMode];
const visualAppearance = theme.charts.xy.appearance(palette, colorMode, undefined, "none");
const visualStyle = theme.charts.xy.style;
const [slice, setSlice] = useState(undefined);
const propsEx = {
chartId: useComponentId("--apptane-chart"),
theme: theme,
colorMode: colorMode,
palette: palette,
background: (_props$background = props.background) !== null && _props$background !== void 0 ? _props$background : visualAppearance.back,
extent: Math.max(0, props.width - axisYWidth),
// viewport extent for data series, i.e. X domain
axisYWidth: axisYWidth,
paneGap: visualStyle.gap,
axisXHeight: visualStyle.xAxis.height,
axisXVisible: axisXVisible,
axisPadding: axisPadding,
setSlice: setSlice
};
let chart;
if (props.domain != null && props.domain.length > 0) {
switch (props.domainType) {
case "time":
if (props.domain.length !== 2) {
warning(false, "`domain` must contain exactly two elements, property ignored");
} else {
chart = _jsx(XYTimeChart, _objectSpread(_objectSpread(_objectSpread({}, props), propsEx), {}, {
domainXType: "time"
}));
}
break;
case "numeric":
if (props.domain.length !== 2) {
warning(false, "`domain` must contain exactly two elements, property ignored`");
} else {
chart = _jsx(XYNumericChart, _objectSpread(_objectSpread(_objectSpread({}, props), propsEx), {}, {
domainXType: "numeric"
}));
}
break;
case "ordinal":
chart = _jsx(XYOrdinalChart, _objectSpread(_objectSpread(_objectSpread({}, props), propsEx), {}, {
domainXType: "ordinal"
}));
break;
}
}
if (chart == null) {
let height = props.height;
if (height == null) {
const {
totalPaneHeight,
dynamicPaneCount
} = computePaneHeights(props.children, propsEx.paneGap);
if (dynamicPaneCount > 0) {
throw new Error("`height` is required unless all panes have their height specified.");
}
height = totalPaneHeight;
}
chart = _jsx(ChartEmptyBlock, {
theme: theme,
colorMode: colorMode,
background: props.background,
width: props.width,
height: height,
top: 0,
left: 0,
children: props.emptyText
});
}
return _jsx(ChartSliceContext.Provider, {
value: slice,
children: _jsx("div", {
css: [StyleContainer((_props$background2 = props.background) !== null && _props$background2 !== void 0 ? _props$background2 : visualAppearance.back, visualStyle.gap), {
width: props.width,
height: props.height
}, process.env.NODE_ENV === "production" ? "" : ";label:XYChart;", process.env.NODE_ENV === "production" ? "" : "/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy94eS9YWUNoYXJ0LnRzeCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUF3Z0JRIiwiZmlsZSI6Ii4uLy4uL3NyYy94eS9YWUNoYXJ0LnRzeCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbG9yLCBDb2xvck1vZGUsIFBhbGV0dGUsIHVzZUNvbXBvbmVudElkLCB3YXJuaW5nIH0gZnJvbSBcIkBhcHB0YW5lL3JlYWN0LXVpLWNvcmVcIjtcbmltcG9ydCB7IFRoZW1lLCB1c2VDb2xvck1vZGUsIHVzZVRoZW1lIH0gZnJvbSBcIkBhcHB0YW5lL3JlYWN0LXVpLXRoZW1lXCI7XG5pbXBvcnQgeyBjc3MgfSBmcm9tIFwiQGVtb3Rpb24vcmVhY3RcIjtcbmltcG9ydCB7IENoaWxkcmVuLCBjbG9uZUVsZW1lbnQsIEZyYWdtZW50LCBpc1ZhbGlkRWxlbWVudCwgdXNlTWVtbywgdXNlU3RhdGUgfSBmcm9tIFwicmVhY3RcIjtcbmltcG9ydCB7IHNjYWxlQmFuZCwgc2NhbGVMaW5lYXIsIHNjYWxlVGltZSB9IGZyb20gXCJkMy1zY2FsZVwiO1xuaW1wb3J0IHsgdGltZUZvcm1hdCB9IGZyb20gXCJkMy10aW1lLWZvcm1hdFwiO1xuaW1wb3J0IHsgRG9tYWluVHlwZSwgRG9tYWluWFZhbHVlIH0gZnJvbSBcIi4uL2NvbW1vbi9UeXBlcy5qc1wiO1xuaW1wb3J0IHtcbiAgQ2hhcnREYXRhLFxuICBDaGFydE51bWVyaWNEYXRhQ29udGV4dCxcbiAgQ2hhcnRPcmRpbmFsRGF0YUNvbnRleHQsXG4gIENoYXJ0VGltZURhdGFDb250ZXh0LFxufSBmcm9tIFwiLi4vcGFydHMvQ2hhcnREYXRhQ29udGV4dC5qc1wiO1xuaW1wb3J0IHsgQ2hhcnRFbXB0eUJsb2NrIH0gZnJvbSBcIi4uL3BhcnRzL0NoYXJ0RW1wdHlCbG9jay5qc1wiO1xuaW1wb3J0IHsgQ2hhcnRMaW5lYXJBeGlzIH0gZnJvbSBcIi4uL3BhcnRzL0NoYXJ0TGluZWFyQXhpcy5qc1wiO1xuaW1wb3J0IHsgQ2hhcnRMaW5lYXJHcmlkIH0gZnJvbSBcIi4uL3BhcnRzL0NoYXJ0TGluZWFyR3JpZC5qc1wiO1xuaW1wb3J0IHsgQ2hhcnRPcmRpbmFsQXhpcyB9IGZyb20gXCIuLi9wYXJ0cy9DaGFydE9yZGluYWxBeGlzLmpzXCI7XG5pbXBvcnQgeyBDaGFydE9yZGluYWxHcmlkIH0gZnJvbSBcIi4uL3BhcnRzL0NoYXJ0T3JkaW5hbEdyaWQuanNcIjtcbmltcG9ydCB7IENoYXJ0U2xpY2UgfSBmcm9tIFwiLi4vcGFydHMvQ2hhcnRTbGljZS5qc1wiO1xuaW1wb3J0IHsgQ2hhcnRTbGljZUNvbnRleHQgfSBmcm9tIFwiLi4vcGFydHMvQ2hhcnRTbGljZUNvbnRleHQuanNcIjtcbmltcG9ydCB7IENoYXJ0VGltZUF4aXMgfSBmcm9tIFwiLi4vcGFydHMvQ2hhcnRUaW1lQXhpcy5qc1wiO1xuaW1wb3J0IHsgQ2hhcnRUaW1lR3JpZCB9IGZyb20gXCIuLi9wYXJ0cy9DaGFydFRpbWVHcmlkLmpzXCI7XG5pbXBvcnQgeyBzY2FsZUJhbmRJbnZlcnQgfSBmcm9tIFwiLi9jb21tb24uanNcIjtcbmltcG9ydCB7IFhZQmFyQ2hhcnRQYW5lIH0gZnJvbSBcIi4vWFlCYXJDaGFydFBhbmUuanNcIjtcbmltcG9ydCB7IFhZQnViYmxlQ2hhcnRQYW5lIH0gZnJvbSBcIi4vWFlCdWJibGVDaGFydFBhbmUuanNcIjtcbmltcG9ydCB7XG4gIFhZQ2hhcnRQYW5lUHJvcHMsXG4gIFhZQ2hhcnRQYW5lUHJvcHNFeCxcbiAgWFlDaGFydFBhbmVQcm9wc0V4QmFzZSxcbiAgWFlDaGFydFByb3BzLFxuICBYWU51bWVyaWNDaGFydFByb3BzLFxuICBYWU9yZGluYWxDaGFydFByb3BzLFxuICBYWVRpbWVDaGFydFByb3BzLFxufSBmcm9tIFwiLi9YWUNoYXJ0LnR5cGVzLmpzXCI7XG5pbXBvcnQgeyBYWUxpbmVDaGFydFBhbmUgfSBmcm9tIFwiLi9YWUxpbmVDaGFydFBhbmUuanNcIjtcbmltcG9ydCB7IFhZU2NhdHRlckNoYXJ0UGFuZSB9IGZyb20gXCIuL1hZU2NhdHRlckNoYXJ0UGFuZS5qc1wiO1xuXG5jb25zdCBTdHlsZUNvbnRhaW5lciA9IChiYWNrOiBDb2xvciwgZ2FwOiBudW1iZXIpID0+IGNzc2BcbiAgYmFja2dyb3VuZDogJHtiYWNrfTtcblxuICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gIGFsaWduLWl0ZW1zOiBzdHJldGNoO1xuICBhbGlnbi1jb250ZW50OiBzdHJldGNoO1xuICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgb3ZlcmZsb3c6IHZpc2libGU7XG5cbiAgLy8gcmVxdWlyZWQgdG8gZm9yY2UgY29ycmVjdCBoZWlnaHQgb24gdGhlIHdyYXBwZXIgZGl2XG4gIHN2ZyB7XG4gICAgZGlzcGxheTogYmxvY2s7XG4gICAgb3ZlcmZsb3c6IHZpc2libGU7XG4gIH1cblxuICA+IGRpdiArIGRpdiB7XG4gICAgbWFyZ2luLXRvcDogJHtnYXB9cHg7XG4gIH1cbmA7XG5cbmZ1bmN0aW9uIGNvbXB1dGVQYW5lSGVpZ2h0cyhwYW5lczogUmVhY3QuUmVhY3ROb2RlLCBnYXA6IG51bWJlcikge1xuICBsZXQgdG90YWxQYW5lSGVpZ2h0ID0gMDtcbiAgbGV0IHRvdGFsUGFuZUNvdW50ID0gMDtcbiAgbGV0IGR5bmFtaWNQYW5lQ291bnQgPSAwO1xuXG4gIENoaWxkcmVuLmZvckVhY2gocGFuZXMsIChwYW5lKSA9PiB7XG4gICAgaWYgKGlzVmFsaWRFbGVtZW50KHBhbmUpKSB7XG4gICAgICBjb25zdCBpdGVtID0gcGFuZSBhcyBSZWFjdC5SZWFjdEVsZW1lbnQ8WFlDaGFydFBhbmVQcm9wcz47XG4gICAgICB0b3RhbFBhbmVDb3VudCsrO1xuXG4gICAgICBpZiAoaXRlbS5wcm9wcy5oZWlnaHQgIT0gbnVsbCkge1xuICAgICAgICB0b3RhbFBhbmVIZWlnaHQgKz0gaXRlbS5wcm9wcy5oZWlnaHQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkeW5hbWljUGFuZUNvdW50Kys7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICB0b3RhbFBhbmVIZWlnaHQgKz0gKHRvdGFsUGFuZUNvdW50IC0gMSkgKiBnYXA7XG4gIHJldHVybiB7IHRvdGFsUGFuZUhlaWdodCwgdG90YWxQYW5lQ291bnQsIGR5bmFtaWNQYW5lQ291bnQgfTtcbn1cblxudHlwZSBTdmdXcmFwcGVyUHJvcHMgPSB7XG4gIGNoaWxkcmVuOiBSZWFjdC5SZWFjdE5vZGU7XG4gIHdpZHRoOiBudW1iZXI7XG4gIGhlaWdodDogbnVtYmVyO1xuICBjb21wb25lbnRJZDogc3RyaW5nO1xuICBiYWNrZ3JvdW5kOiBDb2xvcjtcbn07XG5cbmNvbnN0IFN2Z1dyYXBwZXIgPSAoeyBjaGlsZHJlbiwgd2lkdGgsIGhlaWdodCwgY29tcG9uZW50SWQsIGJhY2tncm91bmQgfTogU3ZnV3JhcHBlclByb3BzKSA9PiAoXG4gIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHJvbGU9XCJpbWdcIiBoZWlnaHQ9e2hlaWdodH0gd2lkdGg9e3dpZHRofT5cbiAgICA8ZGVmcz5cbiAgICAgIDxmaWx0ZXIgeD17LTAuMn0geT17MH0gd2lkdGg9ezEuMn0gaGVpZ2h0PXsxfSBpZD17YCR7Y29tcG9uZW50SWR9LWF4aXMtdGl0bGUtYmFja2B9PlxuICAgICAgICA8ZmVGbG9vZCBmbG9vZENvbG9yPXtiYWNrZ3JvdW5kfSByZXN1bHQ9XCJiZ1wiIC8+XG4gICAgICAgIDxmZU1lcmdlPlxuICAgICAgICAgIDxmZU1lcmdlTm9kZSBpbj1cImJnXCIgLz5cbiAgICAgICAgICA8ZmVNZXJnZU5vZGUgaW49XCJTb3VyY2VHcmFwaGljXCIgLz5cbiAgICAgICAgPC9mZU1lcmdlPlxuICAgICAgPC9maWx0ZXI+XG4gICAgPC9kZWZzPlxuICAgIHtjaGlsZHJlbn1cbiAgPC9zdmc+XG4pO1xuXG50eXBlIFhZQ2hhcnRQcm9wc0V4ID0ge1xuICBjaGFydElkOiBzdHJpbmc7XG4gIHRoZW1lOiBUaGVtZTtcbiAgcGFsZXR0ZTogUGFsZXR0ZTtcbiAgY29sb3JNb2RlOiBDb2xvck1vZGU7XG4gIGJhY2tncm91bmQ6IENvbG9yO1xuICBkb21haW5YVHlwZTogRG9tYWluVHlwZTtcbiAgZXh0ZW50OiBudW1iZXI7XG4gIHBhbmVHYXA6IG51bWJlcjtcbiAgYXhpc1hIZWlnaHQ6IG51bWJlcjtcbiAgYXhpc1hWaXNpYmxlOiBib29sZWFuO1xuICBheGlzWVdpZHRoOiBudW1iZXI7XG4gIGF4aXNQYWRkaW5nOiBudW1iZXI7XG4gIHNldFNsaWNlOiBSZWFjdC5EaXNwYXRjaDxSZWFjdC5TZXRTdGF0ZUFjdGlvbjxDaGFydFNsaWNlIHwgdW5kZWZpbmVkPj47XG59O1xuXG50eXBlIFhZQ2hhcnRQYW5lczxYIGV4dGVuZHMgRG9tYWluWFZhbHVlPiA9IFhZQ2hhcnRQcm9wcyAmXG4gIFhZQ2hhcnRQcm9wc0V4ICYge1xuICAgIGZvcm1hdERvbWFpbj86ICh2YWx1ZTogWCkgPT4gc3RyaW5nO1xuICAgIGZvcm1hdFRvb2x0aXA/OiAodmFsdWU6IFgpID0+IHN0cmluZztcbiAgICBncmlkWDogKHA6IFhZQ2hhcnRQYW5lUHJvcHNFeEJhc2UpID0+IFJlYWN0LlJlYWN0Tm9kZTtcbiAgfTtcblxuLyoqXG4gKiBDb21wdXRlcyBhbmQgc2V0cyBpbmRpdmlkdWFsIHBhbmVzIGdlb21ldHJ5ICh3aWR0aCBhbmQgaGVpZ2h0KS5cbiAqL1xuY29uc3QgWFlDaGFydFBhbmVzID0gPFggZXh0ZW5kcyBEb21haW5YVmFsdWU+KHtcbiAgY2hpbGRyZW4sXG4gIHRoZW1lLFxuICBwYWxldHRlLFxuICBjb2xvck1vZGUsXG4gIGNvbG9yU2NoZW1lLFxuICBkb21haW5YVHlwZSxcbiAgd2lkdGgsXG4gIGhlaWdodCxcbiAgZXh0ZW50LFxuICBwYW5lR2FwLFxuICBheGlzWEhlaWdodCxcbiAgYXhpc1hWaXNpYmxlLFxuICBncmlkWFZpc2libGUsXG4gIGF4aXNZV2lkdGgsXG4gIGF4aXNQYWRkaW5nLFxuICBncmlkWCxcbiAgYXhpc1hUaXRsZSxcbiAgc2V0U2xpY2UsXG4gIGZvcm1hdERvbWFpbixcbiAgZm9ybWF0VG9vbHRpcCxcbiAgZW1wdHlUZXh0LFxuICBvdmVybGF5cyxcbiAgYmFja2dyb3VuZCxcbn06IFhZQ2hhcnRQYW5lczxYPikgPT4ge1xuICBjb25zdCB7IHRvdGFsUGFuZUhlaWdodCwgZHluYW1pY1BhbmVDb3VudCB9ID0gY29tcHV0ZVBhbmVIZWlnaHRzKGNoaWxkcmVuLCBwYW5lR2FwKTtcblxuICBsZXQgZHluYW1pY1BhbmVIZWlnaHQgPSAwO1xuICBpZiAoZHluYW1pY1BhbmVDb3VudCA+IDApIHtcbiAgICBpZiAoaGVpZ2h0ID09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcImBoZWlnaHRgIGlzIHJlcXVpcmVkIHVubGVzcyBhbGwgcGFuZXMgaGF2ZSB0aGVpciBoZWlnaHQgc3BlY2lmaWVkLlwiKTtcbiAgICB9XG5cbiAgICBkeW5hbWljUGFuZUhlaWdodCA9IChoZWlnaHQgLSB0b3RhbFBhbmVIZWlnaHQgLSAoYXhpc1hWaXNpYmxlID8gYXhpc1hIZWlnaHQgOiAwKSkgLyBkeW5hbWljUGFuZUNvdW50O1xuICB9XG5cbiAgY29uc3QgdmlzdWFsU3R5bGUgPSB0aGVtZS5jaGFydHMueHkuc3R5bGU7XG4gIGNvbnN0IHBhbmVzOiBKU1guRWxlbWVudFtdID0gW107XG4gIENoaWxkcmVuLmZvckVhY2goY2hpbGRyZW4sIChjaGlsZCkgPT4ge1xuICAgIGlmIChpc1ZhbGlkRWxlbWVudChjaGlsZCkpIHtcbiAgICAgIGNvbnN0IGl0ZW0gPSBjaGlsZCBhcyBSZWFjdC5SZWFjdEVsZW1lbnQ8WFlDaGFydFBhbmVQcm9wcz47XG4gICAgICBjb25zdCBwYW5lQWN0dWFsSGVpZ2h0ID0gaXRlbS5wcm9wcy5oZWlnaHQgPz8gZHluYW1pY1BhbmVIZWlnaHQ7XG5cbiAgICAgIC8vIGhlaWdodCBvY2N1cGllZCBieSB0aGUgaGVhZGVyIGFuZCBZIGF4aXMgdGl0bGUgd2hlbiBzcGVjaWZpZWRcbiAgICAgIGNvbnN0IGxlZ2VuZFZpc2libGUgPSBpdGVtLnByb3BzLmxlZ2VuZFZpc2libGUgJiYgaXRlbS5wcm9wcy5kYXRhICE9IG51bGwgJiYgaXRlbS5wcm9wcy5kYXRhLmxlbmd0aCA+IDA7XG5cbiAgICAgIGxldCBoZWFkZXJIZWlnaHQgPSBpdGVtLnByb3BzLmhlYWRlciB8fCBsZWdlbmRWaXNpYmxlID8gdmlzdWFsU3R5bGUuaGVhZGVyLmhlaWdodCA6IDA7XG4gICAgICBpZiAoaXRlbS5wcm9wcy5heGlzWVRpdGxlKSB7XG4gICAgICAgIGhlYWRlckhlaWdodCArPSB2aXN1YWxTdHlsZS55QXhpcy50aXRsZUhlaWdodCArIHZpc3VhbFN0eWxlLnlBeGlzLnRpdGxlU3BhY2luZztcbiAgICAgIH1cblxuICAgICAgaWYgKGhlYWRlckhlaWdodCA+IDApIHtcbiAgICAgICAgaGVhZGVySGVpZ2h0ICs9IHZpc3VhbFN0eWxlLmhlYWRlci5zcGFjaW5nO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBtZXJnZWRPdmVybGF5cyA9XG4gICAgICAgIG92ZXJsYXlzICE9IG51bGxcbiAgICAgICAgICA/IGNoaWxkLnByb3BzLm92ZXJsYXlzICE9IG51bGxcbiAgICAgICAgICAgID8gWy4uLm92ZXJsYXlzLCAuLi5jaGlsZC5wcm9wcy5vdmVybGF5c11cbiAgICAgICAgICAgIDogb3ZlcmxheXNcbiAgICAgICAgICA6IGNoaWxkLnByb3BzLm92ZXJsYXlzO1xuXG4gICAgICBwYW5lcy5wdXNoKFxuICAgICAgICBjbG9uZUVsZW1lbnQ8WFlDaGFydFBhbmVQcm9wc0V4PFg+PihjaGlsZCwge1xuICAgICAgICAgIGtleTogY2hpbGQua2V5ID8/IGBwYW5lLSR7cGFuZXMubGVuZ3RofWAsXG4gICAgICAgICAgdGhlbWU6IHRoZW1lLFxuICAgICAgICAgIHBhbGV0dGU6IHBhbGV0dGUsXG4gICAgICAgICAgYmFja2dyb3VuZDogYmFja2dyb3VuZCxcbiAgICAgICAgICBjb2xvck1vZGU6IGNvbG9yTW9kZSxcbiAgICAgICAgICBjb2xvclNjaGVtZTogY2hpbGQucHJvcHMuY29sb3JTY2hlbWUgPz8gY29sb3JTY2hlbWUsXG4gICAgICAgICAgZW1wdHlUZXh0OiBjaGlsZC5wcm9wcy5lbXB0eVRleHQgPz8gZW1wdHlUZXh0LFxuICAgICAgICAgIGRvbWFpblhUeXBlOiBkb21haW5YVHlwZSxcbiAgICAgICAgICBoZWlnaHQ6IHBhbmVBY3R1YWxIZWlnaHQsXG4gICAgICAgICAgd2lkdGg6IHdpZHRoLFxuICAgICAgICAgIGF4aXNQYWRkaW5nOiBheGlzUGFkZGluZyxcbiAgICAgICAgICBheGlzWVdpZHRoOiBheGlzWVdpZHRoLFxuICAgICAgICAgIGdyaWRYVmlzaWJsZTogY2hpbGQucHJvcHMuZ3JpZFhWaXNpYmxlID8/IGdyaWRYVmlzaWJsZSxcbiAgICAgICAgICBoZWFkZXJIZWlnaHQ6IGhlYWRlckhlaWdodCxcbiAgICAgICAgICBleHRlbnRYOiBleHRlbnQsXG4gICAgICAgICAgZXh0ZW50WTogTWF0aC5tYXgoMCwgcGFuZUFjdHVhbEhlaWdodCAtIGhlYWRlckhlaWdodCksXG4gICAgICAgICAgc2V0U2xpY2U6IHNldFNsaWNlLFxuICAgICAgICAgIGF4aXNYVGl0bGU6IGF4aXNYVGl0bGUsXG4gICAgICA