/* 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 __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
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/formatters/FormatByType.ts
var FormatByType_exports = {};
__export(FormatByType_exports, {
  FormatByType: () => FormatByType
});
module.exports = __toCommonJS(FormatByType_exports);

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

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

// esm-externals:@splunk/moment
var moment_exports = {};
__export(moment_exports, {
  default: () => moment_default
});
var defaultImport3 = __toESM(require("@splunk/moment"));
__reExport(moment_exports, require("@splunk/moment"));
var moment_default = "default" in defaultImport3 ? defaultImport3.default : defaultImport3;

// esm-externals:@splunk/visualization-schemas
var visualization_schemas_exports = {};
__export(visualization_schemas_exports, {
  default: () => visualization_schemas_default
});
var defaultImport4 = __toESM(require("@splunk/visualization-schemas"));
__reExport(visualization_schemas_exports, require("@splunk/visualization-schemas"));
var visualization_schemas_default = "default" in defaultImport4 ? defaultImport4.default : defaultImport4;

// src/utils/namedColors.ts
var namedColors_default = [
  "transparent",
  "aliceblue",
  "antiquewhite",
  "aqua",
  "aquamarine",
  "azure",
  "beige",
  "bisque",
  "black",
  "blanchedalmond",
  "blue",
  "blueviolet",
  "brown",
  "burlywood",
  "cadetblue",
  "chartreuse",
  "chocolate",
  "coral",
  "cornflowerblue",
  "cornsilk",
  "crimson",
  "cyan",
  "darkblue",
  "darkcyan",
  "darkgoldenrod",
  "darkgray",
  "darkgreen",
  "darkgrey",
  "darkkhaki",
  "darkmagenta",
  "darkolivegreen",
  "darkorange",
  "darkorchid",
  "darkred",
  "darksalmon",
  "darkseagreen",
  "darkslateblue",
  "darkslategray",
  "darkslategrey",
  "darkturquoise",
  "darkviolet",
  "deeppink",
  "deepskyblue",
  "dimgray",
  "dimgrey",
  "dodgerblue",
  "firebrick",
  "floralwhite",
  "forestgreen",
  "fuchsia",
  "gainsboro",
  "ghostwhite",
  "gold",
  "goldenrod",
  "gray",
  "green",
  "greenyellow",
  "grey",
  "honeydew",
  "hotpink",
  "indianred",
  "indigo",
  "ivory",
  "khaki",
  "lavender",
  "lavenderblush",
  "lawngreen",
  "lemonchiffon",
  "lightblue",
  "lightcoral",
  "lightcyan",
  "lightgoldenrodyellow",
  "lightgray",
  "lightgreen",
  "lightgrey",
  "lightpink",
  "lightsalmon",
  "lightseagreen",
  "lightskyblue",
  "lightslategray",
  "lightslategrey",
  "lightsteelblue",
  "lightyellow",
  "lime",
  "limegreen",
  "linen",
  "magenta",
  "maroon",
  "mediumaquamarine",
  "mediumblue",
  "mediumorchid",
  "mediumpurple",
  "mediumseagreen",
  "mediumslateblue",
  "mediumspringgreen",
  "mediumturquoise",
  "mediumvioletred",
  "midnightblue",
  "mintcream",
  "mistyrose",
  "moccasin",
  "navajowhite",
  "navy",
  "oldlace",
  "olive",
  "olivedrab",
  "orange",
  "orangered",
  "orchid",
  "palegoldenrod",
  "palegreen",
  "paleturquoise",
  "palevioletred",
  "papayawhip",
  "peachpuff",
  "peru",
  "pink",
  "plum",
  "powderblue",
  "purple",
  "rebeccapurple",
  "red",
  "rosybrown",
  "royalblue",
  "saddlebrown",
  "salmon",
  "sandybrown",
  "seagreen",
  "seashell",
  "sienna",
  "silver",
  "skyblue",
  "slateblue",
  "slategray",
  "slategrey",
  "snow",
  "springgreen",
  "steelblue",
  "tan",
  "teal",
  "thistle",
  "tomato",
  "turquoise",
  "violet",
  "wheat",
  "white",
  "whitesmoke",
  "yellow",
  "yellowgreen"
];

// src/utils/colorUtils.ts
function isColor(color = "") {
  if (typeof color !== "string") {
    return false;
  }
  if (color.startsWith("#")) {
    color = color.substring(1);
    return [3, 4, 6, 8].indexOf(color.length) > -1 && !Number.isNaN(parseInt(color, 16));
  }
  const trimmedColor = color.trim();
  if (visualization_schemas_exports.rgbColorPattern.test(trimmedColor) || visualization_schemas_exports.rgbaColorPattern.test(trimmedColor)) {
    return true;
  }
  return namedColors_default.includes(color.toLowerCase());
}

// src/TypeSafeValue.ts
var TypeSafeValue = class _TypeSafeValue {
  // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
  constructor(type, value, coercedValue) {
    /**
     * isTypeSafe. This is a marker field. The presence of this field can be used at runtime to determine if TypedValue is rigorous,
     * loose. Loose TypedValue such as {type:'number', value:'cat'} are handy for testing, but can lie. Obviously 'cat'
     * is not a number. If the isTypeSafe field is present then the instance is a TypeSafeValue
     * @type {boolean}
     */
    this.isTypeSafe = true;
    this.type = type;
    this.value = value;
    this.coercedValue = coercedValue;
  }
  /**
   * returns a TypeSafeValue, either by converting the non TypeSafeValue to
   * a TypeSafeValue, or by simply returning the passed-in TypeSafeValue
   * @param {TypedValue<T>} typedValue
   * @returns {TypeSafeValue<T>}
   */
  static from(typedValue) {
    if (typedValue.isTypeSafe) {
      return typedValue;
    }
    const { value, type } = typedValue;
    const [coercedValue] = _TypeSafeValue.coerceValue(typedValue);
    return new _TypeSafeValue(type, value, coercedValue);
  }
  /**
   * Creates a TypeSafeValue from a raw value
   * @param value
   * @returns {TypeSafeValue<DataType>}
   */
  static fromRaw(value) {
    const type = getDataTypeForPoint(value);
    return new _TypeSafeValue(type, value, value);
  }
  /**
   * attempts to coerce the provided value to the provided type. Returns tuple
   * of the coerced value and a boolean telling if the coercion was clean (true)
   * or if the coercion was likely produced an unusable result, such as NaN for
   * a number, or '' for a color.
   * @param {TypedValue<T>} typedValue
   * @returns {[any]}
   */
  static coerceValue(typedValue) {
    const { type, value } = typedValue;
    let coercedValue = null;
    try {
      switch (type) {
        case "number": {
          coercedValue = Number(value);
          break;
        }
        case "time": {
          const isOk = isTime(value);
          if (value instanceof Date) {
            coercedValue = value;
          } else if (!isOk) {
            coercedValue = "Invalid Date";
          } else {
            const timeString = formatTimeWithTimezoneCorrection(value);
            coercedValue = timeString;
          }
          break;
        }
        case "string": {
          coercedValue = value.toString();
          break;
        }
        case "color": {
          coercedValue = value;
          break;
        }
        case "sparkline": {
          coercedValue = value;
          break;
        }
        case "array": {
          coercedValue = value;
          break;
        }
        case "null": {
          coercedValue = value;
          break;
        }
        case "geojson": {
          coercedValue = value;
          break;
        }
        default: {
          coercedValue = "";
        }
      }
    } catch (e) {
    }
    return [coercedValue];
  }
  toRawCoercedValue() {
    switch (this.type) {
      case "time":
      case "sparkline":
      case "array":
      case "number":
      case "string":
      case "color":
      case "geojson":
      default:
        return this.coercedValue;
    }
  }
  toRawValue() {
    switch (this.type) {
      case "time":
      case "sparkline":
      case "array":
      case "number":
      case "string":
      case "color":
      case "geojson":
      default:
        return this.value;
    }
  }
};

// src/DataPoint.ts
var _DataPoint = class _DataPoint {
  static isDataPoint(o) {
    return o instanceof _DataPoint;
  }
  static fromRaw(value) {
    return new _DataPoint("", TypeSafeValue.fromRaw(value));
  }
  /**
   *
   * @param {string} field data field
   * @param {object} value data value + it's type (number, string, time, color, geojson)
   */
  constructor(field, value) {
    this.field = field;
    this.setValue(value);
    _DataPoint.count += 1;
  }
  getValue() {
    return this.value;
  }
  /**
   * Sets the data point's value to a static TypedValue.
   * @param {TypedValue} v
   */
  setValue(v) {
    this.value = TypeSafeValue.from(v);
  }
  /**
   * Get only value of the data point.
   * @returns {string|number|GeoJsonDataType|null}
   */
  getRawValue() {
    return this.value.toRawValue();
  }
  /**
   * Get only the coerced value of the data point.
   * @returns {string|number|null}
   */
  getCoercedValue() {
    return this.value.toRawCoercedValue();
  }
  /**
   * Returns the data field of the point.
   * @public
   * @returns {DataPoint<'string'>}
   */
  getField() {
    return _DataPoint.fromRaw(this.field);
  }
  /**
   * Returns the data type of the point.
   * @public
   * @returns {string}
   */
  getType() {
    return this.value.type;
  }
};
_DataPoint.count = 0;
var DataPoint = _DataPoint;

// src/utils/types.ts
var supportedDateFormats = [
  "YYYY-MM-DD",
  // HTML5 date
  moment_default.ISO_8601,
  "YYYY-MM-DDTHH:mm",
  // HTML5 date local
  "YYYY-MM-DDTHH:mm:ss.SSS",
  // HTML5 date local milliseconds
  "YYYY-MM-DDTHH:mm:ss",
  // HTML5 date local seconds
  "YYYY-MM-DD HH:MM",
  "YYYY-MM-DD HH:MM:SS",
  "YYYY-MM-DD HH:MM:SS.SSS"
];
var typeOrder = [
  "geojson",
  "sparkline",
  "array",
  "string",
  "color",
  "number",
  "time",
  "null",
  "unknown"
];
function isNumber(dataPoint) {
  return dataPoint !== null && !(0, lodash_exports.isBoolean)(dataPoint) && dataPoint !== "" && (0, lodash_exports.isFinite)(+dataPoint) && (0, lodash_exports.isNumber)(+dataPoint);
}
function isGeoJsonObject(dataPoint) {
  if (!dataPoint) return false;
  let parsedDataPoint;
  try {
    parsedDataPoint = (0, lodash_exports.isObject)(dataPoint) ? dataPoint : JSON.parse(dataPoint);
  } catch (e) {
    return false;
  }
  if (parsedDataPoint == null) {
    return false;
  }
  return Object.prototype.hasOwnProperty.call(parsedDataPoint, "coordinates") && parsedDataPoint.coordinates != null && Array.isArray(parsedDataPoint.coordinates) && Object.prototype.hasOwnProperty.call(parsedDataPoint, "type") && parsedDataPoint.type === "MultiPolygon";
}
function isTime(dataPoint) {
  if (!dataPoint) {
    return false;
  }
  return typeof dataPoint === "string" ? moment_default(dataPoint, supportedDateFormats, true).isValid() : moment_default(dataPoint).isValid();
}
function isString(dataPoint) {
  return typeof dataPoint === "string" && dataPoint.length > 0;
}
var getDataTypeForPoint = (dataPoint, metaData) => {
  if (canInferTypeFromMeta(metaData)) {
    return getDataTypeForMeta(metaData);
  }
  return memoizedGetDataTypeForValue(dataPoint);
};
var getDataTypeForValue = (dataPoint) => {
  if (Array.isArray(dataPoint)) {
    if (dataPoint.length > 1 && dataPoint[0] === "##__SPARKLINE__##") {
      return "sparkline";
    }
    return "array";
  }
  if (isGeoJsonObject(dataPoint)) {
    return "geojson";
  }
  if ((0, lodash_exports.isObject)(dataPoint)) {
    return "unknown";
  }
  if (isNumber(dataPoint)) {
    return "number";
  }
  if (isString(dataPoint) && isColor(dataPoint)) {
    return "color";
  }
  if (isTime(dataPoint)) {
    return "time";
  }
  if (isString(dataPoint)) {
    return "string";
  }
  if (dataPoint === null) {
    return "null";
  }
  return "unknown";
};
var memoizedGetDataTypeForValue = (0, lodash_exports.memoize)(getDataTypeForValue);
var splTypesToDSLDataTypes = {
  str: "string",
  num: "number"
};
var canInferTypeFromMeta = (metaData = {}) => {
  const { name, type = "" } = metaData;
  return splTypesToDSLDataTypes[type] !== void 0 || name === "_time";
};
var getDataTypeForMeta = (metaData = {}) => {
  const { name, type } = metaData;
  if (name === "_time") {
    return "time";
  }
  const typeMatch = splTypesToDSLDataTypes[type];
  if (typeMatch !== void 0) {
    return typeMatch;
  }
  return "unknown";
};
var applyTypePrioritization = (typeMatches) => {
  const typesWithCount = Object.keys(typeMatches).filter(
    (key) => typeMatches[key] > 0
  );
  if (typesWithCount.length === 0) {
    return "unknown";
  }
  if (typesWithCount.length === 1) {
    return typesWithCount[0];
  }
  for (let i = 0; i < typeOrder.length; i += 1) {
    const key = typeOrder[i];
    if (typesWithCount.find((k) => k === key)) {
      return key;
    }
  }
  return "unknown";
};
var inferDataTypeFromDataPoints = (dataPoints) => {
  if (!dataPoints) {
    return "unknown";
  }
  const typeMatches = {
    time: 0,
    number: 0,
    string: 0,
    color: 0,
    unknown: 0,
    array: 0,
    sparkline: 0,
    null: 0,
    geojson: 0
  };
  dataPoints.forEach((point) => {
    typeMatches[point.getType()] += 1;
  });
  return applyTypePrioritization(typeMatches);
};

// src/utils/formatterUtils.ts
var timeToSplunkMoment = (time) => {
  if (moment_default.getDefaultSplunkTimezone()) {
    return moment_default.newSplunkTime({ time });
  }
  return moment_default(time);
};
var formatTimeWithTimezoneCorrection = (time, format = moment_default.defaultFormat) => {
  const utcOffset = moment_default.parseZone(time).utcOffset();
  const momentTime = timeToSplunkMoment(time).utcOffset(utcOffset);
  return momentTime.format(format);
};

// src/DataSeries.ts
var DataSeries = class _DataSeries {
  /**
   *
   * @param {array} points list of data points
   * @param {string} type user explicitly sets the data type
   */
  // eslint-disable-next-line
  constructor(points = [], type, field) {
    this.internalPoints = [];
    this.internalPoints = points;
    if (points.length > 0) {
      this.field = points[0].field;
    }
    if (field) {
      this.field = field;
    }
    this.type = type;
  }
  get points() {
    return this.internalPoints;
  }
  static isDataSeries(o) {
    return o instanceof _DataSeries;
  }
  static fromRaw(pts) {
    return new _DataSeries(pts.map((p) => DataPoint.fromRaw(p)));
  }
  /**
   * Return first dataPoint in series.
   * @public
   * @returns {DataPoint}
   */
  firstPoint() {
    return this.points[0];
  }
  /**
   * Return last dataPoint in series.
   * @public
   * @returns {DataPoint}
   */
  lastPoint() {
    return this.points.slice(-1)[0];
  }
  /**
   * Finds dataPoint(s) in DataSeries by index(es).
   * @public
   * @param {...number} indexes
   * @returns {DataSeries}
   */
  pointsByIndexes(...indexes) {
    const indexedPoints = [];
    indexes.forEach((index) => {
      const dp = this.points[index];
      if (dp != null) {
        indexedPoints.push(dp);
      }
    });
    return new _DataSeries(indexedPoints);
  }
  /**
   * Finds and returns the individual dataPoint at the given index.
   * @public
   * @param {number} index
   * @returns {DataPoint}
   */
  pointByIndex(indexIn) {
    let index = indexIn;
    if (index < 0) {
      index = this.points.length + index;
    }
    if (index < 0 || index >= this.points.length) {
      return null;
    }
    const dp = this.points[index];
    const { field } = dp;
    const { type, value } = dp.getValue();
    return new DataPoint(field, { type, value });
  }
  /**
   * Finds the delta between the last point and point at the given index.
   * A negative index can be used, indicating an offset from the end of the sequence.
   * @public
   * @param {number} index
   * @returns {DataPoint}
   */
  delta(index) {
    const dp1 = this.lastPoint();
    if (dp1 === void 0) {
      return void 0;
    }
    const { field } = dp1;
    const { type, value: val1 } = dp1.getValue();
    if (type !== "number") {
      console.warn(`DSL delta cannot be computed for non-numerical data series of type ${type}`);
    }
    let dp2 = null;
    let delta;
    if (index >= 0) {
      dp2 = this.points[index];
    } else {
      dp2 = this.points.slice().reverse()[Math.abs(index) - 1];
    }
    if (dp2 == null) {
      console.warn("DSL delta cannot be computed, no data - invalid index");
    } else {
      const { value: val2 } = dp2.getValue();
      delta = val1 - val2;
    }
    return new DataPoint(field, { type, value: delta });
  }
  /**
   * Sets all the values in the Data Series to a static TypedValue.
   * @param {TypedValue} v
   */
  setValue(v) {
    this.points.forEach((p) => {
      p.setValue(v);
    });
    this.type = this.points[0].getType();
  }
  /**
   * Gets all the values + their type in the Data Series.
   * @returns {TypedValue[]}
   */
  getValue() {
    const values = [];
    this.points.forEach((p) => {
      values.push(p.getValue());
    });
    return values;
  }
  /**
   * Gets all the values (only) in the Data Series.
   * @returns {array}
   */
  getRawValue() {
    const values = [];
    this.points.forEach((p) => {
      values.push(p.getRawValue());
    });
    return values;
  }
  /**
   * Returns the data source field which the series belongs to.
   * @public
   * @returns {DataPoint<'string'>}
   */
  getField() {
    const dp1 = this.lastPoint();
    return dp1.getField();
  }
  /**
   * Returns the inferred data type of the series.
   * @public
   * @returns {string}
   */
  getType() {
    if (this.type === void 0) {
      this.type = inferDataTypeFromDataPoints(this.points);
    }
    return this.type;
  }
  /**
   * Returns the minimum DataPoint in the series or undefined if no numbers in series.
   * @public
   * @returns {DataPoint<T>}
   */
  min() {
    return this.reduce((v1, v2) => v1 < v2);
  }
  /**
   * Returns the maximum DataPoint in the series.
   * @public
   * @returns {DataPoint<T>}
   */
  max() {
    return this.reduce((v1, v2) => v1 > v2);
  }
  reduce(comparator) {
    return this.points.reduce((agg, cur) => {
      return !agg || comparator(cur.getValue().coercedValue, agg.getValue().coercedValue) ? cur : agg;
    }, void 0);
  }
};

// src/DataFrame.ts
var DataFrame = class _DataFrame {
  /**
   * @param {any} o
   * @returns {boolean}
   */
  static isDataFrame(o) {
    return o instanceof _DataFrame;
  }
  /**
   * @param {array} series list of data series
   */
  constructor(series) {
    this.series = Array.isArray(series) ? series : [series];
  }
  /**
   * Loads ColumnarData into a DataFrame
   * @param {ColumnarData} columnarData
   * @returns {DataFrame<T>}
   */
  static fromJsonCols(columnarData) {
    if (!(columnarData == null ? void 0 : columnarData.data)) {
      return new _DataFrame([]);
    }
    const {
      data: { fields = [], columns = [] }
    } = columnarData;
    if (columns.length !== fields.length) {
      throw new Error(
        `number of columns (${columns.length}) does not match number of fields (${fields.length})`
      );
    }
    const dataSeries = [];
    columns.forEach((data, idx) => {
      const dataPoints = [];
      const fieldInfo = fields[idx];
      const name = fieldInfo.name || fieldInfo;
      const type = fieldInfo == null ? void 0 : fieldInfo.type;
      data.forEach((value) => {
        const dataType = getDataTypeForPoint(value, {
          name,
          type
        });
        dataPoints.push(new DataPoint(name, { value, type: dataType }));
      });
      dataSeries.push(new DataSeries(dataPoints));
    });
    return new _DataFrame(dataSeries);
  }
  static fromRaw(f) {
    const series = [];
    f.forEach((s) => {
      series.push(DataSeries.fromRaw(s));
    });
    return new _DataFrame(series);
  }
  // eslint-disable-next-line consistent-return
  static fromDataPrimitive(dp) {
    if (_DataFrame.isDataFrame(dp)) {
      return dp;
    }
    if (DataSeries.isDataSeries(dp)) {
      return new _DataFrame([dp]);
    }
    if (DataPoint.isDataPoint(dp)) {
      return new _DataFrame([new DataSeries([dp])]);
    }
  }
  /**
   * Filter a DataFrame by specifying the indexes of the DataSeries you would like to return.
   * For example, `frameBySeriesIndexes(first_index, second_index, ...)`, where at least one index is required.
   * @public
   * @param {number[]} indexes
   * @returns {DataFrame.<DataType>}
   *
   * The following code sample shows how to use frameBySeriesIndexes to render a table that includes the first, second, and fourth DataSeries from the data source.
   *
   * ```
   * <Table
   *   options={{
   *     table: '> primary | frameBySeriesIndexes(0,1,3)'
   *   }},
   *   dataSources={{
   *     primary: {
   *       data: {
   *         fields: [
   *           {
   *             name: 'Name'
   *           },
   *           {
   *             name: 'UserID'
   *           },
   *           {
   *             name: 'Money Spent'
   *           },
   *           {
   *             name: 'Most Recent Game'
   *           }
   *         ],
   *         columns: [
   *           [
   *             'Ms. Herman Beer',
   *             'Crystal Ziemann',
   *             'Phil Bartoletti',
   *             'Janis Kiehn V',
   *             'Angel Krajcik',
   *             'Patti Hodkiewicz IV',
   *             'Joanne Emmerich',
   *             'Jay Renner',
   *             'Ora Borer',
   *             'Dr. Bradford Gulgowski'
   *           ],
   *           [
   *             'Enrico98',
   *             'Taylor_Parker83',
   *             'Candice_Carroll',
   *             'Yolanda_McLaughlin95',
   *             'Modesto84',
   *             'Elwin52',
   *             'Francis8',
   *             'Charley.Feeney85',
   *             'Jensen_Jacobson74',
   *             'Dora_Volkman'
   *           ],
   *           [
   *             9740890.83,
   *             2107983.52,
   *             5467223.67,
   *             9529184.93,
   *             9692275.78,
   *             5692737.43,
   *             1001734.82,
   *             3848531.8,
   *             3848531.8
   *           ],
   *           [
   *             '2020-04-12T06:32:08-07:00',
   *             '2020-06-06T16:14:04-07:00',
   *             '2020-02-12T09:43:25-08:00',
   *             '2020-07-25T13:19:49-07:00',
   *             '2020-03-16T21:46:40-07:00',
   *             '2020-08-21T08:38:55-07:00',
   *             '2020-09-26T16:06:03-07:00',
   *             '2020-08-10T14:54:16-07:00',
   *             '2020-08-11T16:49:24-07:00',
   *             '2020-09-29T03:52:51-07:00'
   *           ]
   *         ]
   *       },
   *       meta: {
   *         totalCount: 100
   *       },
   *       requestParams: {
   *         count: 10,
   *         offset: 0
   *       }
   *     }
   *   }}
   * />
   */
  frameBySeriesIndexes(...indexes) {
    const indexedSeries = [];
    indexes.forEach((index) => {
      const ds = this.series[index];
      if (ds != null) {
        indexedSeries.push(ds);
      }
    });
    return new _DataFrame(indexedSeries);
  }
  /**
   * Select a DataSeries by specifying the index of the series you want to return.
   * @public
   * @param {number} index
   * @returns {DataSeries<DataType>}
   *
   * The following code sample shows how to use seriesByIndex to display the second series in a data source as a single value.
   *
   * ```
   * <SingleValue
   *     options={{
   *         sparklineValues: '> primary | seriesByIndex(1)'
   *     }}
   *     dataSources={{
   *         primary: {
   *             data: {
   *                 fields: [
   *                     {
   *                         name: '_time',
   *                     },
   *                     {
   *                         name: 'count',
   *                     },
   *                 ],
   *                 columns: [
   *                     [
   *                         '2018-08-19T00:00:00.000+00:00',
   *                         '2018-08-20T00:00:00.000+00:00',
   *                         '2018-08-21T00:00:00.000+00:00',
   *                         '2018-08-22T00:00:00.000+00:00',
   *                         '2018-08-23T00:00:00.000+00:00',
   *                         '2018-08-24T00:00:00.000+00:00',
   *                         '2018-08-25T00:00:00.000+00:00',
   *                         '2018-08-26T00:00:00.000+00:00',
   *                     ],
   *                     ['1', '62', '103', '308', '587', '876', '930', '1320'],
   *                 ],
   *             },
   *             meta: {},
   *         },
   *     }}
   * />
   *
   */
  // SCP-60632: added a second parameter - empty array as default fallback, hidden from user
  seriesByIndex(index, defaultSeries = []) {
    return this.series[index] || defaultSeries;
  }
  /**
   * Filter a DataFrame by specifying the index range [start, end) of the DataSeries you would like to return.
   * For example, `frameBySeriesIndexRange(start_index)` or `frameBySeriesIndexRange(start_index, end_index)`, where at least the starting index is required.
   * @public
   * @param {int} start (inclusive)
   * @param {int=} end (optional, exclusive)
   * @returns {DataFrame<DataType>}
   *
   * The following code sample shows how to use frameBySeriesIndexRange to render a table that includes the first, second, and third series from the data source.
   *
   * ```
   * <Table
   *   options={{
   *     table: '> primary | frameBySeriesIndexRange(0,2)'
   *   }},
   *   dataSources={{
   *     primary: {
   *       data: {
   *         fields: [
   *           {
   *             name: 'Name'
   *           },
   *           {
   *             name: 'UserID'
   *           },
   *           {
   *             name: 'Money Spent'
   *           },
   *           {
   *             name: 'Most Recent Game'
   *           },
   *         ],
   *         columns: [
   *           [
   *             'Ms. Herman Beer',
   *             'Crystal Ziemann',
   *             'Phil Bartoletti',
   *             'Janis Kiehn V',
   *             'Angel Krajcik',
   *             'Patti Hodkiewicz IV',
   *             'Joanne Emmerich',
   *             'Jay Renner',
   *             'Ora Borer',
   *             'Dr. Bradford Gulgowski'
   *           ],
   *           [
   *             'Enrico98',
   *             'Taylor_Parker83',
   *             'Candice_Carroll',
   *             'Yolanda_McLaughlin95',
   *             'Modesto84',
   *             'Elwin52',
   *             'Francis8',
   *             'Charley.Feeney85',
   *             'Jensen_Jacobson74',
   *             'Dora_Volkman'
   *           ],
   *           [
   *             9740890.83,
   *             2107983.52,
   *             5467223.67,
   *             9529184.93,
   *             9692275.78,
   *             9395814.7,
   *             5692737.43,
   *             1001734.82,
   *             3848531.8,
   *             1691776.38
   *           ],
   *           [
   *             '2020-04-12T06:32:08-07:00',
   *             '2020-06-06T16:14:04-07:00',
   *             '2020-02-12T09:43:25-08:00',
   *             '2020-07-25T13:19:49-07:00',
   *             '2020-03-16T21:46:40-07:00',
   *             '2020-08-21T08:38:55-07:00',
   *             '2020-09-26T16:06:03-07:00',
   *             '2020-08-10T14:54:16-07:00',
   *             '2020-08-11T16:49:24-07:00',
   *             '2020-09-29T03:52:51-07:00'
   *           ]
   *         ]
   *       },
   *       meta: {
   *         totalCount: 100
   *       },
   *       requestParams: {
   *         count: 10,
   *         offset: 0
   *       }
   *     }
   *   }}
   * />
   */
  frameBySeriesIndexRange(start, end) {
    return new _DataFrame(this.series.slice(start, end));
  }
  /**
   * Filter a DataFrame by specifying the names of the DataSeries you would like to return.
   * For example, `frameBySeriesNames(first_name, second_name, ...)`, where at least one series name is required.
   * @public
   * @param {string[]} names
   * @returns {DataFrame<DataType>}
   *
   * The following code sample shows how to use frameBySeriesNames to render a table with the Name and Money Spent columns in the data source.
   *
   * ```
   * <Table
   *     options={{
   *         table: '> primary | frameBySeriesNames("Name", "Money Spent")'
   *     }},
   *     dataSources={{
   *         primary: {
   *             data: {
   *                 fields: [
   *                     {
   *                         name: 'Name'
   *                     },
   *                     {
   *                         name: 'UserID'
   *                     },
   *                     {
   *                         name: 'Money Spent'
   *                     },
   *                     {
   *                         name: 'Most Recent Game'
   *                     },
   *                 ],
   *                 columns: [
   *                     [
   *                         'Ms. Herman Beer',
   *                         'Crystal Ziemann',
   *                         'Phil Bartoletti',
   *                         'Janis Kiehn V',
   *                         'Angel Krajcik',
   *                         'Patti Hodkiewicz IV',
   *                         'Joanne Emmerich',
   *                         'Jay Renner',
   *                         'Ora Borer',
   *                         'Dr. Bradford Gulgowski'
   *                     ],
   *                     [
   *                         'Enrico98',
   *                         'Taylor_Parker83',
   *                         'Candice_Carroll',
   *                         'Yolanda_McLaughlin95',
   *                         'Modesto84',
   *                         'Elwin52',
   *                         'Francis8',
   *                         'Charley.Feeney85',
   *                         'Jensen_Jacobson74',
   *                         'Dora_Volkman'
   *                     ],
   *                     [
   *                         9740890.83,
   *                         2107983.52,
   *                         5467223.67,
   *                         9529184.93,
   *                         9692275.78,
   *                         9395814.7,
   *                         5692737.43,
   *                         1001734.82,
   *                         3848531.8,
   *                         1691776.38
   *                     ],
   *                     [
   *                         '2020-04-12T06:32:08-07:00',
   *                         '2020-06-06T16:14:04-07:00',
   *                         '2020-02-12T09:43:25-08:00',
   *                         '2020-07-25T13:19:49-07:00',
   *                         '2020-03-16T21:46:40-07:00',
   *                         '2020-08-21T08:38:55-07:00',
   *                         '2020-09-26T16:06:03-07:00',
   *                         '2020-08-10T14:54:16-07:00',
   *                         '2020-08-11T16:49:24-07:00',
   *                         '2020-09-29T03:52:51-07:00'
   *                     ]
   *                 ]
   *             },
   *             meta: {
   *                 totalCount: 100
   *             },
   *             requestParams {
   *                 count: 10,
   *                 offset: 0
   *             }
   *         }
   *     }}
   * />
   */
  frameBySeriesNames(...names) {
    const namedSeries = [];
    names.forEach((name) => {
      const series = this.seriesByName(name);
      const found = series && DataSeries.isDataSeries(series);
      if (found) {
        namedSeries.push(series);
      }
    });
    return new _DataFrame(namedSeries);
  }
  /**
   * Filter a DataFrame by specifying the names of the DataSeries you would like to omit.
   *  e.g. `frameWithoutSeriesNames(first_name, second_name, ...)`, where at least one series name is required.
   * Note: the data columns of internal fields are automatically excluded from the result.
   * @public
   * @param {string[]} names
   * @returns {DataFrame<DataType>}
   */
  frameWithoutSeriesNames(...names) {
    if (names == null) {
      return new _DataFrame(this.series);
    }
    return new _DataFrame(
      this.series.filter(
        (s) => !names.includes(s.field) && !s.field.startsWith("_")
      )
    );
  }
  /**
   * Filter a DataFrame by removing all internal fields starting with underscore `_`.
   * For example, if you have a primary data source with the following fields: `_time, _span, date, count, cost, _raw`,
   * then DSL `> primary | frameWithoutInternalFields()` removes all the internal fields and returns the DataFrame with fields `date, count, cost`.
   * @public
   * @returns {DataFrame<DataType>}
   *
   * The following code sample shows how to use `frameWithoutInternalFields()` to remove the internal fields from the data source.
   *
   * ```
   * <Table
   *     options={{
   *         table: '> primary | frameWithoutInternalFields()'
   *     }},
   *     dataSources={{
   *         primary: {
   *             data: {
   *                 fields: [
   *                     {
   *                         name: 'Name'
   *                     },
   *                     {
   *                         name: 'UserID'
   *                     },
   *                     {
   *                         name: '_time'
   *                     },
   *                     {
   *                         name: '_span'
   *                     },
   *                 ],
   *                 columns: [
   *                     [
   *                         'Ms. Herman Beer',
   *                         'Crystal Ziemann',
   *                         'Jay Renner',
   *                         'Ora Borer',
   *                         'Dr. Bradford Gulgowski'
   *                     ],
   *                     [
   *                         'Enrico98',
   *                         'Taylor_Parker83',
   *                         'Charley.Feeney85',
   *                         'Jensen_Jacobson74',
   *                         'Dora_Volkman'
   *                     ],
   *                     [
   *                         '2020-04-12T06:32:08-07:00',
   *                         '2020-06-06T16:14:04-07:00',
   *                         '2020-08-10T14:54:16-07:00',
   *                         '2020-08-11T16:49:24-07:00',
   *                         '2020-09-29T03:52:51-07:00'
   *                     ],
   *                     [
   *                         '1800',
   *                         '1800',
   *                         '1800',
   *                         '1800',
   *                         '1800'
   *                     ]
   *                 ]
   *             },
   *             meta: {
   *                 totalCount: 100
   *             },
   *             requestParams {
   *                 count: 10,
   *                 offset: 0
   *             }
   *         }
   *     }}
   * />
   * ```
   * This code sample will visualize a table with the `Name` and `UserID` columns,
   * and the columns of `_time` and `_span` (internal fields) will not be displayed.
   *
   * Another example of using `frameWithoutInternalFields()` in a chained DSL:
   *
   * ```
   * <SingleValue
   *     options={{
   *         "majorValue": "> primary | frameWithoutInternalFields() | seriesByIndex(0) | lastPoint()"
   *     }},
   *     dataSources={{
   *         primary: {
   *             data: {
   *                 fields: [
   *                     {
   *                         name: '_time'
   *                     },
   *                     {
   *                         name: '_span'
   *                     },
   *                     {
   *                         name: 'Name'
   *                     },
   *                     {
   *                         name: 'UserID'
   *                     }
   *                 ],
   *                 columns: [
   *                     [
   *                         '2020-04-12T06:32:08-07:00',
   *                         '2020-06-06T16:14:04-07:00',
   *                         '2020-08-10T14:54:16-07:00',
   *                         '2020-08-11T16:49:24-07:00',
   *                         '2020-09-29T03:52:51-07:00'
   *                     ],
   *                     [
   *                         '1800',
   *                         '1800',
   *                         '1800',
   *                         '1800',
   *                         '1800'
   *                     ],
   *                     [
   *                         'Patti Hodkiewicz IV',
   *                         'Joanne Emmerich',
   *                         'Jay Renner',
   *                         'Ora Borer',
   *                         'Dr. Bradford Gulgowski'
   *                     ],
   *                     [
   *                         'Elwin52',
   *                         'Francis8',
   *                         'Charley.Feeney85',
   *                         'Jensen_Jacobson74',
   *                         'Dora_Volkman'
   *                     ]
   *                 ]
   *             },
   *             meta: {
   *                 totalCount: 100
   *             },
   *             requestParams {
   *                 count: 10,
   *                 offset: 0
   *             }
   *         }
   *     }}
   * />
   * ```
   * This code sample will visualize `Dr. Bradford Gulgowski` as the major value,
   * because both internal fields (`_time` and `_span`) are removed and index `0` of the rest of the data frame corresponds to the `Name` column.
   */
  frameWithoutInternalFields() {
    return new _DataFrame(
      this.series.filter((s) => !s.field.startsWith("_"))
    );
  }
  /**
   * Filter a DataFrame by removing all internal fields starting with underscore `_`, except for the fields listed in `names`.
   * For example, if you have a primary data source with the following fields: `_time, _span, date, count, cost, _raw`,
   * then DSL `> primary | frameWithoutInternalFields('_time')` removes all the internal fields except `_time` and returns the DataFrame with fields `_time, date, count, cost`.
   * If you want to remove all the internal fields, use `frameWithoutInternalFields()` instead.
   * If you pass any non-internal fields as parameters, they will be ignored.
   *
   * @public
   * @param {string[]} names
   * @returns {DataFrame<DataType>}
   *
   * The following code sample shows how to use `frameWithoutInternalFieldsExcept(...names)` to remove some internal fields from the data source, but leaving specified internal fields by their field names.
   *
   * ```
   * <Table
   *     options={{
   *         table: '> primary | frameWithoutInternalFieldsExcept('_time', '_span')'
   *     }},
   *     dataSources={{
   *         primary: {
   *             data: {
   *                 fields: [
   *                     {
   *                         name: 'Name'
   *                     },
   *                     {
   *                         name: 'UserID'
   *                     },
   *                     {
   *                         name: '_time'
   *                     },
   *                     {
   *                         name: '_span'
   *                     },
   *                     {
   *                         name: '_raw'
   *                     },
   *                 ],
   *                 columns: [
   *                     [
   *                         'Ms. Herman Beer',
   *                         'Joanne Emmerich',
   *                         'Jay Renner',
   *                         'Ora Borer',
   *                         'Dr. Bradford Gulgowski'
   *                     ],
   *                     [
   *                         'Enrico98',
   *                         'Francis8',
   *                         'Charley.Feeney85',
   *                         'Jensen_Jacobson74',
   *                         'Dora_Volkman'
   *                     ],
   *                     [
   *                         '2020-04-12T06:32:08-07:00',
   *                         '2020-09-26T16:06:03-07:00',
   *                         '2020-08-10T14:54:16-07:00',
   *                         '2020-08-11T16:49:24-07:00',
   *                         '2020-09-29T03:52:51-07:00'
   *                     ],
   *                     [
   *                         '1800',
   *                         '1800',
   *                         '1800',
   *                         '1800',
   *                         '1800'
   *                     ],
   *                     [
   *                         '2020-04-12T06:32:08-07:00',
   *                         '2020-09-26T16:06:03-07:00',
   *                         '2020-08-10T14:54:16-07:00',
   *                         '2020-08-11T16:49:24-07:00',
   *                         '2020-09-29T03:52:51-07:00'
   *                     ]
   *                 ]
   *             },
   *             meta: {
   *                 totalCount: 100
   *             },
   *             requestParams {
   *                 count: 10,
   *                 offset: 0
   *             }
   *         }
   *     }}
   * />
   * ```
   *
   * This code sample will visualize the table with the `Name`, `UserID`, `_time` and `_span` columns,
   * and the `_raw` columns will not be displayed.
   *
   * Another example of using `frameWithoutInternalFieldsExcept(...names)` in a chained DSL:
   *
   * ```
   * <SingleValue
   *     options={{
   *         "majorValue": "> primary | frameWithoutInternalFieldsExcept('_time') | seriesByIndex(1) | lastPoint()"
   *     }},
   *     dataSources={{
   *         primary: {
   *             data: {
   *                 fields: [
   *                     {
   *                         name: '_time'
   *                     },
   *                     {
   *                         name: '_span'
   *                     },
   *                     {
   *                         name: '_raw'
   *                     },
   *                     {
   *                         name: 'Name'
   *                     },
   *                     {
   *                         name: 'UserID'
   *                     }
   *                 ],
   *                 columns: [
   *                     [
   *                         '2020-04-12T06:32:08-07:00',
   *                         '2020-09-26T16:06:03-07:00',
   *                         '2020-08-10T14:54:16-07:00',
   *                         '2020-08-11T16:49:24-07:00',
   *                         '2020-09-29T03:52:51-07:00'
   *                     ],
   *                     [
   *                         '1800',
   *                         '1800',
   *                         '1800',
   *                         '1800',
   *                         '1800'
   *                     ],
   *                     [
   *                         '2020-04-12T06:32:08-07:00',
   *                         '2020-06-06T16:14:04-07:00',
   *                         '2020-08-10T14:54:16-07:00',
   *                         '2020-08-11T16:49:24-07:00',
   *                         '2020-09-29T03:52:51-07:00'
   *                     ],
   *                     [
   *                         'Ms. Herman Beer',
   *                         'Crystal Ziemann',
   *                         'Angel Krajcik',
   *                         'Jay Renner',
   *                         'Dr. Bradford Gulgowski'
   *                     ],
   *                     [
   *                         'Candice_Carroll',
   *                         'Elwin52',
   *                         'Francis8',
   *                         'Charley.Feeney85',
   *                         'Dora_Volkman'
   *                     ]
   *                 ]
   *             },
   *             meta: {
   *                 totalCount: 100
   *             },
   *             requestParams {
   *                 count: 10,
   *                 offset: 0
   *             }
   *         }
   *     }}
   * />
   * ```
   *
   * This code sample will visualize `Dr. Bradford Gulgowski` as the major value, because the internal fields other than `_time` are excluded,
   * and index `1` of the rest of the data frame (`_time`, `Name`, `UserID`) corresponds to the `Name` column.
   */
  frameWithoutInternalFieldsExcept(...names) {
    if (!names || names.length === 0) {
      return this.frameWithoutInternalFields();
    }
    const fields = this.series.map((s) => s.field);
    const validNames = names.filter((name) => fields.includes(name));
    return new _DataFrame(
      this.series.filter(
        (s) => validNames.includes(s.field) || !s.field.startsWith("_")
      )
    );
  }
  /**
   * Filter a DataFrame by specifying one or more names or indexes of DataSeries you would like to return.
   * For example,`frameBySeriesNames(first_name_or_index, second_name_or_index, ...)`, where at least one name or index is required.
   * @public
   * @param {...(string|number)} namesOrIndexes
   * @returns {DataFrame<DataType>}
   *
   * The following code sample shows how to use frameBySeriesNamesOrIndexes to render a table with the Name DataSeries and the fourth DataSeries in the data source.
   *
   * ```
   * <Table
   *     options={{
   *         table: '> primary | frameBySeriesNamesOrIndexes("Name", 3)'
   *     }},
   *     dataSources={{
   *         primary: {
   *             data: {
   *                 fields: [
   *                     {
   *                         name: 'Name'
   *                     },
   *                     {
   *                         name: 'UserID'
   *                     },
   *                     {
   *                         name: 'Money Spent'
   *                     },
   *                     {
   *                         name: 'Most Recent Game'
   *                     },
   *                 ],
   *                 columns: [
   *                     [
   *                         'Ms. Herman Beer',
   *                         'Crystal Ziemann',
   *                         'Phil Bartoletti',
   *                         'Janis Kiehn V',
   *                         'Angel Krajcik',
   *                         'Patti Hodkiewicz IV',
   *                         'Joanne Emmerich',
   *                         'Jay Renner',
   *                         'Ora Borer',
   *                         'Dr. Bradford Gulgowski'
   *                     ],
   *                     [
   *                         'Enrico98',
   *                         'Taylor_Parker83',
   *                         'Candice_Carroll',
   *                         'Yolanda_McLaughlin95',
   *                         'Modesto84',
   *                         'Elwin52',
   *                         'Francis8',
   *                         'Charley.Feeney85',
   *                         'Jensen_Jacobson74',
   *                         'Dora_Volkman'
   *                     ],
   *                     [
   *                         9740890.83,
   *                         2107983.52,
   *                         5467223.67,
   *                         9529184.93,
   *                         9692275.78,
   *                         9395814.7,
   *                         5692737.43,
   *                         1001734.82,
   *                         3848531.8,
   *                         1691776.38
   *                     ],
   *                     [
   *                         '2020-04-12T06:32:08-07:00',
   *                         '2020-06-06T16:14:04-07:00',
   *                         '2020-02-12T09:43:25-08:00',
   *                         '2020-07-25T13:19:49-07:00',
   *                         '2020-03-16T21:46:40-07:00',
   *                         '2020-08-21T08:38:55-07:00',
   *                         '2020-09-26T16:06:03-07:00',
   *                         '2020-08-10T14:54:16-07:00',
   *                         '2020-08-11T16:49:24-07:00',
   *                         '2020-09-29T03:52:51-07:00',
   *                     ]
   *                 ]
   *             },
   *             meta: {
   *                 totalCount: 100
   *             },
   *             requestParams: {
   *                 count: 10,
   *                 offset: 0
   *             }
   *         }
   *     }}
   * />
   */
  frameBySeriesNamesOrIndexes(...mixed) {
    const mixedSeries = [];
    mixed.forEach((nameOrIndex) => {
      const asNumber = Number(nameOrIndex);
      if (Number.isNaN(asNumber)) {
        const found = this.seriesByName(nameOrIndex);
        if (found) {
          mixedSeries.push(found);
        }
      } else {
        const found = this.series[asNumber];
        if (found) {
          mixedSeries.push(found);
        }
      }
    });
    return new _DataFrame(mixedSeries);
  }
  /**
   * Filter a DataFrame by specifying one or more types of DataSeries you would like to return.
   * For example, `frameBySeriesNames(first_type, second_type, ...)`, where at least one type is required.
   * @public
   * @param {DataType[]} types
   * @returns {DataFrame<DataType>}
   *
   * The following code sample shows how to use frameBySeriesTypes to render a table that contains only the string columns in the data source.
   *
   * ```
   * <Table
   *     options={{
   *         table: '> primary | frameBySeriesTypes("string")'
   *     }},
   *     dataSources={{
   *         primary: {
   *             data: {
   *                 fields: [
   *                     {
   *                         name: 'Name'
   *                     },
   *                     {
   *                         name: 'UserID'
   *                     },
   *                     {
   *                         name: 'Money Spent'
   *                     },
   *                     {
   *                         name: 'Most Recent Game'
   *                     },
   *                 ],
   *                 columns: [
   *                     [
   *                         'Ms. Herman Beer',
   *                         'Crystal Ziemann',
   *                         'Phil Bartoletti',
   *                         'Janis Kiehn V',
   *                         'Angel Krajcik',
   *                         'Patti Hodkiewicz IV',
   *                         'Joanne Emmerich',
   *                         'Jay Renner',
   *                         'Ora Borer',
   *                         'Dr. Bradford Gulgowski'
   *                     ],
   *                     [
   *                         'Enrico98',
   *                         'Taylor_Parker83',
   *                         'Candice_Carroll',
   *                         'Yolanda_McLaughlin95',
   *                         'Modesto84',
   *                         'Elwin52',
   *                         'Francis8',
   *                         'Charley.Feeney85',
   *                         'Jensen_Jacobson74',
   *                         'Dora_Volkman'
   *                     ],
   *                     [
   *                         9740890.83,
   *                         2107983.52,
   *                         5467223.67,
   *                         9529184.93,
   *                         9692275.78,
   *                         9395814.7,
   *                         5692737.43,
   *                         1001734.82,
   *                         3848531.8,
   *                         1691776.38
   *                     ],
   *                     [
   *                         '2020-04-12T06:32:08-07:00',
   *                         '2020-06-06T16:14:04-07:00',
   *                         '2020-02-12T09:43:25-08:00',
   *                         '2020-07-25T13:19:49-07:00',
   *                         '2020-03-16T21:46:40-07:00',
   *                         '2020-08-21T08:38:55-07:00',
   *                         '2020-09-26T16:06:03-07:00',
   *                         '2020-08-10T14:54:16-07:00',
   *                         '2020-08-11T16:49:24-07:00',
   *                         '2020-09-29T03:52:51-07:00'
   *                     ]
   *                 ]
   *             },
   *             meta: {
   *                 totalCount: 100
   *             },
   *             requestParams: {
   *                 count: 10,
   *                 offset: 0
   *             }
   *         }
   *     }}
   * />
   */
  frameBySeriesTypes(...types) {
    return new _DataFrame(
      this.series.filter((s) => types.includes(s.getType()))
    );
  }
  /**
   * Select a DataSeries by specifying the name of the DataSeries you would like to return.
   * @public
   * @param {string} field
   * @returns {DataSeries<DataType>}
   *
   * The following code sample shows how to use seriesByName to display the count series in a data source as a single value.
   *
   * ```
   * <SingleValue
   *     options={{
   *         sparklineValues: '> primary | seriesByName("count")',
   *     }}
   *     dataSources={{
   *         primary: {
   *             data: {
   *                 fields: [
   *                     {
   *                         name: '_time',
   *                     },
   *                     {
   *                         name: 'count',
   *                     },
   *                 ],
   *                 columns: [
   *                     [
   *                         '2018-08-19T00:00:00.000+00:00',
   *                         '2018-08-20T00:00:00.000+00:00',
   *                         '2018-08-21T00:00:00.000+00:00',
   *                         '2018-08-22T00:00:00.000+00:00',
   *                         '2018-08-23T00:00:00.000+00:00',
   *                         '2018-08-24T00:00:00.000+00:00',
   *                         '2018-08-25T00:00:00.000+00:00',
   *                         '2018-08-26T00:00:00.000+00:00',
   *                     ],
   *                     ['1', '62', '103', '308', '587', '876', '930', '1320'],
   *                 ],
   *             },
   *             meta: {},
   *         },
   *     }}
   * />
   */
  // SCP-60632: added a second parameter - empty array as default fallback, hidden from user
  seriesByName(field, defaultSeries = []) {
    var _a;
    return (_a = this.series.find((dataSeries) => field === dataSeries.field)) != null ? _a : defaultSeries;
  }
  /**
   * Select a DataSeries by specifying the type of the DataSeries you would like to return. The first DataSeries that matches the first type specified will be returned. If no DataSeries matches the first type specified, no DataSeries will be returned.
   * @public
   * @param {DataType} type
   * @returns {DataSeries<DataType>}
   *
   * The following code sample shows how to use seriesByType to display the first numeric series in a data source as a single value.
   *
   * If no numeric series are found, return nothing and display N/A.
   *
   * ```
   * <SingleValue
   *     options={{
   *         sparklineValues: '> primary | seriesByType("number")',
   *     }}
   *     dataSources: {{
   *         primary: {
   *             data: {
   *                 fields: [
   *                     {
   *                         name: '_time",
   *                     },
   *                     {
   *                         name: 'count',
   *                     },
   *                 ],
   *                 columns: [
   *                     [
   *                         '2018-08-19T00:00:00.000+00:00',
   *                         '2018-08-20T00:00:00.000+00:00',
   *                         '2018-08-21T00:00:00.000+00:00',
   *                         '2018-08-22T00:00:00.000+00:00',
   *                         '2018-08-23T00:00:00.000+00:00',
   *                         '2018-08-24T00:00:00.000+00:00',
   *                         '2018-08-25T00:00:00.000+00:00',
   *                         '2018-08-26T00:00:00.000+00:00',
   *                     ],
   *                     [ '1', '62', '103', '308', '587', '876', '930', '1320'],
   *                 ],
   *             },
   *             meta: {},
   *         },
   *     }}
   * />
   */
  seriesByType(type) {
    return this.series.find((dataSeries) => {
      const dataType = dataSeries.getType();
      return dataType === type;
    });
  }
  /**
   * Select a DataSeries by specifying any acceptable types of the DataSeries you would like to return. The first DataSeries that matches any of the types specified will be returned. If no DataSeries matches the type options specified, no DataSeries will be returned.
   * @public
   * @param {DataType[]} types
   * @returns {DataSeries<DataType>}
   */
  seriesByTypes(...types) {
    return this.series.find(
      (dataSeries) => types.some((type) => dataSeries.getType() === type)
    );
  }
  /**
   * Select a DataSeries by specifying the prioritized types of the DataSeries you would like to return. The first DataSeries that matches the first type specified will be returned. If no DataSeries matches the first type specified, the first DataSeries that matches the second type will be returned, and so on.
   * @public
   * @param {DataType[]} types
   * @returns {DataSeries<DataType>}
   *
   * The following code sample shows how to use seriesByPrioritizedTypes to display the first numeric series in a data source as a single value.
   *
   * If no numeric series are found in the data, the first series of type string is displayed. If no string series are found, the first series of type time is displayed.
   *
   * ```
   * <SingleValue
   *     options={{
   *         sparklineValues: '> primary | seriesByPrioritizedTypes'("number", "string", "time"),
   *     }}
   *     dataSources={{
   *         primary: {
   *             data: {
   *                 columns: [
   *                     [
   *                         '2018-08-19T00:00:00.000+00:00',
   *                         '2018-08-20T00:00:00.000+00:00',
   *                         '2018-08-21T00:00:00.000+00:00',
   *                         '2018-08-22T00:00:00.000+00:00',
   *                         '2018-08-23T00:00:00.000+00:00',
   *                         '2018-08-24T00:00:00.000+00:00',
   *                         '2018-08-25T00:00:00.000+00:00',
   *                         '2018-08-26T00:00:00.000+00:00',
   *                     ],
   *                     [ 'INFO', 'ERROR', 'WARN', 'INFO', 'ERROR', 'WARN', 'INFO', 'WARN'],
   *                 ],
   *                 fields: [
   *                     {
   *                         name: '_time',
   *                     },
   *                     {
   *                         name: 'status',
   *                     },
   *                 ],
   *             },
   *             meta: {},
   *         },
   *     }}
   * />
   */
  seriesByPrioritizedTypes(...types) {
    var _a;
    for (const type of types) {
      const matchedSeries = this.seriesByType(type);
      if (Array.isArray(matchedSeries == null ? void 0 : matchedSeries.points) && ((_a = matchedSeries == null ? void 0 : matchedSeries.points) == null ? void 0 : _a.length)) {
        return matchedSeries;
      }
    }
    return this.series[0];
  }
  /**
   * Set all values in the DataFrame to a static TypedValue.
   * @public
   * @param {TypedValue} v
   */
  setValue(v) {
    this.series.forEach((s) => s.setValue(v));
  }
  /**
   * Get all values in the DataFrame. This excludes field names.
   * @public
   * @returns {array}
   */
  getRawValue() {
    const values = [];
    this.series.forEach((s) => {
      values.push(s.getRawValue());
    });
    return values;
  }
  /**
   * Get all values and their types in the DataFrame. This excludes field names.
   * @public
   * @returns {TypedValue[][]}
   */
  getValue() {
    const values = [];
    this.series.forEach((s) => {
      values.push(s.getValue());
    });
    return values;
  }
  /**
   * Get the names of each DataSeries in the DataFrame.
   * @public
   * @returns {DataSeries<string>}
   *
   * ```
   * <Table
   *   options={{
   *       headers: '> table | getField()'
   *   }},
   *   dataSources={{
   *     primary: {
   *       data: {
   *         fields: [
   *           {
   *              name: 'Name'
   *           },
   *           {
   *              name: 'UserID'
   *           },
   *           {
   *              name: 'Money Spent'
   *           },
   *           {
   *              name: 'Most Recent Game'
   *           },
   *         ],
   *         columns: [
   *           [
   *              'Ms. Herman Beer',
   *              'Crystal Ziemann',
   *              'Phil Bartoletti',
   *              'Janis Kiehn V',
   *              'Angel Krajcik',
   *              'Patti Hodkiewicz IV',
   *              'Joanne Emmerich',
   *              'Jay Renner',
   *              'Ora Borer',
   *              'Dr. Bradford Gulgowski'
   *           ],
   *           [
   *              'Enrico98',
   *              'Taylor_Parker83',
   *              'Candice_Carroll',
   *              'Yolanda_McLaughlin95',
   *              'Modesto84',
   *              'Elwin52',
   *              'Francis8',
   *              'Charley.Feeney85',
   *              'Jensen_Jacobson74',
   *              'Dore_Volkman'
   *           ],
   *           [
   *              9740890.83,
   *              2107983.52,
   *              5467223.67,
   *              9529184.93,
   *              9692275.78,
   *              9395814.7,
   *              5692737.43,
   *              1001734.82,
   *              3848531.8,
   *              1691776.38
   *           ],
   *           [
   *              '2020-04-12T06:32:08-07:00',
   *              '2020-06-06T16:14:04-07:00',
   *              '2020-02-12T09:43:25-08:00',
   *              '2020-07-25T13:19:49-07:00',
   *              '2020-03-16T21:46:40-07:00',
   *              '2020-08-21T08:38:55-07:00',
   *              '2020-09-26T16:06:03-07:00',
   *              '2020-08-10T14:54:16-07:00',
   *              '2020-08-11T16:49:24-07:00',
   *              '2020-09-29T03:52:51-07:00'
   *           ]
   *         ]
   *      },
   *      meta: {
   *        totalCount: 100
   *      },
   *      requestParams: {
   *        count: 10,
   *        offset: 0
   *      }
   *     }
   *   }}
   * />
   *
   * Display the third and fourth DataSeries in a column chart as overlay fields.
   *
   * <Column
   *   options={{
   *     overlayFields: '> primary | frameBySeriesIndex(2,3) | getField()'
   *   }},
   *   dataSources={{
   *     primary: {
   *       requestParams: { offset: 0, count: 20},
   *       data: {
   *         fields: [
   *             { name: '_time' },
   *             { name: 'splunkd' },
   *             { name: 'splunkd_web_access' },
   *             { name: 'mongod' },
   *         ],
   *         columns: [
   *             [
   *                 '2018-05-02T18:15:46.000-07:00',
   *                 '2018-05-02T18:15:47.000-07:00',
   *                 '2018-05-02T18:15:48.000-07:00',
   *                 '2018-05-02T18:15:49.000-07:00',
   *                 '2018-05-02T18:15:50.000-07:00',
   *             ],
   *             ['67228', '83195', '3145', '19332', '29763'],
   *             ['67228', '83195', '3145', '19332', '29763'],
   *             ['14881', '17341', '18081', '19774', '10467'],
   *         ]
   *       },
   *       meta: {
   *         totalCount: 100,
   *       }
   *     }
   *   }}
   * />
   */
  getField() {
    const points = this.series.map((s) => s.getField());
    return new DataSeries(points);
  }
  /**
   * Get the data type of each DataSeries in the DataFrame.
   * @public
   * @returns {string[]}
   */
  getType() {
    return this.series.map((s) => s.getType());
  }
  /**
   * Get the global minimum value from all numeric DataSeries in the DataFrame.
   * @public
   * @returns {number}
   *
   * The following code sample shows how to use min to display the smallest data point in a data source as a single value.
   *
   * ```
   * <SingleValue
   *     options={{
   *         majorValue: '> primary | min()',
   *         trendDisplay: 'off',
   *         sparklineDisplay: 'off'
   *     }}
   *     dataSources={{
   *         primary: {
   *             data: {
   *                 fields: [
   *                     {
   *                         name: '_time',
   *                     },
   *                     {
   *                         name: 'count',
   *                     },
   *                 ],
   *                 columns: [
   *                     [
   *                         '2018-08-19T00:00:00.000+00:00',
   *                         '2018-08-20T00:00:00.000+00:00',
   *                         '2018-08-21T00:00:00.000+00:00',
   *                         '2018-08-22T00:00:00.000+00:00',
   *                         '2018-08-23T00:00:00.000+00:00',
   *                         '2018-08-24T00:00:00.000+00:00',
   *                         '2018-08-25T00:00:00.000+00:00',
   *                         '2018-08-26T00:00:00.000+00:00',
   *                     ],
   *                     ['1', '62', '103', '308', '587', '876', '930', '1320'],
   *                 ],
   *             },
   *             meta: {},
   *         },
   *     }}
   * />
   */
  min() {
    return this.minOrMax("min");
  }
  /**
   * Get the global maximum value from all numeric DataSeries in the DataFrame.
   * @public
   * @returns {number}
   *
   * The following code sample shows how to use max to display the largest data point in a data source as a single value.
   *
   * ```
   * <SingleValue
   *     options={{
   *         majorValue: '> primary | max()',
   *         trendDisplay: 'off',
   *         sparklineDisplay: 'off',
   *     }}
   *     dataSources={{
   *         primary: {
   *             data: {
   *                 fields: [
   *                     {
   *                         name: '_time',
   *                     },
   *                     {
   *                         name: 'count',
   *                     },
   *                 ],
   *                 columns: [
   *                     [
   *                         '2018-08-19T00:00:00.000+00:00',
   *                         '2018-08-20T00:00:00.000+00:00',
   *                         '2018-08-21T00:00:00.000+00:00',
   *                         '2018-08-22T00:00:00.000+00:00',
   *                         '2018-08-23T00:00:00.000+00:00',
   *                         '2018-08-24T00:00:00.000+00:00',
   *                         '2018-08-25T00:00:00.000+00:00',
   *                         '2018-08-26T00:00:00.000+00:00',
   *                     ],
   *                     [ '1', '62', '103', '308', '587', '876', '930', '1320' ],
   *                 ],
   *             },
   *             meta: {},
   *         },
   *     }}
   * />
   */
  max() {
    return this.minOrMax("max");
  }
  /**
   * runs result of min or max function over all the series and returns the data point
   * points
   * @param {string} aggName
   * @returns {DataPoint<T>}
   */
  minOrMax(funcName) {
    const overallSeries = new DataSeries();
    this.series.forEach((s) => {
      const m = s[funcName]();
      if (m) {
        overallSeries.points.push(m);
      }
    });
    return overallSeries[funcName]();
  }
};

// src/DataSeriesLite.ts
var DataSeriesLite = class extends DataSeries {
  /**
   *
   * @param {string} type user explicitly sets the data type
   * @param {string} field or column name
   * @param {ColumnVal} the raw values
   */
  constructor(values, type, field) {
    super([], type, field);
    this.internalPoints = [];
    this.values = values;
    const dataTypeForMeta = getDataTypeForMeta({ name: field, type });
    if (dataTypeForMeta !== "unknown") {
      this.type = dataTypeForMeta;
    }
  }
  get points() {
    this.values.forEach((rawValue, index) => {
      if (!this.internalPoints[index]) {
        this.createDataPointFromValueAtIndex(index);
      }
    });
    return this.internalPoints;
  }
  /**
   * Return first dataPoint in series.
   * @public
   * @returns {DataPoint}
   */
  firstPoint() {
    if (!this.internalPoints[0]) {
      this.createDataPointFromValueAtIndex(0);
    }
    return this.internalPoints[0];
  }
  /**
   * Return last dataPoint in series.
   * @public
   * @returns {DataPoint}
   */
  lastPoint() {
    if (!this.internalPoints[this.values.length - 1]) {
      this.createDataPointFromValueAtIndex(this.values.length - 1);
    }
    return this.internalPoints[this.internalPoints.length - 1];
  }
  /**
   * Finds dataPoint(s) in DataSeries by index(es).
   * @public
   * @param {...number} indexes
   * @returns {DataSeries}
   */
  pointsByIndexes(...indexes) {
    const indexedPoints = [];
    indexes.forEach((index) => {
      let dp = this.internalPoints[index];
      if (!dp) {
        dp = this.createDataPointFromValueAtIndex(index);
      }
      if (dp != null) {
        indexedPoints.push(dp);
      }
    });
    return new DataSeries(indexedPoints);
  }
  /**
   * Finds and returns the individual dataPoint at the given index.
   * @public
   * @param {number} index
   * @returns {DataPoint}
   */
  pointByIndex(indexIn) {
    let index = indexIn;
    if (index < 0) {
      index = this.values.length + index;
    }
    if (index < 0 || index >= this.values.length) {
      return null;
    }
    let dp = this.internalPoints[index];
    if (!dp) {
      dp = this.createDataPointFromValueAtIndex(index);
    }
    return dp;
  }
  /**
   * Finds the delta between the last point and point at the given index.
   * A negative index can be used, indicating an offset from the end of the sequence.
   * @public
   * @param {number} index
   * @returns {DataPoint}
   */
  delta(index) {
    const dp1 = this.lastPoint();
    if (dp1 === void 0) {
      return void 0;
    }
    const { field } = dp1;
    const { type, value: val1 } = dp1.getValue();
    if (type !== "number") {
      console.warn(`DSL delta cannot be computed for non-numerical data series of type ${type}`);
    }
    let dp2 = null;
    let delta;
    if (index >= 0) {
      dp2 = this.internalPoints[index];
      if (!dp2) {
        dp2 = this.createDataPointFromValueAtIndex(index);
      }
    } else {
      const newIndex = this.values.length + index;
      dp2 = this.internalPoints[newIndex];
      if (!dp2) {
        dp2 = this.createDataPointFromValueAtIndex(newIndex);
      }
    }
    if (dp2 == null) {
      console.warn("DSL delta cannot be computed, no data - invalid index");
    } else {
      const { value: val2 } = dp2.getValue();
      delta = val1 - val2;
    }
    if (Number.isNaN(delta)) {
      delta = void 0;
    }
    return new DataPoint(field, { type, value: delta });
  }
  /**
   * Sets all the values in the Data Series to a static TypedValue.
   * @param {TypedValue} v
   */
  setValue(v) {
    this.internalPoints.forEach((p) => {
      p.setValue(v);
    });
    this.values.fill(v.value);
    this.type = inferDataTypeFromDataPoints(this.points);
  }
  /**
   * Gets all the values + their type in the Data Series.
   * @returns {TypedValue[]}
   */
  getValue() {
    const values = [];
    this.points.forEach((p) => {
      values.push(p.getValue());
    });
    return values;
  }
  /**
   * Gets all the values (only) in the Data Series.
   * @returns {array}
   */
  getRawValue() {
    return this.values;
  }
  createDataPointFromValueAtIndex(index) {
    const dataType = getDataTypeForPoint(this.values[index], {
      name: this.field,
      type: this.type
    });
    this.internalPoints[index] = new DataPoint(String(this.field), {
      type: dataType,
      value: this.values[index]
    });
    return this.internalPoints[index];
  }
};

// src/Formatter.ts
var AbstractFormatter = class {
  format(dataPrimitive) {
    if (dataPrimitive instanceof DataFrame) {
      const newSeries = [];
      dataPrimitive.series.forEach((dataSeries, i) => {
        newSeries.push(this.formatSeries(dataSeries, i));
      });
      return new DataFrame(newSeries);
    }
    if (dataPrimitive instanceof DataSeries || dataPrimitive instanceof DataSeriesLite) {
      return this.formatSeries(dataPrimitive);
    }
    return this.formatPoint(dataPrimitive);
  }
  formatSeries(s, i = 0) {
    const newPoints = [];
    s.points.forEach((dataPoint, j) => {
      newPoints.push(this.formatPoint(dataPoint, s, i, j));
    });
    return new DataSeries(newPoints);
  }
  formatPoint(p, s, i = 0, j = 0) {
    const { field } = p;
    const dp = new DataPoint(field, {
      type: p.getValue().type,
      value: p.getValue().coercedValue
    });
    const tmp = this.formatTypedValue(dp, s, i, j);
    return new DataPoint(field, tmp);
  }
  makeArrays2D(a) {
    if (Array.isArray(a)) {
      if (Array.isArray(a[0])) {
        return a;
      }
      return [a];
    }
    throw new Error("argument wasn't array");
  }
};

// src/formatters/FormatByType.ts
var formatNumber = (number, config) => {
  const mappedConfig = {
    prefix: !(0, lodash_exports.isEmpty)(config.unit) && config.unitPosition === "before" ? `${config.unit} ` : void 0,
    postfix: !(0, lodash_exports.isEmpty)(config.unit) && config.unitPosition !== "before" ? ` ${config.unit}` : void 0,
    mantissa: typeof config.precision === "number" ? config.precision : void 0
  };
  const c = (0, lodash_exports.defaultsDeep)(
    {},
    (0, lodash_exports.omitBy)(mappedConfig, lodash_exports.isUndefined),
    (0, lodash_exports.omit)(config, ["unit", "unitPosition", "precision"])
  );
  return numbro_default(number).format(c);
};
var formatString = (string, config) => {
  if (!(0, lodash_exports.isEmpty)(config.unit)) {
    return config.unitPosition === "before" ? `${config.unit} ${string}` : `${string} ${config.unit}`;
  }
  return `${string}`;
};
var formatTime = (dateString, defaultValue, config) => {
  if (typeof config.format === "string" && !(0, lodash_exports.isEmpty)(config.format)) {
    return formatTimeWithTimezoneCorrection(dateString, config.format);
  }
  return defaultValue.toString();
};
var FormatByType = class extends AbstractFormatter {
  constructor(config) {
    super();
    this.config = {
      number: {},
      string: {},
      time: { format: "" }
    };
    this.config = (0, lodash_exports.defaultsDeep)({}, config, this.config);
  }
  formatTypedValue(p) {
    const { number: numberConfig, string: stringConfig, time: timeConfig } = this.config;
    const value = p.getValue();
    switch (value.type) {
      case "number":
        return new TypeSafeValue(
          "string",
          formatNumber(p.getRawValue(), numberConfig),
          value.value
        );
      case "string":
        return new TypeSafeValue("string", formatString(value.value, stringConfig), value.value);
      case "time":
        return new TypeSafeValue(
          "string",
          formatTime(value.coercedValue, value.value, timeConfig),
          value.value
        );
      default:
        return p.getValue();
    }
  }
};
//# sourceMappingURL=FormatByType.js.map
