/* Copyright © 2020 Splunk Inc.
SPLUNK CONFIDENTIAL – Use or disclosure of this material in whole or
in part without a valid written license from Splunk Inc. is PROHIBITED. */
var __create = Object.create;
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __pow = Math.pow;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
  for (var prop in b || (b = {}))
    if (__hasOwnProp.call(b, prop))
      __defNormalProp(a, prop, b[prop]);
  if (__getOwnPropSymbols)
    for (var prop of __getOwnPropSymbols(b)) {
      if (__propIsEnum.call(b, prop))
        __defNormalProp(a, prop, b[prop]);
    }
  return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  // If the importer is in node compatibility mode or this is not an ESM
  // file that has been converted to a CommonJS file using a Babel-
  // compatible transform (i.e. "__esModule" has not been set), then set
  // "default" to the CommonJS "module.exports" for node compatibility.
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// src/cursorPlugin.ts
var cursorPlugin_exports = {};
__export(cursorPlugin_exports, {
  cursorPluginFactory: () => cursorPluginFactory,
  useCursorPlugin: () => useCursorPlugin
});
module.exports = __toCommonJS(cursorPlugin_exports);

// esm-externals:lodash/debounce
var debounce_exports = {};
__export(debounce_exports, {
  default: () => debounce_default
});
var defaultImport = __toESM(require("lodash/debounce"));
__reExport(debounce_exports, require("lodash/debounce"));
var debounce_default = "default" in defaultImport ? defaultImport.default : defaultImport;

// esm-externals:react
var react_exports = {};
__export(react_exports, {
  default: () => react_default
});
var defaultImport2 = __toESM(require("react"));
__reExport(react_exports, require("react"));
var react_default = "default" in defaultImport2 ? defaultImport2.default : defaultImport2;

// esm-externals:lodash
var lodash_exports = {};
__export(lodash_exports, {
  default: () => lodash_default
});
var defaultImport3 = __toESM(require("lodash"));
__reExport(lodash_exports, require("lodash"));
var lodash_default = "default" in defaultImport3 ? defaultImport3.default : defaultImport3;

// src/utilities/scaleTime.ts
var timeScaleMap = {
  ["w" /* Weeks */]: { unit: "w", scaleUp: null, scaleUpValue: null, decimalPlaces: 0 },
  ["d" /* Days */]: {
    unit: "d",
    scaleUp: "w" /* Weeks */,
    scaleUpValue: 7,
    decimalPlaces: 0
  },
  ["h" /* Hours */]: { unit: "h", scaleUp: "d" /* Days */, scaleUpValue: 24, decimalPlaces: 1 },
  ["m" /* Minutes */]: {
    unit: "m",
    scaleUp: "h" /* Hours */,
    scaleUpValue: 60,
    decimalPlaces: 1
  },
  ["s" /* Seconds */]: {
    unit: "s",
    scaleUp: "m" /* Minutes */,
    scaleUpValue: 60,
    decimalPlaces: 2
  },
  ["ms" /* Milliseconds */]: {
    unit: "ms",
    scaleUp: "s" /* Seconds */,
    scaleUpValue: 1e3,
    decimalPlaces: 0
  },
  ["us" /* Microseconds */]: {
    unit: `${String.fromCharCode(181)}s`,
    scaleUp: "ms" /* Milliseconds */,
    scaleUpValue: 1e3,
    decimalPlaces: 0
  },
  ["ns" /* Nanoseconds */]: {
    unit: "ns",
    scaleUp: "us" /* Microseconds */,
    scaleUpValue: 1e3,
    decimalPlaces: 0
  }
};
function scaleTime(time, startingScale = "us" /* Microseconds */, decimalPlaces) {
  if (!time || time === 0) {
    return {
      scale: timeScaleMap["ms" /* Milliseconds */].unit,
      value: 0
    };
  }
  let iScale = timeScaleMap[startingScale];
  let timeValue = time;
  let sign = 1;
  if (time < 0) {
    sign = -1;
    timeValue = Math.abs(time);
  }
  while (iScale.scaleUpValue !== null && timeValue >= iScale.scaleUpValue && iScale.scaleUp) {
    timeValue /= iScale.scaleUpValue;
    iScale = timeScaleMap[iScale.scaleUp];
  }
  timeValue *= sign;
  return {
    scale: iScale.unit,
    value: timeValue.toFixed(typeof decimalPlaces !== "undefined" ? decimalPlaces : iScale.decimalPlaces)
  };
}

// src/utilities/formatDuration.ts
var formatDurationMicros = (tickValue, decimalPlaces) => {
  const { value, scale } = scaleTime(tickValue, "us" /* Microseconds */, decimalPlaces || void 0);
  return parseFloat(value.toString()).toString() + scale;
};

// src/utilities/shortenByte.ts
function shortenByte(num, decimalPlaces = 1) {
  let str;
  let suffix = "";
  if (!num) {
    return "0B";
  }
  decimalPlaces = decimalPlaces || 0;
  num = +num.toFixed(decimalPlaces);
  const factor = __pow(10, decimalPlaces);
  if (num < 1e3) {
    str = num;
    suffix = "B";
  } else if (num < 1e6) {
    str = Math.floor(num / (1e3 / factor)) / factor;
    suffix = "KB";
  } else if (num < 1e9) {
    str = Math.floor(num / (1e6 / factor)) / factor;
    suffix = "MB";
  } else if (num < 1e12) {
    str = Math.floor(num / (1e9 / factor)) / factor;
    suffix = "GB";
  } else if (num < 1e15) {
    str = Math.floor(num / (1e12 / factor)) / factor;
    suffix = "TB";
  } else if (num < 1e18) {
    str = Math.floor(num / (1e15 / factor)) / factor;
    suffix = "PB";
  }
  return str + suffix;
}

// src/utilities/shortenNumber.ts
var generateShortenNumberComponents = (num, decimalPlaces) => {
  let str;
  let suffix = "";
  let value;
  if (num === 0 || !num) {
    value = 0;
    return { value, str: "0", suffix };
  }
  if (typeof decimalPlaces === "undefined") {
    decimalPlaces = num < 10 ? 2 : 1;
  }
  num = +num.toFixed(decimalPlaces);
  const factor = __pow(10, decimalPlaces);
  if (num === 0) {
    if (decimalPlaces === 0) {
      str = "<1";
    } else {
      str = `<0.${"0".repeat(decimalPlaces - 1)}1`;
    }
  } else if (num < 1e3) {
    value = num;
    str = value;
  } else if (num < 1e6) {
    value = Math.floor(num / (1e3 / factor)) / factor;
    str = value;
    suffix = "k";
  } else if (num < 1e9) {
    value = Math.floor(num / (1e6 / factor)) / factor;
    str = value;
    suffix = "m";
  } else if (num < 1e12) {
    value = Math.floor(num / (1e9 / factor)) / factor;
    str = value;
    suffix = "b";
  } else if (num < 1e15) {
    value = Math.floor(num / (1e12 / factor)) / factor;
    str = value;
    suffix = "t";
  }
  return { value, str: String(str), suffix };
};
function shortenNumber(num, decimalPlaces) {
  const { str, suffix } = generateShortenNumberComponents(num, decimalPlaces);
  return str + suffix;
}

// esm-externals:lodash/some
var some_exports = {};
__export(some_exports, {
  default: () => some_default
});
var defaultImport4 = __toESM(require("lodash/some"));
__reExport(some_exports, require("lodash/some"));
var some_default = "default" in defaultImport4 ? defaultImport4.default : defaultImport4;

// esm-externals:uplot
var uplot_exports = {};
__export(uplot_exports, {
  default: () => uplot_default
});
var defaultImport5 = __toESM(require("uplot"));
__reExport(uplot_exports, require("uplot"));
var uplot_default = "default" in defaultImport5 ? defaultImport5.default : defaultImport5;

// esm-externals:temporal-polyfill
var temporal_polyfill_exports = {};
__export(temporal_polyfill_exports, {
  default: () => temporal_polyfill_default
});
var defaultImport6 = __toESM(require("temporal-polyfill"));
__reExport(temporal_polyfill_exports, require("temporal-polyfill"));
var temporal_polyfill_default = "default" in defaultImport6 ? defaultImport6.default : defaultImport6;

// esm-externals:string-format-obj
var string_format_obj_exports = {};
__export(string_format_obj_exports, {
  default: () => string_format_obj_default
});
var defaultImport7 = __toESM(require("string-format-obj"));
__reExport(string_format_obj_exports, require("string-format-obj"));
var string_format_obj_default = "default" in defaultImport7 ? defaultImport7.default : defaultImport7;

// src/utilities/formatTimestamp.ts
var EPOCH_SECONDS_MAX_VALUE = Date.now() / 100;

// src/renderers/uplot-utils.ts
var { bars } = uplot_default.paths;
var bars90PercentGap100MaxWidthPaths = bars ? bars({ size: [0.9, 100] }) : void 0;
function getSeriesKey(seriesIndex, allSeries) {
  return typeof seriesIndex === "number" && seriesIndex < (allSeries == null ? void 0 : allSeries.length) ? allSeries[seriesIndex].field : void 0;
}

// src/utilities/utils.ts
var DAY = 24 * 60 * 60;
function exists(value) {
  return value !== void 0 && value !== null;
}
var formatKibBytes = (bytes, decimals = 2) => {
  if (!+bytes) {
    return "0B";
  }
  const k = 1024;
  const dm = decimals < 0 ? 0 : decimals;
  const sizes = ["B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return `${parseFloat((bytes / __pow(k, i)).toFixed(dm))}${sizes[i]}`;
};
var namedFormatters = {
  durationMicros: (value) => formatDurationMicros(value),
  rate: (value, xAxisResolution) => `${shortenNumber(value / (xAxisResolution || 1))} /s`,
  count: (value) => `${shortenNumber(value)}`,
  bytes: (value) => `${shortenByte(value)}`,
  percentage: (value) => `${shortenNumber(value)}%`,
  kibBytes: (value) => `${formatKibBytes(value, 0)}`
};
var scaleNamedFormatters = __spreadProps(__spreadValues({}, namedFormatters), {
  percentage: (value) => `${shortenNumber(value, value < 10 ? 3 : 2)}%`
});

// src/cursorPlugin.ts
function cursorPluginFactory({
  id,
  plotUtilitiesFn,
  plotRenderer,
  cursorEl,
  onChange,
  onCrosshairChange,
  onCrosshairClick,
  onRangeSelection
}) {
  let state = {
    state: "off",
    cursor: null,
    selection: null,
    seriesIndex: null,
    active: false
  };
  const fireOnChange = debounce_default((nextState) => onChange(nextState), 10);
  function change(nextState) {
    state = Object.assign(state, nextState);
    fireOnChange(state);
  }
  function fireCrosshairChange(cursor) {
    const plotUtilities = plotUtilitiesFn();
    if (!onCrosshairChange || !plotUtilities) {
      return;
    }
    if (!cursor) {
      onCrosshairChange(void 0);
      return;
    }
    if (!state.active) {
      return;
    }
    onCrosshairChange({
      time: plotUtilities.posToVal(cursor.left, "x"),
      seriesKey: getSeriesKey(state.seriesIndex, plotUtilities.allSeries)
    });
  }
  function setCrosshairValue(crosshairValue) {
    const plotUtilities = plotUtilitiesFn();
    if (state.active || !plotUtilities) {
      return;
    }
    if (crosshairValue) {
      plotUtilities.setCursor(
        {
          left: plotUtilities.valToPos(crosshairValue.time, "x"),
          // using `undefined` top will prevent uplot from highlighting a "closest series"
          top: void 0
        },
        true
      );
    } else {
      plotUtilities.setCursor({ left: -10, top: -10 }, true);
    }
  }
  function fireRangeSelection(e, selection) {
    const plotUtilities = plotUtilitiesFn();
    if (!state.active || !plotUtilities || !onRangeSelection || !selection || !exists(selection.left) || !exists(selection.width)) {
      return;
    }
    const start = selection.width > 0 ? selection.left : selection.left - selection.width;
    const end = selection.width > 0 ? selection.left + selection.width : selection.left;
    onRangeSelection(
      {
        start: plotUtilities.posToVal(start, "x"),
        end: plotUtilities.posToVal(end, "x"),
        vizId: id
      },
      e
    );
  }
  const mouseenter = () => {
    change({ active: true });
  };
  const mouseleave = () => {
    const plotUtilities = plotUtilitiesFn();
    change({ active: false, cursor: null });
    plotUtilities == null ? void 0 : plotUtilities.setCursor({ left: -10, top: -10 });
    fireCrosshairChange(void 0);
  };
  let clientX;
  let clientY;
  let selecting = false;
  const mousedown = (e) => {
    clientX = e.clientX;
    clientY = e.clientY;
  };
  const mouseup = (e) => {
    const plotUtilities = plotUtilitiesFn();
    if (onCrosshairClick && e.clientX === clientX && e.clientY === clientY) {
      const { seriesIndex, cursor } = state;
      if (plotUtilities && cursor && exists(seriesIndex)) {
        onCrosshairClick({
          time: plotUtilities.posToVal(cursor.left, "x"),
          index: cursor.index,
          seriesIndex,
          originalEvent: e,
          seriesKey: plotUtilities.allSeries[seriesIndex].field
        });
      }
    }
    if (selecting && exists(clientX) && exists(clientY)) {
      selecting = false;
      fireRangeSelection(e, state.selection);
      change({
        selection: null
      });
    }
    clientX = void 0;
    clientY = void 0;
  };
  const mousemove = (e) => {
    const plotUtilities = plotUtilitiesFn();
    if (!cursorEl || !plotUtilities) {
      return;
    }
    if (exists(clientX) && exists(clientY)) {
      selecting = true;
      const overRect2 = plotUtilities.dimensions.over;
      const left2 = Math.max(
        0,
        e.clientX - clientX > 0 ? clientX - overRect2.left : e.clientX - overRect2.left
      );
      const right = e.clientX > clientX ? e.clientX - overRect2.left : clientX - overRect2.left;
      const width = Math.min(overRect2.width, right - left2);
      change({
        selection: { left: Math.max(0, left2), width: Math.max(0, width) }
      });
    }
    const overRect = plotUtilities.dimensions.over;
    const top = e.clientY - overRect.top;
    const left = e.clientX - overRect.left;
    plotUtilities.setCursor({ left, top }, true);
  };
  const setupEventListeners = () => {
    if (cursorEl) {
      cursorEl.addEventListener("mouseenter", mouseenter);
      cursorEl.addEventListener("mouseleave", mouseleave);
      cursorEl.addEventListener("mousedown", mousedown);
      cursorEl.addEventListener("mouseup", mouseup);
      cursorEl.addEventListener("mousemove", mousemove);
    }
  };
  plotRenderer.onSetCursor((cursor) => {
    if (!cursor) {
      change({
        state: "off",
        cursor: null,
        seriesIndex: null
      });
    } else {
      change({
        state: "hover",
        cursor
      });
      fireCrosshairChange(state.cursor);
    }
  });
  plotRenderer.onFocusSeries((seriesIndex) => {
    change({
      seriesIndex
    });
  });
  const cleanupEventListeners = () => {
    if (cursorEl) {
      cursorEl.removeEventListener("mouseenter", mouseenter);
      cursorEl.removeEventListener("mouseleave", mouseleave);
      cursorEl.removeEventListener("mousedown", mousedown);
      cursorEl.removeEventListener("mouseup", mouseup);
      cursorEl.removeEventListener("mousemove", mousemove);
    }
  };
  return {
    // Receive input from external system
    setCrosshairValue,
    setupEventListeners,
    cleanupEventListeners
  };
}
var useCursorPlugin = ({
  id,
  plotUtilitiesFn,
  plotRenderer,
  cursorEl,
  crosshairValue,
  onCrosshairChange,
  onCrosshairClick,
  onRangeSelection
}) => {
  const [cursorState, setCursorState] = (0, react_exports.useState)();
  const { setCrosshairValue, setupEventListeners, cleanupEventListeners } = (0, react_exports.useMemo)(
    () => cursorPluginFactory({
      id,
      plotUtilitiesFn,
      plotRenderer,
      cursorEl,
      onChange: (nextCursorState) => {
        setCursorState(__spreadValues({}, nextCursorState));
      },
      onCrosshairChange,
      onCrosshairClick,
      onRangeSelection
    }),
    [id, plotUtilitiesFn, plotRenderer, cursorEl, onCrosshairChange, onCrosshairClick, onRangeSelection]
  );
  (0, react_exports.useEffect)(() => setCrosshairValue(crosshairValue), [setCrosshairValue, crosshairValue]);
  (0, react_exports.useEffect)(() => {
    setupEventListeners();
    return cleanupEventListeners;
  }, [setupEventListeners, cleanupEventListeners]);
  return { cursorState };
};
//# sourceMappingURL=cursorPlugin.js.map
