/* 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 __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/utils/parserUtils.js
var parserUtils_exports = {};
__export(parserUtils_exports, {
  INVALID_VALUE: () => INVALID_VALUE,
  MAX_LOGGED_FORMATTER_ERRORS: () => MAX_LOGGED_FORMATTER_ERRORS,
  NON_NUMERIC_RANGE_ERROR: () => NON_NUMERIC_RANGE_ERROR,
  VALUES_AND_RANGES_HAVE_DIFFERENT_LENGTH: () => VALUES_AND_RANGES_HAVE_DIFFERENT_LENGTH,
  categoryFormat: () => categoryFormat,
  colorGradientFormat: () => colorGradientFormat,
  drawSample: () => drawSample,
  getDataTypeForPoint: () => getDataTypeForPoint,
  getFormatter: () => getFormatter,
  inferDataTypeFromSample: () => inferDataTypeFromSample,
  matchValueFormat: () => matchValueFormat,
  mergeEncoding: () => mergeEncoding,
  newFormatterErrorHandler: () => newFormatterErrorHandler,
  parse: () => parse,
  parseFieldRangeReference: () => parseFieldRangeReference,
  parseIndexBasedFieldReference: () => parseIndexBasedFieldReference,
  parseNameBasedFieldReference: () => parseNameBasedFieldReference,
  rangeFormat: () => rangeFormat,
  rangeValueFormat: () => rangeValueFormat
});
module.exports = __toCommonJS(parserUtils_exports);

// esm-externals:chroma-js
var chroma_js_exports = {};
__export(chroma_js_exports, {
  default: () => chroma_js_default
});
var defaultImport = __toESM(require("chroma-js"));
__reExport(chroma_js_exports, require("chroma-js"));
var chroma_js_default = "default" in defaultImport ? defaultImport.default : defaultImport;

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

// src/utils/parserUtils.js
var { hasOwnProperty } = Object.prototype;
var getDataTypeForPoint = (dataPoint) => {
  if ((0, lodash_exports.isFinite)(+dataPoint) && (0, lodash_exports.isNumber)(+dataPoint)) {
    return "number";
  }
  if (!Number.isNaN(Date.parse(dataPoint))) {
    return "time";
  }
  if (typeof dataPoint === "string") {
    return "string";
  }
  return "unknown";
};
var inferDataTypeFromSample = (dataSample) => {
  const typeMatches = {
    time: 0,
    number: 0,
    string: 0,
    unknown: 0
  };
  dataSample.forEach((point) => {
    typeMatches[getDataTypeForPoint(point)] += 1;
  });
  let typeCount = -1;
  let returnType = "unknown";
  Object.keys(typeMatches).forEach((key) => {
    if (typeMatches[key] > typeCount) {
      typeCount = typeMatches[key];
      returnType = key;
    }
  });
  return returnType;
};
var drawSample = (data) => {
  if (data.length > 2) {
    return [data[0], data[Math.floor(data.length / 2)], data[data.length - 1]];
  }
  if (data.length === 2) {
    return [data[0], data[1]];
  }
  return data;
};
var rangeFormat = (value, { ranges, values } = {}) => {
  if (Array.isArray(ranges) && Array.isArray(values) && !Number.isNaN(value)) {
    const floatVal = parseFloat(value);
    for (let i = 0; i < ranges.length; i += 1) {
      if (Number.isNaN(Number(ranges[i]))) {
        return value;
      }
      if (floatVal <= parseFloat(ranges[i])) {
        const valueIndex = Math.min(i, values.length - 1);
        if (values[valueIndex]) {
          return values[valueIndex];
        }
      }
    }
    if (floatVal > parseFloat(ranges[ranges.length - 1])) {
      return values[values.length - 1];
    }
  }
  return value;
};
var categoryFormat = (value, { categories, values }) => {
  if (!(Array.isArray(categories) && Array.isArray(values) && categories.length === values.length)) {
    return value;
  }
  const valueIndex = categories.indexOf(value);
  if (valueIndex > -1) {
    return values[valueIndex];
  }
  return value;
};
var rangeValueFormat = (value, { ranges = [] }) => {
  const floatValue = parseFloat(value);
  if (Number.isNaN(Number(value))) {
    return value;
  }
  for (let i = 0; i < ranges.length; i += 1) {
    if (
      // open upper bound: value is bigger than or equal to open upper bound start (from)
      i === 0 && hasOwnProperty.call(ranges[i], "from") && floatValue >= ranges[i].from || // inbetween: value falls into from - to range
      floatValue >= ranges[i].from && floatValue < ranges[i].to || // open lower bound: value is smaller than or equal to open lower bound end (to)
      i === ranges.length - 1 && hasOwnProperty.call(ranges[i], "to") && floatValue < ranges[i].to
    ) {
      return ranges[i].value;
    }
  }
  return value;
};
var matchValueFormat = (value, { matches = [], defaultValue = void 0 }) => {
  const defaultResult = (0, lodash_exports.isUndefined)(defaultValue) ? value : defaultValue;
  const matchResult = (0, lodash_exports.find)(matches, (match) => match.match && match.match === value);
  return (0, lodash_exports.isUndefined)(matchResult) ? defaultResult : matchResult.value;
};
var NON_NUMERIC_RANGE_ERROR = "Could not format value: Ranges are required to be numbers. Falling back to first color";
var VALUES_AND_RANGES_HAVE_DIFFERENT_LENGTH = "gradient ranges and values must have the same number of elements";
var INVALID_VALUE = "Could not format value for gradient:";
var colorGradientFormat = (value, { ranges, values }, data, errorHandler) => {
  let colorValues = values;
  let colorRanges = ranges;
  function errorColor() {
    return colorValues ? chroma_js_default(colorValues[0]).hex().toUpperCase() : "#000";
  }
  if (!Number.isNaN(Number(value))) {
    if (!colorValues) {
      colorValues = ["white", "red"];
    }
    if (colorValues.length === 1) {
      colorValues.unshift("white");
    }
    if (!ranges) {
      if (data && data.length > 0) {
        const min = data.length > 0 ? Math.min.apply(null, data) : void 0;
        const max = data.length > 0 ? Math.max.apply(null, data) : void 0;
        colorRanges = [min];
        for (let i = 1; i < colorValues.length - 1; i += 1) {
          colorRanges.push(min + i * (max - min) / (colorValues.length - 1));
        }
        colorRanges.push(max);
      } else {
        colorRanges = [0, 1];
      }
    }
    if (colorRanges.length === 1) {
      colorRanges.push(colorRanges[0]);
    }
    colorRanges.sort((a, b) => a - b);
    if (colorRanges.length !== colorValues.length) {
      errorHandler(VALUES_AND_RANGES_HAVE_DIFFERENT_LENGTH);
      return errorColor();
    }
    const floatVal = parseFloat(value);
    if (floatVal > parseFloat(colorRanges[colorRanges.length - 1])) {
      return chroma_js_default(colorValues[colorValues.length - 1]).hex().toUpperCase();
    }
    if (floatVal < parseFloat(colorRanges[0])) {
      return chroma_js_default(colorValues[0]).hex().toUpperCase();
    }
    for (let i = 1; i < colorRanges.length; i += 1) {
      if (Number.isNaN(Number(colorRanges[i]))) {
        errorHandler(NON_NUMERIC_RANGE_ERROR);
        return errorColor();
      }
      const upperVal = colorRanges[i];
      if (floatVal <= upperVal) {
        const lowerVal = colorRanges[i - 1];
        let tau = (value - lowerVal) / (upperVal - lowerVal);
        if (upperVal === lowerVal) {
          if (value === 0) {
            tau = 0;
          } else {
            tau = 1;
          }
        }
        const upperColor = colorValues[i];
        const lowerColor = colorValues[i - 1];
        return chroma_js_default.scale([lowerColor, upperColor])(tau).hex().toUpperCase();
      }
    }
  }
  errorHandler(`${INVALID_VALUE} ${value}`);
  return errorColor();
};
var formatters = {
  rangevalue: rangeValueFormat,
  matchvalue: matchValueFormat,
  gradient: colorGradientFormat
};
var MAX_LOGGED_FORMATTER_ERRORS = 10;
var newFormatterErrorHandler = (maxErrors, handlerFunc) => {
  let errorCount = 0;
  return (msg) => {
    if (errorCount < maxErrors) {
      handlerFunc(msg);
    }
    errorCount += 1;
  };
};
var getFormatter = (data, formatCfg = {}) => {
  if (formatCfg.type) {
    if (formatters[formatCfg.type]) {
      return (value) => formatters[formatCfg.type](
        value,
        formatCfg,
        data,
        // eslint-disable-next-line no-console
        newFormatterErrorHandler(MAX_LOGGED_FORMATTER_ERRORS, (msg) => console.warn(msg))
      );
    }
    return (value) => value;
  }
  const { ranges, values } = formatCfg;
  if (values) {
    if (ranges) {
      return (value) => rangeFormat(value, formatCfg);
    }
    if (formatCfg.categories) {
      return (value) => categoryFormat(value, formatCfg);
    }
  }
  console.warn("Could not find a formatter. Falling back to identity fn");
  return (value) => value;
};
var getDataForDataSourceType = (data, dataSourceType) => {
  if (!dataSourceType || !data[dataSourceType] || !data[dataSourceType].data) {
    return {
      fields: [],
      columns: []
    };
  }
  return data[dataSourceType].data;
};
var parseFieldRangeReference = (fieldIndexRangeStr) => {
  if (!fieldIndexRangeStr || fieldIndexRangeStr.indexOf(":") === -1) {
    return {
      isFieldIndexRange: false
    };
  }
  const [fromFieldIndexStr, toFieldIndexStr] = fieldIndexRangeStr.split(":");
  return {
    isFieldIndexRange: true,
    fromFieldIndex: Number.isNaN(Number(fromFieldIndexStr)) || !fromFieldIndexStr ? 0 : Number(fromFieldIndexStr),
    toFieldIndex: Number.isNaN(Number(toFieldIndexStr)) || !toFieldIndexStr ? -1 : Number(toFieldIndexStr)
  };
};
var parseIndexBasedFieldReference = (fieldReferenceStr) => {
  const indices = fieldReferenceStr.replace(/^[A-Za-z0-9]+/, "").replace(/\[/g, "").replace(/\]/g, ",").split(",");
  const dataSourceName = fieldReferenceStr.match(/^[A-Za-z0-9]+/)[0];
  const fieldRange = parseFieldRangeReference(indices[0]);
  return __spreadValues({
    dataSourceName,
    fieldIndex: Number.isNaN(Number(indices[0])) || !indices[0] ? null : Number(indices[0]),
    columnIndex: Number.isNaN(Number(indices[1])) || !indices[1] ? null : Number(indices[1])
  }, fieldRange);
};
var parseNameBasedFieldReference = (fieldReferenceStr) => {
  const dataSourceName = fieldReferenceStr.match(/^[A-Za-z0-9]+/)[0];
  const fieldNameStr = fieldReferenceStr.split(".")[1];
  const splitedStr = fieldNameStr.split("[");
  const fieldName = splitedStr[0];
  const columnIndex = splitedStr[1] ? Number(splitedStr[1].replace("]", "")) : null;
  return { dataSourceName, fieldName, columnIndex };
};
var getDataForIndexBasedFieldReference = (data, fieldReferenceStr) => {
  const { fields, columns } = data;
  const { dataSourceName, isFieldIndexRange, fromFieldIndex, toFieldIndex, fieldIndex, columnIndex } = parseIndexBasedFieldReference(fieldReferenceStr);
  if (isFieldIndexRange) {
    const dataForRange = [];
    if (fromFieldIndex > -1) {
      const endIndex = toFieldIndex > -1 ? Math.min(fields.length - 1, toFieldIndex) : fields.length + toFieldIndex;
      for (let i = fromFieldIndex; i <= endIndex; i += 1) {
        dataForRange.push(
          getDataForIndexBasedFieldReference(data, `${dataSourceName}[${i}][${columnIndex}]`)
        );
      }
      return dataForRange;
    }
  }
  if ((0, lodash_exports.isNumber)(fieldIndex)) {
    const isNegative = fieldIndex < 0;
    const absoluteIndex = Math.abs(fieldIndex);
    if (isNegative && absoluteIndex > fields.length || !isNegative && fieldIndex > fields.length - 1) {
      return {};
    }
    const correctedFieldIndex = isNegative ? fields.length - absoluteIndex : fieldIndex;
    const fieldName = typeof fields[correctedFieldIndex] === "object" ? fields[correctedFieldIndex].name : fields[correctedFieldIndex];
    let fieldData;
    if ((0, lodash_exports.isNumber)(columnIndex)) {
      const isNegativeColumnIndex = columnIndex < 0;
      if (isNegativeColumnIndex && columnIndex < -columns[correctedFieldIndex].length || columnIndex >= columns[correctedFieldIndex].length) {
        return {};
      }
      const correctColumnIndex = isNegativeColumnIndex ? columns[correctedFieldIndex].length + columnIndex : columnIndex;
      fieldData = columns[correctedFieldIndex].map(
        () => columns[correctedFieldIndex][correctColumnIndex]
      );
    } else {
      fieldData = columns[correctedFieldIndex];
    }
    return {
      fieldName,
      data: fieldData
    };
  }
  return {};
};
var getDataForNameBasedFieldReference = (data, fieldReferenceStr) => {
  const { fields, columns } = data;
  const { fieldName, columnIndex } = parseNameBasedFieldReference(fieldReferenceStr);
  if (fieldName) {
    const fieldIndex = (0, lodash_exports.findIndex)(
      fields,
      (field) => typeof field === "object" ? field.name === fieldName : field === fieldName
    );
    if (fieldIndex > -1) {
      let fieldData;
      if ((0, lodash_exports.isNumber)(columnIndex)) {
        const isNegativeColumnIndex = columnIndex < 0;
        if (isNegativeColumnIndex && columnIndex < -columns[fieldIndex].length || columnIndex >= columns[fieldIndex].length) {
          return {};
        }
        const correctColumnIndex = isNegativeColumnIndex ? columns[fieldIndex].length + columnIndex : columnIndex;
        fieldData = columns[fieldIndex].map(() => columns[fieldIndex][correctColumnIndex]);
      } else {
        fieldData = columns[fieldIndex];
      }
      return {
        fieldName,
        data: fieldData
      };
    }
    console.warn(`field '${fieldName}' not available.`);
    return {};
  }
  return {};
};
var getDataForFieldReference = (dataSources, fieldReference) => {
  let fieldReferenceStr = fieldReference;
  let formatValue;
  if (Array.isArray(fieldReference) && !fieldReference.isDefault) {
    return fieldReference.map((ref) => getDataForFieldReference(dataSources, ref));
  }
  if (fieldReference.isDefault && Array.isArray(fieldReference.field)) {
    for (let i = 0; i < fieldReference.field.length; i += 1) {
      fieldReferenceStr = fieldReference.field[i];
      const dataFromDefault = getDataForFieldReference(dataSources, fieldReferenceStr);
      if (Array.isArray(dataFromDefault.data)) {
        const type = inferDataTypeFromSample(drawSample(dataFromDefault.data));
        if (fieldReference.type.indexOf(type) > -1) {
          return dataFromDefault;
        }
      }
    }
  }
  if (typeof fieldReference === "object") {
    const { field } = fieldReference;
    if (field && !Array.isArray(field)) {
      fieldReferenceStr = field;
    }
  }
  const indexBasedRegx = /^[A-Za-z0-9_]+\[.*\].*$/;
  const nameBasedRegx = /^[A-Za-z0-9_]+\..*$/;
  const isIndexBasedReference = indexBasedRegx.test(fieldReferenceStr);
  const isNameBasedReference = nameBasedRegx.test(fieldReferenceStr);
  if (!isIndexBasedReference && !isNameBasedReference) {
    return {};
  }
  const dataSourceType = fieldReferenceStr.match(/^(.*?)(\.|\[)/)[1];
  const data = getDataForDataSourceType(dataSources, dataSourceType);
  let fieldData;
  if (isIndexBasedReference) {
    fieldData = getDataForIndexBasedFieldReference(data, fieldReferenceStr);
  } else {
    fieldData = getDataForNameBasedFieldReference(data, fieldReferenceStr);
  }
  if (typeof fieldReference === "object") {
    const { format } = fieldReference;
    if (format) {
      formatValue = getFormatter(fieldData.data, format);
    }
  }
  if (formatValue && !(0, lodash_exports.isEmpty)(fieldData)) {
    return {
      fieldName: fieldData.fieldName,
      data: fieldData.data.map(formatValue)
    };
  }
  return fieldData;
};
var mergeEncoding = (defaultEncoding, userDefinedEncoding = {}) => {
  const mergedEncoding = __spreadValues({}, userDefinedEncoding);
  Object.keys(defaultEncoding).forEach((key) => {
    if ((0, lodash_exports.isEmpty)(userDefinedEncoding[key]) && defaultEncoding[key].isRequired && defaultEncoding[key].default) {
      mergedEncoding[key] = typeof defaultEncoding[key].default === "object" && !Array.isArray(defaultEncoding[key].default) ? __spreadProps(__spreadValues({}, defaultEncoding[key].default), {
        isDefault: true,
        type: defaultEncoding[key].type
      }) : {
        field: defaultEncoding[key].default,
        isDefault: true,
        type: defaultEncoding[key].type
      };
    }
  });
  return mergedEncoding;
};
var parse = (dataSources, encoding = {}) => {
  const parsedOutput = {
    _meta: {
      fieldNames: {},
      types: {}
    }
  };
  Object.keys(encoding).forEach((key) => {
    let fieldReference = (0, lodash_exports.clone)(encoding[key]);
    if (typeof fieldReference === "object" && fieldReference.field && fieldReference.field.indexOf("encoding") === 0) {
      const replacedKey = fieldReference.field.split(".")[1];
      if (!encoding[replacedKey]) {
        console.warn(`${key} field cannot refer to 'encoding.${replacedKey}'.`);
      }
      const field = typeof encoding[replacedKey] === "object" ? encoding[replacedKey].field : encoding[replacedKey];
      fieldReference = __spreadProps(__spreadValues({}, fieldReference), {
        field
      });
    }
    const dataForFieldReference = getDataForFieldReference(dataSources, fieldReference);
    if (Array.isArray(dataForFieldReference)) {
      parsedOutput[key] = dataForFieldReference.map((entry) => entry.data);
      parsedOutput._meta.fieldNames[key] = dataForFieldReference.map((entry) => entry.fieldName);
      parsedOutput._meta.types[key] = dataForFieldReference.map(
        (entry) => inferDataTypeFromSample(drawSample(entry.data))
      );
    } else {
      const { fieldName, data } = dataForFieldReference;
      if (fieldName) {
        parsedOutput[key] = data;
        parsedOutput._meta.fieldNames[key] = fieldName;
        parsedOutput._meta.types[key] = inferDataTypeFromSample(drawSample(data));
      }
    }
  });
  return parsedOutput;
};
//# sourceMappingURL=parserUtils.js.map
