text: /*
   * @reference: https://github.com/Planeshifter/kernel-smooth/blob/master/lib/index.js
   */
  var assign = require('@antv/util/lib/mix');
  var isArray = require('@antv/util/lib/type/isArray');
  var isFunction = require('@antv/util/lib/type/isFunction');
  var isNumber = require('@antv/util/lib/type/isNumber');
  var isString = require('@antv/util/lib/type/isString');
  var keys = require('@antv/util/lib/object/keys');
  // const regression = require('regression');
  var getSeriesValues = require('../../util/get-series-values');
  // const enclideanDistance = require('../../util/euclidean-distance');
  var kernel = require('../../util/kernel');
  
  var _require = require('../../data-set'),
      registerTransform = _require.registerTransform;
  
  var _require2 = require('../../util/option-parser'),
      getFields = _require2.getFields;
  
  var _require3 = require('../../util/bandwidth'),
      silverman = _require3.silverman;
  
  var DEFAULT_OPTIONS = {
    as: ['x', 'y', 'z'],
    // fields: [ 'x', 'y' ], // required, one or two fields
    method: 'gaussian', // kernel method: should be one of keys(kernel)
    extent: [], // extent to execute regression function, default: [ [ min(x), max(x) ], [ min(y), max(y) ] ]
    bandwidth: [] // bandWidth to execute kernel function
  };
  
  var KERNEL_METHODS = keys(kernel);
  
  function transform(dv, options) {
    options = assign({}, DEFAULT_OPTIONS, options);
    var fields = getFields(options);
    if (!isArray(fields) || fields.length !== 2) {
      throw new TypeError('invalid fields: must be an array of 2 strings!');
    }
    var _options$as = options.as,
        asX = _options$as[0],
        asY = _options$as[1],
        asZ = _options$as[2];
  
    if (!isString(asX) || !isString(asY) || !isString(asZ)) {
      throw new TypeError('invalid as: must be an array of 3 strings!');
    }
    var method = options.method;
    if (isString(method)) {
      if (KERNEL_METHODS.indexOf(method) === -1) {
        throw new TypeError('invalid method: ' + method + '. Must be one of ' + KERNEL_METHODS.join(', '));
      }
      method = kernel[method];
    }
    if (!isFunction(method)) {
      throw new TypeError('invalid method: kernel method must be a function!');
    }
  
    var xField = fields[0],
        yField = fields[1];
    var _options$extent = options.extent,
        extentX = _options$extent[0],
        extentY = _options$extent[1];
  
    if (!isArray(extentX) || !isArray(extentY)) {
      extentX = dv.range(xField);
      extentY = dv.range(yField);
    }
    var _options$bandwidth = options.bandwidth,
        bwX = _options$bandwidth[0],
        bwY = _options$bandwidth[1];
  
    if (!isNumber(bwX) || bwX <= 0 || !isNumber(bwY) || bwY <= 0) {
      bwX = silverman(dv.getColumn(xField));
      bwY = silverman(dv.getColumn(yField));
    }
    var seriesValuesX = getSeriesValues(extentX, bwX);
    var seriesValuesY = getSeriesValues(extentY, bwY);
    var count = dv.rows.length;
    var result = [];
  
    for (var i = 0; i < seriesValuesX.length; i++) {
      for (var j = 0; j < seriesValuesY.length; j++) {
        var sum = 0;
        var x = seriesValuesX[i];
        var y = seriesValuesY[j];
        for (var k = 0; k < count; k++) {
          sum += method((x - dv.rows[k][xField]) / bwX) * method((y - dv.rows[k][yField]) / bwY);
        }
        var z = 1 / (count * bwX * bwY) * sum;
        var row = {};
        row[asX] = x;
        row[asY] = y;
        row[asZ] = z;
        result.push(row);
      }
    }
  
    dv.rows = result;
  }
  
  registerTransform('kernel-smooth.density', transform);
  registerTransform('kernel.density', transform);
  
  module.exports = {
    KERNEL_METHODS: KERNEL_METHODS
  };