From aecbfe97f4be63a418b0efe6b9cd18497e341b09 Mon Sep 17 00:00:00 2001 From: Kirill Baldin Date: Wed, 15 Jan 2025 16:08:24 +0400 Subject: [PATCH 01/10] convert js to typescript --- .babelrc | 4 +- dist/d3-regression.cjs.js | 1439 ++++++++---------- dist/d3-regression.esm.js | 1439 ++++++++---------- dist/d3-regression.js | 1439 ++++++++---------- dist/d3-regression.min.js | 1 - dist/d3-regression.zip | Bin 23007 -> 0 bytes dist/index.d.ts | 7 + dist/src/exponential.d.ts | 19 + dist/src/linear.d.ts | 19 + dist/src/loess.d.ts | 13 + dist/src/logarithmic.d.ts | 22 + dist/src/polynomial.d.ts | 20 + dist/src/power.d.ts | 20 + dist/src/quadratic.d.ts | 21 + dist/src/types.d.ts | 4 + dist/src/utils/determination.d.ts | 6 + dist/src/utils/geometry.d.ts | 9 + dist/src/utils/interpose.d.ts | 6 + dist/src/utils/median.d.ts | 4 + dist/src/utils/ols.d.ts | 6 + dist/src/utils/points.d.ts | 11 + index.js => index.ts | 0 package-lock.json | 2197 ++++++++++++++++++---------- package.json | 6 +- rollup.config.js | 32 +- src/exponential.js | 62 - src/exponential.ts | 94 ++ src/linear.js | 57 - src/linear.ts | 87 ++ src/loess.js | 136 -- src/loess.ts | 161 ++ src/logarithmic.js | 65 - src/logarithmic.ts | 100 ++ src/polynomial.js | 169 --- src/polynomial.ts | 218 +++ src/power.js | 63 - src/power.ts | 93 ++ src/quadratic.js | 80 - src/quadratic.ts | 115 ++ src/types.ts | 5 + src/utils/determination.js | 18 - src/utils/determination.ts | 26 + src/utils/geometry.js | 9 - src/utils/geometry.ts | 21 + src/utils/interpose.js | 40 - src/utils/interpose.ts | 49 + src/utils/{median.js => median.ts} | 8 +- src/utils/ols.js | 10 - src/utils/ols.ts | 18 + src/utils/{points.js => points.ts} | 54 +- test/loess-test.js | 2 +- tsconfig.json | 20 + 52 files changed, 4551 insertions(+), 3973 deletions(-) delete mode 100644 dist/d3-regression.min.js delete mode 100644 dist/d3-regression.zip create mode 100644 dist/index.d.ts create mode 100644 dist/src/exponential.d.ts create mode 100644 dist/src/linear.d.ts create mode 100644 dist/src/loess.d.ts create mode 100644 dist/src/logarithmic.d.ts create mode 100644 dist/src/polynomial.d.ts create mode 100644 dist/src/power.d.ts create mode 100644 dist/src/quadratic.d.ts create mode 100644 dist/src/types.d.ts create mode 100644 dist/src/utils/determination.d.ts create mode 100644 dist/src/utils/geometry.d.ts create mode 100644 dist/src/utils/interpose.d.ts create mode 100644 dist/src/utils/median.d.ts create mode 100644 dist/src/utils/ols.d.ts create mode 100644 dist/src/utils/points.d.ts rename index.js => index.ts (100%) delete mode 100644 src/exponential.js create mode 100644 src/exponential.ts delete mode 100644 src/linear.js create mode 100644 src/linear.ts delete mode 100644 src/loess.js create mode 100644 src/loess.ts delete mode 100644 src/logarithmic.js create mode 100644 src/logarithmic.ts delete mode 100644 src/polynomial.js create mode 100644 src/polynomial.ts delete mode 100644 src/power.js create mode 100644 src/power.ts delete mode 100644 src/quadratic.js create mode 100644 src/quadratic.ts create mode 100644 src/types.ts delete mode 100644 src/utils/determination.js create mode 100644 src/utils/determination.ts delete mode 100644 src/utils/geometry.js create mode 100644 src/utils/geometry.ts delete mode 100644 src/utils/interpose.js create mode 100644 src/utils/interpose.ts rename src/utils/{median.js => median.ts} (52%) delete mode 100644 src/utils/ols.js create mode 100644 src/utils/ols.ts rename src/utils/{points.js => points.ts} (50%) create mode 100644 tsconfig.json diff --git a/.babelrc b/.babelrc index 60cad8d..52b84f7 100644 --- a/.babelrc +++ b/.babelrc @@ -1,5 +1,7 @@ { + "presets": [ + ["@babel/env", {"modules": false}] ] -} \ No newline at end of file +} diff --git a/dist/d3-regression.cjs.js b/dist/d3-regression.cjs.js index 8271f81..01b59fe 100644 --- a/dist/d3-regression.cjs.js +++ b/dist/d3-regression.cjs.js @@ -1,873 +1,676 @@ -// https://github.com/HarryStevens/d3-regression#readme Version 1.3.10. Copyright 2022 Harry Stevens. +// https://github.com/HarryStevens/d3-regression#readme Version 1.3.10. Copyright 2025 Harry Stevens. 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); -function _slicedToArray(arr, i) { - return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); -} - -function _arrayWithHoles(arr) { - if (Array.isArray(arr)) return arr; -} - -function _iterableToArrayLimit(arr, i) { - var _arr = []; - var _n = true; - var _d = false; - var _e = undefined; - - try { - for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { - _arr.push(_s.value); - - if (i && _arr.length === i) break; - } - } catch (err) { - _d = true; - _e = err; - } finally { - try { - if (!_n && _i["return"] != null) _i["return"](); - } finally { - if (_d) throw _e; - } - } - - return _arr; -} - -function _nonIterableRest() { - throw new TypeError("Invalid attempt to destructure non-iterable instance"); -} - -// Adapted from vega-statistics by Jeffrey Heer -// License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE -// Source: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/packages/vega-statistics/src/regression/points.js +/** + * Adapted from vega-statistics by Jeffrey Heer + * License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE + * Source: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/packages/vega-statistics/src/regression/points.js + */ function points(data, x, y, sort) { - data = data.filter(function (d, i) { - var u = x(d, i), - v = y(d, i); - return u != null && isFinite(u) && v != null && isFinite(v); - }); - - if (sort) { - data.sort(function (a, b) { - return x(a) - x(b); + data = data.filter(function (d, i) { + var u = x(d, i), v = y(d, i); + return u != null && isFinite(u) && v != null && isFinite(v); }); - } - - var n = data.length, - X = new Float64Array(n), - Y = new Float64Array(n); // extract values, calculate means - - var ux = 0, - uy = 0, - xv, - yv, - d; - - for (var i = 0; i < n;) { - d = data[i]; - X[i] = xv = +x(d, i, data); - Y[i] = yv = +y(d, i, data); - ++i; - ux += (xv - ux) / i; - uy += (yv - uy) / i; - } // mean center the data - - - for (var _i = 0; _i < n; ++_i) { - X[_i] -= ux; - Y[_i] -= uy; - } - - return [X, Y, ux, uy]; + if (sort) { + data.sort(function (a, b) { return x(a) - x(b); }); + } + var n = data.length, X = new Float64Array(n), Y = new Float64Array(n); + // extract values, calculate means + var ux = 0, uy = 0, xv, yv, d; + for (var i = 0; i < n;) { + d = data[i]; + X[i] = xv = +x(d, i, data); + Y[i] = yv = +y(d, i, data); + ++i; + ux += (xv - ux) / i; + uy += (yv - uy) / i; + } + // mean center the data + for (var i = 0; i < n; ++i) { + X[i] -= ux; + Y[i] -= uy; + } + return [X, Y, ux, uy]; } +/** + * Iterates over valid data points, invoking a callback for each. + */ function visitPoints(data, x, y, cb) { - var iterations = 0; - - for (var i = 0, n = data.length; i < n; i++) { - var d = data[i], - dx = +x(d, i, data), - dy = +y(d, i, data); - - if (dx != null && isFinite(dx) && dy != null && isFinite(dy)) { - cb(dx, dy, iterations++); + var iterations = 0; + for (var i = 0; i < data.length; i++) { + var d = data[i]; + var dx = +x(d, i, data); + var dy = +y(d, i, data); + if (dx != null && isFinite(dx) && dy != null && isFinite(dy)) { + cb(dx, dy, iterations++); + } } - } } -// return the coefficient of determination, or R squared. - +/** + * Given a dataset, x- and y-accessors, the mean center of the y-values (uY), + * and a prediction function, return the coefficient of determination, R^2. + */ function determination(data, x, y, uY, predict) { - var SSE = 0, - SST = 0; - visitPoints(data, x, y, function (dx, dy) { - var sse = dy - predict(dx), - sst = dy - uY; - SSE += sse * sse; - SST += sst * sst; - }); - return 1 - SSE / SST; + var SSE = 0, // Sum of Squared Errors + SST = 0; // Total Sum of Squares + visitPoints(data, x, y, function (dx, dy) { + var sse = dy - predict(dx); + var sst = dy - uY; + SSE += sse * sse; + SST += sst * sst; + }); + return 1 - SSE / SST; } -// Returns the angle of a line in degrees. +/** + * Returns the angle of a line in degrees. + */ function angle(line) { - return Math.atan2(line[1][1] - line[0][1], line[1][0] - line[0][0]) * 180 / Math.PI; -} // Returns the midpoint of a line. - + return (Math.atan2(line[1][1] - line[0][1], line[1][0] - line[0][0]) * + (180 / Math.PI)); +} +/** + * Returns the midpoint of a line. + */ function midpoint(line) { - return [(line[0][0] + line[1][0]) / 2, (line[0][1] + line[1][1]) / 2]; + return [ + (line[0][0] + line[1][0]) / 2, + (line[0][1] + line[1][1]) / 2 + ]; } -// returns a smooth line. - +/** + * Given a start point (xmin), an end point (xmax), + * and a prediction function, returns a smooth line. + */ function interpose(xmin, xmax, predict) { - var l = Math.log(xmax - xmin) * Math.LOG10E + 1 | 0; - var precision = 1 * Math.pow(10, -l / 2 - 1), - maxIter = 1e4; - var points = [px(xmin), px(xmax)], - iter = 0; - - while (find(points) && iter < maxIter) { - } - - return points; - - function px(x) { - return [x, predict(x)]; - } - - function find(points) { - iter++; - var n = points.length; - var found = false; - - for (var i = 0; i < n - 1; i++) { - var p0 = points[i], - p1 = points[i + 1], - m = midpoint([p0, p1]), - mp = px(m[0]), - a0 = angle([p0, m]), - a1 = angle([p0, mp]), - a = Math.abs(a0 - a1); - - if (a > precision) { - points.splice(i + 1, 0, mp); - found = true; - } + var l = (Math.log(xmax - xmin) * Math.LOG10E + 1) | 0; + var precision = Math.pow(10, -l / 2 - 1); + var maxIter = 1e4; + var points = [px(xmin), px(xmax)]; + var iter = 0; + while (find(points) && iter < maxIter) + ; + return points; + function px(x) { + return [x, predict(x)]; + } + function find(points) { + iter++; + var n = points.length; + var found = false; + for (var i = 0; i < n - 1; i++) { + var p0 = points[i]; + var p1 = points[i + 1]; + var m = midpoint([p0, p1]); + var mp = px(m[0]); + var a0 = angle([p0, m]); + var a1 = angle([p0, mp]); + var a = Math.abs(a0 - a1); + if (a > precision) { + points.splice(i + 1, 0, mp); + found = true; + } + } + return found; } - - return found; - } } -// Ordinary Least Squares from vega-statistics by Jeffrey Heer -// License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE -// Source: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/packages/vega-statistics/src/regression/ols.js +/** + * Ordinary Least Squares from vega-statistics by Jeffrey Heer + * License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE + * Source: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/packages/vega-statistics/src/regression/ols.js + */ function ols(uX, uY, uXY, uX2) { - var delta = uX2 - uX * uX, - slope = Math.abs(delta) < 1e-24 ? 0 : (uXY - uX * uY) / delta, - intercept = uY - slope * uX; - return [intercept, slope]; + var delta = uX2 - uX * uX, slope = Math.abs(delta) < 1e-24 ? 0 : (uXY - uX * uY) / delta, intercept = uY - slope * uX; + return [intercept, slope]; } -function exponential () { - var x = function x(d) { - return d[0]; - }, - y = function y(d) { - return d[1]; - }, - domain; - - function exponential(data) { - var n = 0, - Y = 0, - YL = 0, - XY = 0, - XYL = 0, - X2Y = 0, - xmin = domain ? +domain[0] : Infinity, - xmax = domain ? +domain[1] : -Infinity; - visitPoints(data, x, y, function (dx, dy) { - var ly = Math.log(dy), - xy = dx * dy; - ++n; - Y += (dy - Y) / n; - XY += (xy - XY) / n; - X2Y += (dx * xy - X2Y) / n; - YL += (dy * ly - YL) / n; - XYL += (xy * ly - XYL) / n; - - if (!domain) { - if (dx < xmin) xmin = dx; - if (dx > xmax) xmax = dx; - } - }); - - var _ols = ols(XY / Y, YL / Y, XYL / Y, X2Y / Y), - _ols2 = _slicedToArray(_ols, 2), - a = _ols2[0], - b = _ols2[1]; - - a = Math.exp(a); - - var fn = function fn(x) { - return a * Math.exp(b * x); - }, - out = interpose(xmin, xmax, fn); - - out.a = a; - out.b = b; - out.predict = fn; - out.rSquared = determination(data, x, y, Y, fn); - return out; - } - - exponential.domain = function (arr) { - return arguments.length ? (domain = arr, exponential) : domain; - }; - - exponential.x = function (fn) { - return arguments.length ? (x = fn, exponential) : x; - }; - - exponential.y = function (fn) { - return arguments.length ? (y = fn, exponential) : y; - }; - - return exponential; +function exponential() { + var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, domain; + var exponentialRegression = function (data) { + var n = 0, Y = 0, YL = 0, XY = 0, XYL = 0, X2Y = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; + visitPoints(data, x, y, function (dx, dy) { + var ly = Math.log(dy), xy = dx * dy; + ++n; + Y += (dy - Y) / n; + XY += (xy - XY) / n; + X2Y += (dx * xy - X2Y) / n; + YL += (dy * ly - YL) / n; + XYL += (xy * ly - XYL) / n; + if (!domain) { + if (dx < xmin) + xmin = dx; + if (dx > xmax) + xmax = dx; + } + }); + var _a = ols(XY / Y, YL / Y, XYL / Y, X2Y / Y), a = _a[0], b = _a[1]; + a = Math.exp(a); + var fn = function (xx) { return a * Math.exp(b * xx); }; + var out = interpose(xmin, xmax, fn); + out.a = a; + out.b = b; + out.predict = fn; + out.rSquared = determination(data, x, y, Y, fn); + return out; + }; + exponentialRegression.domain = function (arr) { + if (!arguments.length) + return domain; + domain = arr; + return exponentialRegression; + }; + exponentialRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return exponentialRegression; + }; + exponentialRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return exponentialRegression; + }; + return exponentialRegression; } -function linear () { - var x = function x(d) { - return d[0]; - }, - y = function y(d) { - return d[1]; - }, - domain; - - function linear(data) { - var n = 0, - X = 0, - // sum of x - Y = 0, - // sum of y - XY = 0, - // sum of x * y - X2 = 0, - // sum of x * x - xmin = domain ? +domain[0] : Infinity, - xmax = domain ? +domain[1] : -Infinity; - visitPoints(data, x, y, function (dx, dy) { - ++n; - X += (dx - X) / n; - Y += (dy - Y) / n; - XY += (dx * dy - XY) / n; - X2 += (dx * dx - X2) / n; - - if (!domain) { - if (dx < xmin) xmin = dx; - if (dx > xmax) xmax = dx; - } - }); - - var _ols = ols(X, Y, XY, X2), - _ols2 = _slicedToArray(_ols, 2), - intercept = _ols2[0], - slope = _ols2[1], - fn = function fn(x) { - return slope * x + intercept; - }, - out = [[xmin, fn(xmin)], [xmax, fn(xmax)]]; - - out.a = slope; - out.b = intercept; - out.predict = fn; - out.rSquared = determination(data, x, y, Y, fn); - return out; - } - - linear.domain = function (arr) { - return arguments.length ? (domain = arr, linear) : domain; - }; - - linear.x = function (fn) { - return arguments.length ? (x = fn, linear) : x; - }; - - linear.y = function (fn) { - return arguments.length ? (y = fn, linear) : y; - }; - - return linear; +function linear() { + var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, domain; + var linearRegression = function (data) { + var n = 0, X = 0, // sum of x + Y = 0, // sum of y + XY = 0, // sum of x*y + X2 = 0, // sum of x*x + xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; + visitPoints(data, x, y, function (dx, dy) { + ++n; + X += (dx - X) / n; + Y += (dy - Y) / n; + XY += (dx * dy - XY) / n; + X2 += (dx * dx - X2) / n; + if (!domain) { + if (dx < xmin) + xmin = dx; + if (dx > xmax) + xmax = dx; + } + }); + var _a = ols(X, Y, XY, X2), intercept = _a[0], slope = _a[1]; + var fn = function (xx) { return slope * xx + intercept; }; + var out = [[xmin, fn(xmin)], [xmax, fn(xmax)]]; + out.a = slope; + out.b = intercept; + out.predict = fn; + out.rSquared = determination(data, x, y, Y, fn); + return out; + }; + linearRegression.domain = function (arr) { + if (!arguments.length) + return domain; + domain = arr; + return linearRegression; + }; + linearRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return linearRegression; + }; + linearRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return linearRegression; + }; + return linearRegression; } -// Returns the medium value of an array of numbers. +/** + * Returns the median value of an array of numbers. + */ function median(arr) { - arr.sort(function (a, b) { - return a - b; - }); - var i = arr.length / 2; - return i % 1 === 0 ? (arr[i - 1] + arr[i]) / 2 : arr[Math.floor(i)]; + arr.sort(function (a, b) { return a - b; }); + var i = arr.length / 2; + return i % 1 === 0 ? (arr[i - 1] + arr[i]) / 2 : arr[Math.floor(i)]; } -var maxiters = 2, - epsilon = 1e-12; -function loess () { - var x = function x(d) { - return d[0]; - }, - y = function y(d) { - return d[1]; - }, - bandwidth = .3; - - function loess(data) { - var _points = points(data, x, y, true), - _points2 = _slicedToArray(_points, 4), - xv = _points2[0], - yv = _points2[1], - ux = _points2[2], - uy = _points2[3], - n = xv.length, - bw = Math.max(2, ~~(bandwidth * n)), - yhat = new Float64Array(n), - residuals = new Float64Array(n), - robustWeights = new Float64Array(n).fill(1); - - for (var iter = -1; ++iter <= maxiters;) { - var interval = [0, bw - 1]; - - for (var i = 0; i < n; ++i) { - var dx = xv[i], - i0 = interval[0], - i1 = interval[1], - edge = dx - xv[i0] > xv[i1] - dx ? i0 : i1; - var W = 0, - X = 0, - Y = 0, - XY = 0, - X2 = 0, - denom = 1 / Math.abs(xv[edge] - dx || 1); // Avoid singularity - - for (var k = i0; k <= i1; ++k) { - var xk = xv[k], - yk = yv[k], - w = tricube(Math.abs(dx - xk) * denom) * robustWeights[k], - xkw = xk * w; - W += w; - X += xkw; - Y += yk * w; - XY += yk * xkw; - X2 += xk * xkw; - } // Linear regression fit - - - var _ols = ols(X / W, Y / W, XY / W, X2 / W), - _ols2 = _slicedToArray(_ols, 2), - a = _ols2[0], - b = _ols2[1]; - - yhat[i] = a + b * dx; - residuals[i] = Math.abs(yv[i] - yhat[i]); - updateInterval(xv, i + 1, interval); - } - - if (iter === maxiters) { - break; - } - - var medianResidual = median(residuals); - if (Math.abs(medianResidual) < epsilon) break; - - for (var _i = 0, arg, _w; _i < n; ++_i) { - arg = residuals[_i] / (6 * medianResidual); // Default to epsilon (rather than zero) for large deviations - // Keeping weights tiny but non-zero prevents singularites - - robustWeights[_i] = arg >= 1 ? epsilon : (_w = 1 - arg * arg) * _w; - } - } - - return output(xv, yhat, ux, uy); - } - - loess.bandwidth = function (bw) { - return arguments.length ? (bandwidth = bw, loess) : bandwidth; - }; - - loess.x = function (fn) { - return arguments.length ? (x = fn, loess) : x; - }; - - loess.y = function (fn) { - return arguments.length ? (y = fn, loess) : y; - }; - - return loess; -} // Weighting kernel for local regression - +// Adapted from science.js by Jason Davies +var maxiters = 2, epsilon = 1e-12; +function loess() { + var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, bandwidth = .3; + var loessRegression = function loessRegression(data) { + var _a = points(data, x, y, true), xv = _a[0], yv = _a[1], ux = _a[2], uy = _a[3]; + var n = xv.length; + var bw = Math.max(2, ~~(bandwidth * n)); // # of nearest neighbors + var yhat = new Float64Array(n); + var residuals = new Float64Array(n); + var robustWeights = new Float64Array(n).fill(1); + for (var iter = -1; ++iter <= maxiters;) { + var interval = [0, bw - 1]; + for (var i = 0; i < n; ++i) { + var dx = xv[i]; + var i0 = interval[0]; + var i1 = interval[1]; + var edge = (dx - xv[i0]) > (xv[i1] - dx) ? i0 : i1; + var W = 0, X = 0, Y = 0, XY = 0, X2 = 0; + var denom = 1 / Math.abs(xv[edge] - dx || 1); + for (var k = i0; k <= i1; ++k) { + var xk = xv[k]; + var yk = yv[k]; + var w = tricube(Math.abs(dx - xk) * denom) * robustWeights[k]; + var xkw = xk * w; + W += w; + X += xkw; + Y += yk * w; + XY += yk * xkw; + X2 += xk * xkw; + } + // Linear regression fit + var _b = ols(X / W, Y / W, XY / W, X2 / W), a = _b[0], b = _b[1]; + yhat[i] = a + b * dx; + residuals[i] = Math.abs(yv[i] - yhat[i]); + updateInterval(xv, i + 1, interval); + } + if (iter === maxiters) { + break; + } + var medianResidual = median(residuals); + if (Math.abs(medianResidual) < epsilon) + break; + for (var i = 0, arg = void 0, w = void 0; i < n; ++i) { + arg = residuals[i] / (6 * medianResidual); + // Default to epsilon (rather than zero) for large deviations + // Keeping weights tiny but non-zero prevents singularites + robustWeights[i] = (arg >= 1) ? epsilon : ((w = 1 - arg * arg) * w); + } + } + return output(xv, yhat, ux, uy); + }; + loessRegression.bandwidth = function (bw) { + if (!arguments.length) + return bandwidth; + bandwidth = bw; + return loessRegression; + }; + loessRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return loessRegression; + }; + loessRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return loessRegression; + }; + return loessRegression; +} +// Weighting kernel for local regression function tricube(x) { - return (x = 1 - x * x * x) * x * x; -} // Advance sliding window interval of nearest neighbors - - + return (x = 1 - x * x * x) * x * x; +} +// Advance sliding window interval of nearest neighbors function updateInterval(xv, i, interval) { - var val = xv[i], - left = interval[0], - right = interval[1] + 1; - if (right >= xv.length) return; // Step right if distance to new right edge is <= distance to old left edge - // Step when distance is equal to ensure movement over duplicate x values - - while (i > left && xv[right] - val <= val - xv[left]) { - interval[0] = ++left; - interval[1] = right; - ++right; - } -} // Generate smoothed output points + var val = xv[i], left = interval[0], right = interval[1] + 1; + if (right >= xv.length) + return; + // Step right if distance to new right edge is <= distance to old left edge + // Step when distance is equal to ensure movement over duplicate x values + while (i > left && (xv[right] - val) <= (val - xv[left])) { + interval[0] = ++left; + interval[1] = right; + ++right; + } +} +// Generate smoothed output points // Average points with repeated x values - - function output(xv, yhat, ux, uy) { - var n = xv.length, - out = []; - var i = 0, - cnt = 0, - prev = [], - v; - - for (; i < n; ++i) { - v = xv[i] + ux; - - if (prev[0] === v) { - // Average output values via online update - prev[1] += (yhat[i] - prev[1]) / ++cnt; - } else { - // Add new output point - cnt = 0; - prev[1] += uy; - prev = [v, yhat[i]]; - out.push(prev); + var n = xv.length, out = []; + var i = 0, cnt = 0, prev = [], v; + for (; i < n; ++i) { + v = xv[i] + ux; + if (prev[0] === v) { + // Average output values via online update + prev[1] += (yhat[i] - prev[1]) / (++cnt); + } + else { + // Add new output point + cnt = 0; + prev[1] += uy; + prev = [v, yhat[i]]; + out.push(prev); + } } - } - - prev[1] += uy; - return out; -} - -function logarithmic () { - var x = function x(d) { - return d[0]; - }, - y = function y(d) { - return d[1]; - }, - base = Math.E, - domain; - - function logarithmic(data) { - var n = 0, - X = 0, - Y = 0, - XY = 0, - X2 = 0, - xmin = domain ? +domain[0] : Infinity, - xmax = domain ? +domain[1] : -Infinity, - lb = Math.log(base); - visitPoints(data, x, y, function (dx, dy) { - var lx = Math.log(dx) / lb; - ++n; - X += (lx - X) / n; - Y += (dy - Y) / n; - XY += (lx * dy - XY) / n; - X2 += (lx * lx - X2) / n; - - if (!domain) { - if (dx < xmin) xmin = dx; - if (dx > xmax) xmax = dx; - } - }); - - var _ols = ols(X, Y, XY, X2), - _ols2 = _slicedToArray(_ols, 2), - intercept = _ols2[0], - slope = _ols2[1], - fn = function fn(x) { - return slope * Math.log(x) / lb + intercept; - }, - out = interpose(xmin, xmax, fn); - - out.a = slope; - out.b = intercept; - out.predict = fn; - out.rSquared = determination(data, x, y, Y, fn); + prev[1] += uy; return out; - } - - logarithmic.domain = function (arr) { - return arguments.length ? (domain = arr, logarithmic) : domain; - }; - - logarithmic.x = function (fn) { - return arguments.length ? (x = fn, logarithmic) : x; - }; - - logarithmic.y = function (fn) { - return arguments.length ? (y = fn, logarithmic) : y; - }; - - logarithmic.base = function (n) { - return arguments.length ? (base = n, logarithmic) : base; - }; - - return logarithmic; } -function quad () { - var x = function x(d) { - return d[0]; - }, - y = function y(d) { - return d[1]; - }, - domain; - - function quadratic(data) { - var _points = points(data, x, y), - _points2 = _slicedToArray(_points, 4), - xv = _points2[0], - yv = _points2[1], - ux = _points2[2], - uy = _points2[3], - n = xv.length; - - var X2 = 0, - X3 = 0, - X4 = 0, - XY = 0, - X2Y = 0, - i, - dx, - dy, - x2; - - for (i = 0; i < n;) { - dx = xv[i]; - dy = yv[i++]; - x2 = dx * dx; - X2 += (x2 - X2) / i; - X3 += (x2 * dx - X3) / i; - X4 += (x2 * x2 - X4) / i; - XY += (dx * dy - XY) / i; - X2Y += (x2 * dy - X2Y) / i; - } - - var Y = 0, - n0 = 0, - xmin = domain ? +domain[0] : Infinity, - xmax = domain ? +domain[1] : -Infinity; - visitPoints(data, x, y, function (dx, dy) { - n0++; - Y += (dy - Y) / n0; - - if (!domain) { - if (dx < xmin) xmin = dx; - if (dx > xmax) xmax = dx; - } - }); - - var X2X2 = X4 - X2 * X2, - d = X2 * X2X2 - X3 * X3, - a = (X2Y * X2 - XY * X3) / d, - b = (XY * X2X2 - X2Y * X3) / d, - c = -a * X2, - fn = function fn(x) { - x = x - ux; - return a * x * x + b * x + c + uy; +function logarithmic() { + var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, base = Math.E, domain; + var logarithmicRegression = function logarithmicRegression(data) { + var n = 0, X = 0, Y = 0, XY = 0, X2 = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity, lb = Math.log(base); + visitPoints(data, x, y, function (dx, dy) { + var lx = Math.log(dx) / lb; + ++n; + X += (lx - X) / n; + Y += (dy - Y) / n; + XY += (lx * dy - XY) / n; + X2 += (lx * lx - X2) / n; + if (!domain) { + if (dx < xmin) + xmin = dx; + if (dx > xmax) + xmax = dx; + } + }); + var _a = ols(X, Y, XY, X2), intercept = _a[0], slope = _a[1]; + var fn = function (xx) { return slope * Math.log(xx) / lb + intercept; }; + var out = interpose(xmin, xmax, fn); + out.a = slope; + out.b = intercept; + out.predict = fn; + out.rSquared = determination(data, x, y, Y, fn); + return out; }; - - var out = interpose(xmin, xmax, fn); - out.a = a; - out.b = b - 2 * a * ux; - out.c = c - b * ux + a * ux * ux + uy; - out.predict = fn; - out.rSquared = determination(data, x, y, Y, fn); - return out; - } - - quadratic.domain = function (arr) { - return arguments.length ? (domain = arr, quadratic) : domain; - }; - - quadratic.x = function (fn) { - return arguments.length ? (x = fn, quadratic) : x; - }; - - quadratic.y = function (fn) { - return arguments.length ? (y = fn, quadratic) : y; - }; - - return quadratic; + logarithmicRegression.domain = function (arr) { + if (!arguments.length) + return domain; + domain = arr; + return logarithmicRegression; + }; + logarithmicRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return logarithmicRegression; + }; + logarithmicRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return logarithmicRegression; + }; + logarithmicRegression.base = function (b) { + if (!arguments.length) + return base; + base = b; + return logarithmicRegression; + }; + return logarithmicRegression; } -// Source: https://github.com/Tom-Alexander/regression-js/blob/master/src/regression.js#L246 -// License: https://github.com/Tom-Alexander/regression-js/blob/master/LICENSE -// ...with ideas from vega-statistics by Jeffrey Heer -// Source: https://github.com/vega/vega/blob/f21cb8792b4e0cbe2b1a3fd44b0f5db370dbaadb/packages/vega-statistics/src/regression/poly.js -// License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE - -function polynomial () { - var x = function x(d) { - return d[0]; - }, - y = function y(d) { - return d[1]; - }, - order = 3, - domain; - - function polynomial(data) { - // Use more efficient methods for lower orders - if (order === 1) { - var o = linear().x(x).y(y).domain(domain)(data); - o.coefficients = [o.b, o.a]; - delete o.a; - delete o.b; - return o; - } - - if (order === 2) { - var _o = quad().x(x).y(y).domain(domain)(data); - - _o.coefficients = [_o.c, _o.b, _o.a]; - delete _o.a; - delete _o.b; - delete _o.c; - return _o; - } - - var _points = points(data, x, y), - _points2 = _slicedToArray(_points, 4), - xv = _points2[0], - yv = _points2[1], - ux = _points2[2], - uy = _points2[3], - n = xv.length, - lhs = [], - rhs = [], - k = order + 1; - - var Y = 0, - n0 = 0, - xmin = domain ? +domain[0] : Infinity, - xmax = domain ? +domain[1] : -Infinity; - visitPoints(data, x, y, function (dx, dy) { - ++n0; - Y += (dy - Y) / n0; - - if (!domain) { - if (dx < xmin) xmin = dx; - if (dx > xmax) xmax = dx; - } - }); - var i, j, l, v, c; - - for (i = 0; i < k; ++i) { - for (l = 0, v = 0; l < n; ++l) { - v += Math.pow(xv[l], i) * yv[l]; - } - - lhs.push(v); - c = new Float64Array(k); - - for (j = 0; j < k; ++j) { - for (l = 0, v = 0; l < n; ++l) { - v += Math.pow(xv[l], i + j); +function quadratic() { + var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, domain; + var quadraticRegression = function quadraticRegression(data) { + var _a = points(data, x, y), xv = _a[0], yv = _a[1], ux = _a[2], uy = _a[3]; + var n = xv.length; + var X2 = 0, X3 = 0, X4 = 0, XY = 0, X2Y = 0, i, dx, dy, x2; + for (i = 0; i < n;) { + dx = xv[i]; + dy = yv[i++]; + x2 = dx * dx; + X2 += (x2 - X2) / i; + X3 += ((x2 * dx) - X3) / i; + X4 += ((x2 * x2) - X4) / i; + XY += ((dx * dy) - XY) / i; + X2Y += ((x2 * dy) - X2Y) / i; } - - c[j] = v; - } - - rhs.push(c); - } - - rhs.push(lhs); - - var coef = gaussianElimination(rhs), - fn = function fn(x) { - x -= ux; - var y = uy + coef[0] + coef[1] * x + coef[2] * x * x; - - for (i = 3; i < k; ++i) { - y += coef[i] * Math.pow(x, i); - } - - return y; - }, - out = interpose(xmin, xmax, fn); - - out.coefficients = uncenter(k, coef, -ux, uy); - out.predict = fn; - out.rSquared = determination(data, x, y, Y, fn); - return out; - } - - polynomial.domain = function (arr) { - return arguments.length ? (domain = arr, polynomial) : domain; - }; - - polynomial.x = function (fn) { - return arguments.length ? (x = fn, polynomial) : x; - }; - - polynomial.y = function (fn) { - return arguments.length ? (y = fn, polynomial) : y; - }; - - polynomial.order = function (n) { - return arguments.length ? (order = n, polynomial) : order; - }; - - return polynomial; + var Y = 0, n0 = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; + visitPoints(data, x, y, function (dx2, dy2) { + n0++; + Y += (dy2 - Y) / n0; + if (!domain) { + if (dx2 < xmin) + xmin = dx2; + if (dx2 > xmax) + xmax = dx2; + } + }); + var X2X2 = X4 - (X2 * X2); + var d = (X2 * X2X2 - X3 * X3); + var a = (X2Y * X2 - XY * X3) / d; + var b = (XY * X2X2 - X2Y * X3) / d; + var c = -a * X2; + var fn = function (xx) { + var shifted = xx - ux; + return a * shifted * shifted + b * shifted + c + uy; + }; + var out = interpose(xmin, xmax, fn); + out.a = a; + out.b = b - 2 * a * ux; + out.c = c - b * ux + a * ux * ux + uy; + out.predict = fn; + out.rSquared = determination(data, x, y, Y, fn); + return out; + }; + quadraticRegression.domain = function (arr) { + if (!arguments.length) + return domain; + domain = arr; + return quadraticRegression; + }; + quadraticRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return quadraticRegression; + }; + quadraticRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return quadraticRegression; + }; + return quadraticRegression; } +function polynomial() { + var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, order = 3, domain; + var polynomialRegression = function polynomialRegression(data) { + // Shortcut for lower-order polynomials: + if (order === 1) { + var o = linear().x(x).y(y).domain(domain)(data); + var result = [ + o[0], + o[1], + ]; + result.coefficients = [o.b, o.a]; + result.predict = o.predict; + result.rSquared = o.rSquared; + return result; + } + if (order === 2) { + var o = quadratic().x(x).y(y).domain(domain)(data); + var result = [ + o[0], + o[1], + ]; + result.coefficients = [o.c, o.b, o.a]; + result.predict = o.predict; + result.rSquared = o.rSquared; + return result; + } + var _a = points(data, x, y), xv = _a[0], yv = _a[1], ux = _a[2], uy = _a[3]; + var n = xv.length; + var k = order + 1; + var lhs = []; + var rhs = []; + var Y = 0, n0 = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; + visitPoints(data, x, y, function (dx, dy) { + n0++; + Y += (dy - Y) / n0; + if (!domain) { + if (dx < xmin) + xmin = dx; + if (dx > xmax) + xmax = dx; + } + }); + // Build normal equations + for (var i = 0; i < k; i++) { + // LHS + var v = 0; + for (var l = 0; l < n; l++) { + v += Math.pow(xv[l], i) * yv[l]; + } + lhs.push(v); + // RHS + var c = new Float64Array(k); + for (var j = 0; j < k; j++) { + var v2 = 0; + for (var l = 0; l < n; l++) { + v2 += Math.pow(xv[l], i + j); + } + c[j] = v2; + } + rhs.push(c); + } + rhs.push(new Float64Array(lhs)); + var coef = gaussianElimination(rhs); + var fn = function (xx) { + var shifted = xx - ux; + var val = uy + coef[0]; + for (var i = 1; i < k; i++) { + val += coef[i] * Math.pow(shifted, i); + } + return val; + }; + var out = interpose(xmin, xmax, fn); + out.coefficients = uncenter(k, coef, -ux, uy); + out.predict = fn; + out.rSquared = determination(data, x, y, Y, fn); + return out; + }; + polynomialRegression.domain = function (arr) { + if (!arguments.length) + return domain; + domain = arr; + return polynomialRegression; + }; + polynomialRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return polynomialRegression; + }; + polynomialRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return polynomialRegression; + }; + polynomialRegression.order = function (n) { + if (!arguments.length) + return order; + order = n; + return polynomialRegression; + }; + return polynomialRegression; +} function uncenter(k, a, x, y) { - var z = Array(k); - var i, j, v, c; // initialize to zero - - for (i = 0; i < k; ++i) { - z[i] = 0; - } // polynomial expansion - - - for (i = k - 1; i >= 0; --i) { - v = a[i]; - c = 1; - z[i] += v; - - for (j = 1; j <= i; ++j) { - c *= (i + 1 - j) / j; // binomial coefficent - - z[i - j] += v * Math.pow(x, j) * c; + var z = new Array(k).fill(0); + for (var i = k - 1; i >= 0; --i) { + var v = a[i]; + z[i] += v; + var c = 1; + for (var j = 1; j <= i; ++j) { + c *= (i + 1 - j) / j; // binomial coefficient + z[i - j] += v * Math.pow(x, j) * c; + } } - } // bias term - - - z[0] += y; - return z; -} // Given an array for a two-dimensional matrix and the polynomial order, -// solve A * x = b using Gaussian elimination. - - + // bias term + z[0] += y; + return z; +} +// Solve A * x = b using Gaussian elimination function gaussianElimination(matrix) { - var n = matrix.length - 1, - coef = []; - var i, j, k, r, t; - - for (i = 0; i < n; ++i) { - r = i; // max row - - for (j = i + 1; j < n; ++j) { - if (Math.abs(matrix[i][j]) > Math.abs(matrix[i][r])) { - r = j; - } - } - - for (k = i; k < n + 1; ++k) { - t = matrix[k][i]; - matrix[k][i] = matrix[k][r]; - matrix[k][r] = t; - } - - for (j = i + 1; j < n; ++j) { - for (k = n; k >= i; k--) { - matrix[k][j] -= matrix[k][i] * matrix[i][j] / matrix[i][i]; - } + var n = matrix.length - 1; + var coef = new Array(n); + for (var i = 0; i < n; i++) { + var r = i; + // find pivot row + for (var j = i + 1; j < n; j++) { + if (Math.abs(matrix[i][j]) > Math.abs(matrix[i][r])) { + r = j; + } + } + // swap columns + for (var k = i; k < n + 1; k++) { + var t = matrix[k][i]; + matrix[k][i] = matrix[k][r]; + matrix[k][r] = t; + } + // reduce + for (var j = i + 1; j < n; j++) { + for (var k = n; k >= i; k--) { + matrix[k][j] -= (matrix[k][i] * matrix[i][j]) / matrix[i][i]; + } + } } - } - - for (j = n - 1; j >= 0; --j) { - t = 0; - - for (k = j + 1; k < n; ++k) { - t += matrix[k][j] * coef[k]; + for (var j = n - 1; j >= 0; j--) { + var t = 0; + for (var k = j + 1; k < n; k++) { + t += matrix[k][j] * coef[k]; + } + coef[j] = (matrix[n][j] - t) / matrix[j][j]; } - - coef[j] = (matrix[n][j] - t) / matrix[j][j]; - } - - return coef; + return coef; } -function power () { - var x = function x(d) { - return d[0]; - }, - y = function y(d) { - return d[1]; - }, - domain; - - function power(data) { - var n = 0, - X = 0, - Y = 0, - XY = 0, - X2 = 0, - YS = 0, - xmin = domain ? +domain[0] : Infinity, - xmax = domain ? +domain[1] : -Infinity; - visitPoints(data, x, y, function (dx, dy) { - var lx = Math.log(dx), - ly = Math.log(dy); - ++n; - X += (lx - X) / n; - Y += (ly - Y) / n; - XY += (lx * ly - XY) / n; - X2 += (lx * lx - X2) / n; - YS += (dy - YS) / n; - - if (!domain) { - if (dx < xmin) xmin = dx; - if (dx > xmax) xmax = dx; - } - }); - - var _ols = ols(X, Y, XY, X2), - _ols2 = _slicedToArray(_ols, 2), - a = _ols2[0], - b = _ols2[1]; - - a = Math.exp(a); - - var fn = function fn(x) { - return a * Math.pow(x, b); - }, - out = interpose(xmin, xmax, fn); - - out.a = a; - out.b = b; - out.predict = fn; - out.rSquared = determination(data, x, y, YS, fn); - return out; - } - - power.domain = function (arr) { - return arguments.length ? (domain = arr, power) : domain; - }; - - power.x = function (fn) { - return arguments.length ? (x = fn, power) : x; - }; - - power.y = function (fn) { - return arguments.length ? (y = fn, power) : y; - }; - - return power; +function power() { + var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, domain; + var powerRegression = function powerRegression(data) { + var n = 0, X = 0, Y = 0, XY = 0, X2 = 0, YS = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; + visitPoints(data, x, y, function (dx, dy) { + var lx = Math.log(dx), ly = Math.log(dy); + ++n; + X += (lx - X) / n; + Y += (ly - Y) / n; + XY += (lx * ly - XY) / n; + X2 += (lx * lx - X2) / n; + YS += (dy - YS) / n; + if (!domain) { + if (dx < xmin) + xmin = dx; + if (dx > xmax) + xmax = dx; + } + }); + var _a = ols(X, Y, XY, X2), a = _a[0], b = _a[1]; + a = Math.exp(a); + var fn = function (xx) { return a * Math.pow(xx, b); }; + var out = interpose(xmin, xmax, fn); + out.a = a; + out.b = b; + out.predict = fn; + out.rSquared = determination(data, x, y, YS, fn); + return out; + }; + powerRegression.domain = function (arr) { + if (!arguments.length) + return domain; + domain = arr; + return powerRegression; + }; + powerRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return powerRegression; + }; + powerRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return powerRegression; + }; + return powerRegression; } exports.regressionExp = exponential; @@ -876,4 +679,4 @@ exports.regressionLoess = loess; exports.regressionLog = logarithmic; exports.regressionPoly = polynomial; exports.regressionPow = power; -exports.regressionQuad = quad; +exports.regressionQuad = quadratic; diff --git a/dist/d3-regression.esm.js b/dist/d3-regression.esm.js index c1a206b..cb631e0 100644 --- a/dist/d3-regression.esm.js +++ b/dist/d3-regression.esm.js @@ -1,869 +1,672 @@ -// https://github.com/HarryStevens/d3-regression#readme Version 1.3.10. Copyright 2022 Harry Stevens. -function _slicedToArray(arr, i) { - return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); -} - -function _arrayWithHoles(arr) { - if (Array.isArray(arr)) return arr; -} - -function _iterableToArrayLimit(arr, i) { - var _arr = []; - var _n = true; - var _d = false; - var _e = undefined; - - try { - for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { - _arr.push(_s.value); - - if (i && _arr.length === i) break; - } - } catch (err) { - _d = true; - _e = err; - } finally { - try { - if (!_n && _i["return"] != null) _i["return"](); - } finally { - if (_d) throw _e; - } - } - - return _arr; -} - -function _nonIterableRest() { - throw new TypeError("Invalid attempt to destructure non-iterable instance"); -} - -// Adapted from vega-statistics by Jeffrey Heer -// License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE -// Source: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/packages/vega-statistics/src/regression/points.js +// https://github.com/HarryStevens/d3-regression#readme Version 1.3.10. Copyright 2025 Harry Stevens. +/** + * Adapted from vega-statistics by Jeffrey Heer + * License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE + * Source: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/packages/vega-statistics/src/regression/points.js + */ function points(data, x, y, sort) { - data = data.filter(function (d, i) { - var u = x(d, i), - v = y(d, i); - return u != null && isFinite(u) && v != null && isFinite(v); - }); - - if (sort) { - data.sort(function (a, b) { - return x(a) - x(b); + data = data.filter(function (d, i) { + var u = x(d, i), v = y(d, i); + return u != null && isFinite(u) && v != null && isFinite(v); }); - } - - var n = data.length, - X = new Float64Array(n), - Y = new Float64Array(n); // extract values, calculate means - - var ux = 0, - uy = 0, - xv, - yv, - d; - - for (var i = 0; i < n;) { - d = data[i]; - X[i] = xv = +x(d, i, data); - Y[i] = yv = +y(d, i, data); - ++i; - ux += (xv - ux) / i; - uy += (yv - uy) / i; - } // mean center the data - - - for (var _i = 0; _i < n; ++_i) { - X[_i] -= ux; - Y[_i] -= uy; - } - - return [X, Y, ux, uy]; + if (sort) { + data.sort(function (a, b) { return x(a) - x(b); }); + } + var n = data.length, X = new Float64Array(n), Y = new Float64Array(n); + // extract values, calculate means + var ux = 0, uy = 0, xv, yv, d; + for (var i = 0; i < n;) { + d = data[i]; + X[i] = xv = +x(d, i, data); + Y[i] = yv = +y(d, i, data); + ++i; + ux += (xv - ux) / i; + uy += (yv - uy) / i; + } + // mean center the data + for (var i = 0; i < n; ++i) { + X[i] -= ux; + Y[i] -= uy; + } + return [X, Y, ux, uy]; } +/** + * Iterates over valid data points, invoking a callback for each. + */ function visitPoints(data, x, y, cb) { - var iterations = 0; - - for (var i = 0, n = data.length; i < n; i++) { - var d = data[i], - dx = +x(d, i, data), - dy = +y(d, i, data); - - if (dx != null && isFinite(dx) && dy != null && isFinite(dy)) { - cb(dx, dy, iterations++); + var iterations = 0; + for (var i = 0; i < data.length; i++) { + var d = data[i]; + var dx = +x(d, i, data); + var dy = +y(d, i, data); + if (dx != null && isFinite(dx) && dy != null && isFinite(dy)) { + cb(dx, dy, iterations++); + } } - } } -// return the coefficient of determination, or R squared. - +/** + * Given a dataset, x- and y-accessors, the mean center of the y-values (uY), + * and a prediction function, return the coefficient of determination, R^2. + */ function determination(data, x, y, uY, predict) { - var SSE = 0, - SST = 0; - visitPoints(data, x, y, function (dx, dy) { - var sse = dy - predict(dx), - sst = dy - uY; - SSE += sse * sse; - SST += sst * sst; - }); - return 1 - SSE / SST; + var SSE = 0, // Sum of Squared Errors + SST = 0; // Total Sum of Squares + visitPoints(data, x, y, function (dx, dy) { + var sse = dy - predict(dx); + var sst = dy - uY; + SSE += sse * sse; + SST += sst * sst; + }); + return 1 - SSE / SST; } -// Returns the angle of a line in degrees. +/** + * Returns the angle of a line in degrees. + */ function angle(line) { - return Math.atan2(line[1][1] - line[0][1], line[1][0] - line[0][0]) * 180 / Math.PI; -} // Returns the midpoint of a line. - + return (Math.atan2(line[1][1] - line[0][1], line[1][0] - line[0][0]) * + (180 / Math.PI)); +} +/** + * Returns the midpoint of a line. + */ function midpoint(line) { - return [(line[0][0] + line[1][0]) / 2, (line[0][1] + line[1][1]) / 2]; + return [ + (line[0][0] + line[1][0]) / 2, + (line[0][1] + line[1][1]) / 2 + ]; } -// returns a smooth line. - +/** + * Given a start point (xmin), an end point (xmax), + * and a prediction function, returns a smooth line. + */ function interpose(xmin, xmax, predict) { - var l = Math.log(xmax - xmin) * Math.LOG10E + 1 | 0; - var precision = 1 * Math.pow(10, -l / 2 - 1), - maxIter = 1e4; - var points = [px(xmin), px(xmax)], - iter = 0; - - while (find(points) && iter < maxIter) { - } - - return points; - - function px(x) { - return [x, predict(x)]; - } - - function find(points) { - iter++; - var n = points.length; - var found = false; - - for (var i = 0; i < n - 1; i++) { - var p0 = points[i], - p1 = points[i + 1], - m = midpoint([p0, p1]), - mp = px(m[0]), - a0 = angle([p0, m]), - a1 = angle([p0, mp]), - a = Math.abs(a0 - a1); - - if (a > precision) { - points.splice(i + 1, 0, mp); - found = true; - } + var l = (Math.log(xmax - xmin) * Math.LOG10E + 1) | 0; + var precision = Math.pow(10, -l / 2 - 1); + var maxIter = 1e4; + var points = [px(xmin), px(xmax)]; + var iter = 0; + while (find(points) && iter < maxIter) + ; + return points; + function px(x) { + return [x, predict(x)]; + } + function find(points) { + iter++; + var n = points.length; + var found = false; + for (var i = 0; i < n - 1; i++) { + var p0 = points[i]; + var p1 = points[i + 1]; + var m = midpoint([p0, p1]); + var mp = px(m[0]); + var a0 = angle([p0, m]); + var a1 = angle([p0, mp]); + var a = Math.abs(a0 - a1); + if (a > precision) { + points.splice(i + 1, 0, mp); + found = true; + } + } + return found; } - - return found; - } } -// Ordinary Least Squares from vega-statistics by Jeffrey Heer -// License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE -// Source: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/packages/vega-statistics/src/regression/ols.js +/** + * Ordinary Least Squares from vega-statistics by Jeffrey Heer + * License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE + * Source: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/packages/vega-statistics/src/regression/ols.js + */ function ols(uX, uY, uXY, uX2) { - var delta = uX2 - uX * uX, - slope = Math.abs(delta) < 1e-24 ? 0 : (uXY - uX * uY) / delta, - intercept = uY - slope * uX; - return [intercept, slope]; + var delta = uX2 - uX * uX, slope = Math.abs(delta) < 1e-24 ? 0 : (uXY - uX * uY) / delta, intercept = uY - slope * uX; + return [intercept, slope]; } -function exponential () { - var x = function x(d) { - return d[0]; - }, - y = function y(d) { - return d[1]; - }, - domain; - - function exponential(data) { - var n = 0, - Y = 0, - YL = 0, - XY = 0, - XYL = 0, - X2Y = 0, - xmin = domain ? +domain[0] : Infinity, - xmax = domain ? +domain[1] : -Infinity; - visitPoints(data, x, y, function (dx, dy) { - var ly = Math.log(dy), - xy = dx * dy; - ++n; - Y += (dy - Y) / n; - XY += (xy - XY) / n; - X2Y += (dx * xy - X2Y) / n; - YL += (dy * ly - YL) / n; - XYL += (xy * ly - XYL) / n; - - if (!domain) { - if (dx < xmin) xmin = dx; - if (dx > xmax) xmax = dx; - } - }); - - var _ols = ols(XY / Y, YL / Y, XYL / Y, X2Y / Y), - _ols2 = _slicedToArray(_ols, 2), - a = _ols2[0], - b = _ols2[1]; - - a = Math.exp(a); - - var fn = function fn(x) { - return a * Math.exp(b * x); - }, - out = interpose(xmin, xmax, fn); - - out.a = a; - out.b = b; - out.predict = fn; - out.rSquared = determination(data, x, y, Y, fn); - return out; - } - - exponential.domain = function (arr) { - return arguments.length ? (domain = arr, exponential) : domain; - }; - - exponential.x = function (fn) { - return arguments.length ? (x = fn, exponential) : x; - }; - - exponential.y = function (fn) { - return arguments.length ? (y = fn, exponential) : y; - }; - - return exponential; +function exponential() { + var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, domain; + var exponentialRegression = function (data) { + var n = 0, Y = 0, YL = 0, XY = 0, XYL = 0, X2Y = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; + visitPoints(data, x, y, function (dx, dy) { + var ly = Math.log(dy), xy = dx * dy; + ++n; + Y += (dy - Y) / n; + XY += (xy - XY) / n; + X2Y += (dx * xy - X2Y) / n; + YL += (dy * ly - YL) / n; + XYL += (xy * ly - XYL) / n; + if (!domain) { + if (dx < xmin) + xmin = dx; + if (dx > xmax) + xmax = dx; + } + }); + var _a = ols(XY / Y, YL / Y, XYL / Y, X2Y / Y), a = _a[0], b = _a[1]; + a = Math.exp(a); + var fn = function (xx) { return a * Math.exp(b * xx); }; + var out = interpose(xmin, xmax, fn); + out.a = a; + out.b = b; + out.predict = fn; + out.rSquared = determination(data, x, y, Y, fn); + return out; + }; + exponentialRegression.domain = function (arr) { + if (!arguments.length) + return domain; + domain = arr; + return exponentialRegression; + }; + exponentialRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return exponentialRegression; + }; + exponentialRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return exponentialRegression; + }; + return exponentialRegression; } -function linear () { - var x = function x(d) { - return d[0]; - }, - y = function y(d) { - return d[1]; - }, - domain; - - function linear(data) { - var n = 0, - X = 0, - // sum of x - Y = 0, - // sum of y - XY = 0, - // sum of x * y - X2 = 0, - // sum of x * x - xmin = domain ? +domain[0] : Infinity, - xmax = domain ? +domain[1] : -Infinity; - visitPoints(data, x, y, function (dx, dy) { - ++n; - X += (dx - X) / n; - Y += (dy - Y) / n; - XY += (dx * dy - XY) / n; - X2 += (dx * dx - X2) / n; - - if (!domain) { - if (dx < xmin) xmin = dx; - if (dx > xmax) xmax = dx; - } - }); - - var _ols = ols(X, Y, XY, X2), - _ols2 = _slicedToArray(_ols, 2), - intercept = _ols2[0], - slope = _ols2[1], - fn = function fn(x) { - return slope * x + intercept; - }, - out = [[xmin, fn(xmin)], [xmax, fn(xmax)]]; - - out.a = slope; - out.b = intercept; - out.predict = fn; - out.rSquared = determination(data, x, y, Y, fn); - return out; - } - - linear.domain = function (arr) { - return arguments.length ? (domain = arr, linear) : domain; - }; - - linear.x = function (fn) { - return arguments.length ? (x = fn, linear) : x; - }; - - linear.y = function (fn) { - return arguments.length ? (y = fn, linear) : y; - }; - - return linear; +function linear() { + var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, domain; + var linearRegression = function (data) { + var n = 0, X = 0, // sum of x + Y = 0, // sum of y + XY = 0, // sum of x*y + X2 = 0, // sum of x*x + xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; + visitPoints(data, x, y, function (dx, dy) { + ++n; + X += (dx - X) / n; + Y += (dy - Y) / n; + XY += (dx * dy - XY) / n; + X2 += (dx * dx - X2) / n; + if (!domain) { + if (dx < xmin) + xmin = dx; + if (dx > xmax) + xmax = dx; + } + }); + var _a = ols(X, Y, XY, X2), intercept = _a[0], slope = _a[1]; + var fn = function (xx) { return slope * xx + intercept; }; + var out = [[xmin, fn(xmin)], [xmax, fn(xmax)]]; + out.a = slope; + out.b = intercept; + out.predict = fn; + out.rSquared = determination(data, x, y, Y, fn); + return out; + }; + linearRegression.domain = function (arr) { + if (!arguments.length) + return domain; + domain = arr; + return linearRegression; + }; + linearRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return linearRegression; + }; + linearRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return linearRegression; + }; + return linearRegression; } -// Returns the medium value of an array of numbers. +/** + * Returns the median value of an array of numbers. + */ function median(arr) { - arr.sort(function (a, b) { - return a - b; - }); - var i = arr.length / 2; - return i % 1 === 0 ? (arr[i - 1] + arr[i]) / 2 : arr[Math.floor(i)]; + arr.sort(function (a, b) { return a - b; }); + var i = arr.length / 2; + return i % 1 === 0 ? (arr[i - 1] + arr[i]) / 2 : arr[Math.floor(i)]; } -var maxiters = 2, - epsilon = 1e-12; -function loess () { - var x = function x(d) { - return d[0]; - }, - y = function y(d) { - return d[1]; - }, - bandwidth = .3; - - function loess(data) { - var _points = points(data, x, y, true), - _points2 = _slicedToArray(_points, 4), - xv = _points2[0], - yv = _points2[1], - ux = _points2[2], - uy = _points2[3], - n = xv.length, - bw = Math.max(2, ~~(bandwidth * n)), - yhat = new Float64Array(n), - residuals = new Float64Array(n), - robustWeights = new Float64Array(n).fill(1); - - for (var iter = -1; ++iter <= maxiters;) { - var interval = [0, bw - 1]; - - for (var i = 0; i < n; ++i) { - var dx = xv[i], - i0 = interval[0], - i1 = interval[1], - edge = dx - xv[i0] > xv[i1] - dx ? i0 : i1; - var W = 0, - X = 0, - Y = 0, - XY = 0, - X2 = 0, - denom = 1 / Math.abs(xv[edge] - dx || 1); // Avoid singularity - - for (var k = i0; k <= i1; ++k) { - var xk = xv[k], - yk = yv[k], - w = tricube(Math.abs(dx - xk) * denom) * robustWeights[k], - xkw = xk * w; - W += w; - X += xkw; - Y += yk * w; - XY += yk * xkw; - X2 += xk * xkw; - } // Linear regression fit - - - var _ols = ols(X / W, Y / W, XY / W, X2 / W), - _ols2 = _slicedToArray(_ols, 2), - a = _ols2[0], - b = _ols2[1]; - - yhat[i] = a + b * dx; - residuals[i] = Math.abs(yv[i] - yhat[i]); - updateInterval(xv, i + 1, interval); - } - - if (iter === maxiters) { - break; - } - - var medianResidual = median(residuals); - if (Math.abs(medianResidual) < epsilon) break; - - for (var _i = 0, arg, _w; _i < n; ++_i) { - arg = residuals[_i] / (6 * medianResidual); // Default to epsilon (rather than zero) for large deviations - // Keeping weights tiny but non-zero prevents singularites - - robustWeights[_i] = arg >= 1 ? epsilon : (_w = 1 - arg * arg) * _w; - } - } - - return output(xv, yhat, ux, uy); - } - - loess.bandwidth = function (bw) { - return arguments.length ? (bandwidth = bw, loess) : bandwidth; - }; - - loess.x = function (fn) { - return arguments.length ? (x = fn, loess) : x; - }; - - loess.y = function (fn) { - return arguments.length ? (y = fn, loess) : y; - }; - - return loess; -} // Weighting kernel for local regression - +// Adapted from science.js by Jason Davies +var maxiters = 2, epsilon = 1e-12; +function loess() { + var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, bandwidth = .3; + var loessRegression = function loessRegression(data) { + var _a = points(data, x, y, true), xv = _a[0], yv = _a[1], ux = _a[2], uy = _a[3]; + var n = xv.length; + var bw = Math.max(2, ~~(bandwidth * n)); // # of nearest neighbors + var yhat = new Float64Array(n); + var residuals = new Float64Array(n); + var robustWeights = new Float64Array(n).fill(1); + for (var iter = -1; ++iter <= maxiters;) { + var interval = [0, bw - 1]; + for (var i = 0; i < n; ++i) { + var dx = xv[i]; + var i0 = interval[0]; + var i1 = interval[1]; + var edge = (dx - xv[i0]) > (xv[i1] - dx) ? i0 : i1; + var W = 0, X = 0, Y = 0, XY = 0, X2 = 0; + var denom = 1 / Math.abs(xv[edge] - dx || 1); + for (var k = i0; k <= i1; ++k) { + var xk = xv[k]; + var yk = yv[k]; + var w = tricube(Math.abs(dx - xk) * denom) * robustWeights[k]; + var xkw = xk * w; + W += w; + X += xkw; + Y += yk * w; + XY += yk * xkw; + X2 += xk * xkw; + } + // Linear regression fit + var _b = ols(X / W, Y / W, XY / W, X2 / W), a = _b[0], b = _b[1]; + yhat[i] = a + b * dx; + residuals[i] = Math.abs(yv[i] - yhat[i]); + updateInterval(xv, i + 1, interval); + } + if (iter === maxiters) { + break; + } + var medianResidual = median(residuals); + if (Math.abs(medianResidual) < epsilon) + break; + for (var i = 0, arg = void 0, w = void 0; i < n; ++i) { + arg = residuals[i] / (6 * medianResidual); + // Default to epsilon (rather than zero) for large deviations + // Keeping weights tiny but non-zero prevents singularites + robustWeights[i] = (arg >= 1) ? epsilon : ((w = 1 - arg * arg) * w); + } + } + return output(xv, yhat, ux, uy); + }; + loessRegression.bandwidth = function (bw) { + if (!arguments.length) + return bandwidth; + bandwidth = bw; + return loessRegression; + }; + loessRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return loessRegression; + }; + loessRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return loessRegression; + }; + return loessRegression; +} +// Weighting kernel for local regression function tricube(x) { - return (x = 1 - x * x * x) * x * x; -} // Advance sliding window interval of nearest neighbors - - + return (x = 1 - x * x * x) * x * x; +} +// Advance sliding window interval of nearest neighbors function updateInterval(xv, i, interval) { - var val = xv[i], - left = interval[0], - right = interval[1] + 1; - if (right >= xv.length) return; // Step right if distance to new right edge is <= distance to old left edge - // Step when distance is equal to ensure movement over duplicate x values - - while (i > left && xv[right] - val <= val - xv[left]) { - interval[0] = ++left; - interval[1] = right; - ++right; - } -} // Generate smoothed output points + var val = xv[i], left = interval[0], right = interval[1] + 1; + if (right >= xv.length) + return; + // Step right if distance to new right edge is <= distance to old left edge + // Step when distance is equal to ensure movement over duplicate x values + while (i > left && (xv[right] - val) <= (val - xv[left])) { + interval[0] = ++left; + interval[1] = right; + ++right; + } +} +// Generate smoothed output points // Average points with repeated x values - - function output(xv, yhat, ux, uy) { - var n = xv.length, - out = []; - var i = 0, - cnt = 0, - prev = [], - v; - - for (; i < n; ++i) { - v = xv[i] + ux; - - if (prev[0] === v) { - // Average output values via online update - prev[1] += (yhat[i] - prev[1]) / ++cnt; - } else { - // Add new output point - cnt = 0; - prev[1] += uy; - prev = [v, yhat[i]]; - out.push(prev); + var n = xv.length, out = []; + var i = 0, cnt = 0, prev = [], v; + for (; i < n; ++i) { + v = xv[i] + ux; + if (prev[0] === v) { + // Average output values via online update + prev[1] += (yhat[i] - prev[1]) / (++cnt); + } + else { + // Add new output point + cnt = 0; + prev[1] += uy; + prev = [v, yhat[i]]; + out.push(prev); + } } - } - - prev[1] += uy; - return out; -} - -function logarithmic () { - var x = function x(d) { - return d[0]; - }, - y = function y(d) { - return d[1]; - }, - base = Math.E, - domain; - - function logarithmic(data) { - var n = 0, - X = 0, - Y = 0, - XY = 0, - X2 = 0, - xmin = domain ? +domain[0] : Infinity, - xmax = domain ? +domain[1] : -Infinity, - lb = Math.log(base); - visitPoints(data, x, y, function (dx, dy) { - var lx = Math.log(dx) / lb; - ++n; - X += (lx - X) / n; - Y += (dy - Y) / n; - XY += (lx * dy - XY) / n; - X2 += (lx * lx - X2) / n; - - if (!domain) { - if (dx < xmin) xmin = dx; - if (dx > xmax) xmax = dx; - } - }); - - var _ols = ols(X, Y, XY, X2), - _ols2 = _slicedToArray(_ols, 2), - intercept = _ols2[0], - slope = _ols2[1], - fn = function fn(x) { - return slope * Math.log(x) / lb + intercept; - }, - out = interpose(xmin, xmax, fn); - - out.a = slope; - out.b = intercept; - out.predict = fn; - out.rSquared = determination(data, x, y, Y, fn); + prev[1] += uy; return out; - } - - logarithmic.domain = function (arr) { - return arguments.length ? (domain = arr, logarithmic) : domain; - }; - - logarithmic.x = function (fn) { - return arguments.length ? (x = fn, logarithmic) : x; - }; - - logarithmic.y = function (fn) { - return arguments.length ? (y = fn, logarithmic) : y; - }; - - logarithmic.base = function (n) { - return arguments.length ? (base = n, logarithmic) : base; - }; - - return logarithmic; } -function quad () { - var x = function x(d) { - return d[0]; - }, - y = function y(d) { - return d[1]; - }, - domain; - - function quadratic(data) { - var _points = points(data, x, y), - _points2 = _slicedToArray(_points, 4), - xv = _points2[0], - yv = _points2[1], - ux = _points2[2], - uy = _points2[3], - n = xv.length; - - var X2 = 0, - X3 = 0, - X4 = 0, - XY = 0, - X2Y = 0, - i, - dx, - dy, - x2; - - for (i = 0; i < n;) { - dx = xv[i]; - dy = yv[i++]; - x2 = dx * dx; - X2 += (x2 - X2) / i; - X3 += (x2 * dx - X3) / i; - X4 += (x2 * x2 - X4) / i; - XY += (dx * dy - XY) / i; - X2Y += (x2 * dy - X2Y) / i; - } - - var Y = 0, - n0 = 0, - xmin = domain ? +domain[0] : Infinity, - xmax = domain ? +domain[1] : -Infinity; - visitPoints(data, x, y, function (dx, dy) { - n0++; - Y += (dy - Y) / n0; - - if (!domain) { - if (dx < xmin) xmin = dx; - if (dx > xmax) xmax = dx; - } - }); - - var X2X2 = X4 - X2 * X2, - d = X2 * X2X2 - X3 * X3, - a = (X2Y * X2 - XY * X3) / d, - b = (XY * X2X2 - X2Y * X3) / d, - c = -a * X2, - fn = function fn(x) { - x = x - ux; - return a * x * x + b * x + c + uy; +function logarithmic() { + var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, base = Math.E, domain; + var logarithmicRegression = function logarithmicRegression(data) { + var n = 0, X = 0, Y = 0, XY = 0, X2 = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity, lb = Math.log(base); + visitPoints(data, x, y, function (dx, dy) { + var lx = Math.log(dx) / lb; + ++n; + X += (lx - X) / n; + Y += (dy - Y) / n; + XY += (lx * dy - XY) / n; + X2 += (lx * lx - X2) / n; + if (!domain) { + if (dx < xmin) + xmin = dx; + if (dx > xmax) + xmax = dx; + } + }); + var _a = ols(X, Y, XY, X2), intercept = _a[0], slope = _a[1]; + var fn = function (xx) { return slope * Math.log(xx) / lb + intercept; }; + var out = interpose(xmin, xmax, fn); + out.a = slope; + out.b = intercept; + out.predict = fn; + out.rSquared = determination(data, x, y, Y, fn); + return out; }; - - var out = interpose(xmin, xmax, fn); - out.a = a; - out.b = b - 2 * a * ux; - out.c = c - b * ux + a * ux * ux + uy; - out.predict = fn; - out.rSquared = determination(data, x, y, Y, fn); - return out; - } - - quadratic.domain = function (arr) { - return arguments.length ? (domain = arr, quadratic) : domain; - }; - - quadratic.x = function (fn) { - return arguments.length ? (x = fn, quadratic) : x; - }; - - quadratic.y = function (fn) { - return arguments.length ? (y = fn, quadratic) : y; - }; - - return quadratic; + logarithmicRegression.domain = function (arr) { + if (!arguments.length) + return domain; + domain = arr; + return logarithmicRegression; + }; + logarithmicRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return logarithmicRegression; + }; + logarithmicRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return logarithmicRegression; + }; + logarithmicRegression.base = function (b) { + if (!arguments.length) + return base; + base = b; + return logarithmicRegression; + }; + return logarithmicRegression; } -// Source: https://github.com/Tom-Alexander/regression-js/blob/master/src/regression.js#L246 -// License: https://github.com/Tom-Alexander/regression-js/blob/master/LICENSE -// ...with ideas from vega-statistics by Jeffrey Heer -// Source: https://github.com/vega/vega/blob/f21cb8792b4e0cbe2b1a3fd44b0f5db370dbaadb/packages/vega-statistics/src/regression/poly.js -// License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE - -function polynomial () { - var x = function x(d) { - return d[0]; - }, - y = function y(d) { - return d[1]; - }, - order = 3, - domain; - - function polynomial(data) { - // Use more efficient methods for lower orders - if (order === 1) { - var o = linear().x(x).y(y).domain(domain)(data); - o.coefficients = [o.b, o.a]; - delete o.a; - delete o.b; - return o; - } - - if (order === 2) { - var _o = quad().x(x).y(y).domain(domain)(data); - - _o.coefficients = [_o.c, _o.b, _o.a]; - delete _o.a; - delete _o.b; - delete _o.c; - return _o; - } - - var _points = points(data, x, y), - _points2 = _slicedToArray(_points, 4), - xv = _points2[0], - yv = _points2[1], - ux = _points2[2], - uy = _points2[3], - n = xv.length, - lhs = [], - rhs = [], - k = order + 1; - - var Y = 0, - n0 = 0, - xmin = domain ? +domain[0] : Infinity, - xmax = domain ? +domain[1] : -Infinity; - visitPoints(data, x, y, function (dx, dy) { - ++n0; - Y += (dy - Y) / n0; - - if (!domain) { - if (dx < xmin) xmin = dx; - if (dx > xmax) xmax = dx; - } - }); - var i, j, l, v, c; - - for (i = 0; i < k; ++i) { - for (l = 0, v = 0; l < n; ++l) { - v += Math.pow(xv[l], i) * yv[l]; - } - - lhs.push(v); - c = new Float64Array(k); - - for (j = 0; j < k; ++j) { - for (l = 0, v = 0; l < n; ++l) { - v += Math.pow(xv[l], i + j); +function quadratic() { + var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, domain; + var quadraticRegression = function quadraticRegression(data) { + var _a = points(data, x, y), xv = _a[0], yv = _a[1], ux = _a[2], uy = _a[3]; + var n = xv.length; + var X2 = 0, X3 = 0, X4 = 0, XY = 0, X2Y = 0, i, dx, dy, x2; + for (i = 0; i < n;) { + dx = xv[i]; + dy = yv[i++]; + x2 = dx * dx; + X2 += (x2 - X2) / i; + X3 += ((x2 * dx) - X3) / i; + X4 += ((x2 * x2) - X4) / i; + XY += ((dx * dy) - XY) / i; + X2Y += ((x2 * dy) - X2Y) / i; } - - c[j] = v; - } - - rhs.push(c); - } - - rhs.push(lhs); - - var coef = gaussianElimination(rhs), - fn = function fn(x) { - x -= ux; - var y = uy + coef[0] + coef[1] * x + coef[2] * x * x; - - for (i = 3; i < k; ++i) { - y += coef[i] * Math.pow(x, i); - } - - return y; - }, - out = interpose(xmin, xmax, fn); - - out.coefficients = uncenter(k, coef, -ux, uy); - out.predict = fn; - out.rSquared = determination(data, x, y, Y, fn); - return out; - } - - polynomial.domain = function (arr) { - return arguments.length ? (domain = arr, polynomial) : domain; - }; - - polynomial.x = function (fn) { - return arguments.length ? (x = fn, polynomial) : x; - }; - - polynomial.y = function (fn) { - return arguments.length ? (y = fn, polynomial) : y; - }; - - polynomial.order = function (n) { - return arguments.length ? (order = n, polynomial) : order; - }; - - return polynomial; + var Y = 0, n0 = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; + visitPoints(data, x, y, function (dx2, dy2) { + n0++; + Y += (dy2 - Y) / n0; + if (!domain) { + if (dx2 < xmin) + xmin = dx2; + if (dx2 > xmax) + xmax = dx2; + } + }); + var X2X2 = X4 - (X2 * X2); + var d = (X2 * X2X2 - X3 * X3); + var a = (X2Y * X2 - XY * X3) / d; + var b = (XY * X2X2 - X2Y * X3) / d; + var c = -a * X2; + var fn = function (xx) { + var shifted = xx - ux; + return a * shifted * shifted + b * shifted + c + uy; + }; + var out = interpose(xmin, xmax, fn); + out.a = a; + out.b = b - 2 * a * ux; + out.c = c - b * ux + a * ux * ux + uy; + out.predict = fn; + out.rSquared = determination(data, x, y, Y, fn); + return out; + }; + quadraticRegression.domain = function (arr) { + if (!arguments.length) + return domain; + domain = arr; + return quadraticRegression; + }; + quadraticRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return quadraticRegression; + }; + quadraticRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return quadraticRegression; + }; + return quadraticRegression; } +function polynomial() { + var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, order = 3, domain; + var polynomialRegression = function polynomialRegression(data) { + // Shortcut for lower-order polynomials: + if (order === 1) { + var o = linear().x(x).y(y).domain(domain)(data); + var result = [ + o[0], + o[1], + ]; + result.coefficients = [o.b, o.a]; + result.predict = o.predict; + result.rSquared = o.rSquared; + return result; + } + if (order === 2) { + var o = quadratic().x(x).y(y).domain(domain)(data); + var result = [ + o[0], + o[1], + ]; + result.coefficients = [o.c, o.b, o.a]; + result.predict = o.predict; + result.rSquared = o.rSquared; + return result; + } + var _a = points(data, x, y), xv = _a[0], yv = _a[1], ux = _a[2], uy = _a[3]; + var n = xv.length; + var k = order + 1; + var lhs = []; + var rhs = []; + var Y = 0, n0 = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; + visitPoints(data, x, y, function (dx, dy) { + n0++; + Y += (dy - Y) / n0; + if (!domain) { + if (dx < xmin) + xmin = dx; + if (dx > xmax) + xmax = dx; + } + }); + // Build normal equations + for (var i = 0; i < k; i++) { + // LHS + var v = 0; + for (var l = 0; l < n; l++) { + v += Math.pow(xv[l], i) * yv[l]; + } + lhs.push(v); + // RHS + var c = new Float64Array(k); + for (var j = 0; j < k; j++) { + var v2 = 0; + for (var l = 0; l < n; l++) { + v2 += Math.pow(xv[l], i + j); + } + c[j] = v2; + } + rhs.push(c); + } + rhs.push(new Float64Array(lhs)); + var coef = gaussianElimination(rhs); + var fn = function (xx) { + var shifted = xx - ux; + var val = uy + coef[0]; + for (var i = 1; i < k; i++) { + val += coef[i] * Math.pow(shifted, i); + } + return val; + }; + var out = interpose(xmin, xmax, fn); + out.coefficients = uncenter(k, coef, -ux, uy); + out.predict = fn; + out.rSquared = determination(data, x, y, Y, fn); + return out; + }; + polynomialRegression.domain = function (arr) { + if (!arguments.length) + return domain; + domain = arr; + return polynomialRegression; + }; + polynomialRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return polynomialRegression; + }; + polynomialRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return polynomialRegression; + }; + polynomialRegression.order = function (n) { + if (!arguments.length) + return order; + order = n; + return polynomialRegression; + }; + return polynomialRegression; +} function uncenter(k, a, x, y) { - var z = Array(k); - var i, j, v, c; // initialize to zero - - for (i = 0; i < k; ++i) { - z[i] = 0; - } // polynomial expansion - - - for (i = k - 1; i >= 0; --i) { - v = a[i]; - c = 1; - z[i] += v; - - for (j = 1; j <= i; ++j) { - c *= (i + 1 - j) / j; // binomial coefficent - - z[i - j] += v * Math.pow(x, j) * c; + var z = new Array(k).fill(0); + for (var i = k - 1; i >= 0; --i) { + var v = a[i]; + z[i] += v; + var c = 1; + for (var j = 1; j <= i; ++j) { + c *= (i + 1 - j) / j; // binomial coefficient + z[i - j] += v * Math.pow(x, j) * c; + } } - } // bias term - - - z[0] += y; - return z; -} // Given an array for a two-dimensional matrix and the polynomial order, -// solve A * x = b using Gaussian elimination. - - + // bias term + z[0] += y; + return z; +} +// Solve A * x = b using Gaussian elimination function gaussianElimination(matrix) { - var n = matrix.length - 1, - coef = []; - var i, j, k, r, t; - - for (i = 0; i < n; ++i) { - r = i; // max row - - for (j = i + 1; j < n; ++j) { - if (Math.abs(matrix[i][j]) > Math.abs(matrix[i][r])) { - r = j; - } - } - - for (k = i; k < n + 1; ++k) { - t = matrix[k][i]; - matrix[k][i] = matrix[k][r]; - matrix[k][r] = t; - } - - for (j = i + 1; j < n; ++j) { - for (k = n; k >= i; k--) { - matrix[k][j] -= matrix[k][i] * matrix[i][j] / matrix[i][i]; - } + var n = matrix.length - 1; + var coef = new Array(n); + for (var i = 0; i < n; i++) { + var r = i; + // find pivot row + for (var j = i + 1; j < n; j++) { + if (Math.abs(matrix[i][j]) > Math.abs(matrix[i][r])) { + r = j; + } + } + // swap columns + for (var k = i; k < n + 1; k++) { + var t = matrix[k][i]; + matrix[k][i] = matrix[k][r]; + matrix[k][r] = t; + } + // reduce + for (var j = i + 1; j < n; j++) { + for (var k = n; k >= i; k--) { + matrix[k][j] -= (matrix[k][i] * matrix[i][j]) / matrix[i][i]; + } + } } - } - - for (j = n - 1; j >= 0; --j) { - t = 0; - - for (k = j + 1; k < n; ++k) { - t += matrix[k][j] * coef[k]; + for (var j = n - 1; j >= 0; j--) { + var t = 0; + for (var k = j + 1; k < n; k++) { + t += matrix[k][j] * coef[k]; + } + coef[j] = (matrix[n][j] - t) / matrix[j][j]; } - - coef[j] = (matrix[n][j] - t) / matrix[j][j]; - } - - return coef; + return coef; } -function power () { - var x = function x(d) { - return d[0]; - }, - y = function y(d) { - return d[1]; - }, - domain; - - function power(data) { - var n = 0, - X = 0, - Y = 0, - XY = 0, - X2 = 0, - YS = 0, - xmin = domain ? +domain[0] : Infinity, - xmax = domain ? +domain[1] : -Infinity; - visitPoints(data, x, y, function (dx, dy) { - var lx = Math.log(dx), - ly = Math.log(dy); - ++n; - X += (lx - X) / n; - Y += (ly - Y) / n; - XY += (lx * ly - XY) / n; - X2 += (lx * lx - X2) / n; - YS += (dy - YS) / n; - - if (!domain) { - if (dx < xmin) xmin = dx; - if (dx > xmax) xmax = dx; - } - }); - - var _ols = ols(X, Y, XY, X2), - _ols2 = _slicedToArray(_ols, 2), - a = _ols2[0], - b = _ols2[1]; - - a = Math.exp(a); - - var fn = function fn(x) { - return a * Math.pow(x, b); - }, - out = interpose(xmin, xmax, fn); - - out.a = a; - out.b = b; - out.predict = fn; - out.rSquared = determination(data, x, y, YS, fn); - return out; - } - - power.domain = function (arr) { - return arguments.length ? (domain = arr, power) : domain; - }; - - power.x = function (fn) { - return arguments.length ? (x = fn, power) : x; - }; - - power.y = function (fn) { - return arguments.length ? (y = fn, power) : y; - }; - - return power; +function power() { + var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, domain; + var powerRegression = function powerRegression(data) { + var n = 0, X = 0, Y = 0, XY = 0, X2 = 0, YS = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; + visitPoints(data, x, y, function (dx, dy) { + var lx = Math.log(dx), ly = Math.log(dy); + ++n; + X += (lx - X) / n; + Y += (ly - Y) / n; + XY += (lx * ly - XY) / n; + X2 += (lx * lx - X2) / n; + YS += (dy - YS) / n; + if (!domain) { + if (dx < xmin) + xmin = dx; + if (dx > xmax) + xmax = dx; + } + }); + var _a = ols(X, Y, XY, X2), a = _a[0], b = _a[1]; + a = Math.exp(a); + var fn = function (xx) { return a * Math.pow(xx, b); }; + var out = interpose(xmin, xmax, fn); + out.a = a; + out.b = b; + out.predict = fn; + out.rSquared = determination(data, x, y, YS, fn); + return out; + }; + powerRegression.domain = function (arr) { + if (!arguments.length) + return domain; + domain = arr; + return powerRegression; + }; + powerRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return powerRegression; + }; + powerRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return powerRegression; + }; + return powerRegression; } -export { exponential as regressionExp, linear as regressionLinear, loess as regressionLoess, logarithmic as regressionLog, polynomial as regressionPoly, power as regressionPow, quad as regressionQuad }; +export { exponential as regressionExp, linear as regressionLinear, loess as regressionLoess, logarithmic as regressionLog, polynomial as regressionPoly, power as regressionPow, quadratic as regressionQuad }; diff --git a/dist/d3-regression.js b/dist/d3-regression.js index 6437bff..600764d 100644 --- a/dist/d3-regression.js +++ b/dist/d3-regression.js @@ -1,875 +1,678 @@ -// https://github.com/HarryStevens/d3-regression#readme Version 1.3.10. Copyright 2022 Harry Stevens. +// https://github.com/HarryStevens/d3-regression#readme Version 1.3.10. Copyright 2025 Harry Stevens. (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (global = global || self, factory(global.d3 = {})); }(this, (function (exports) { 'use strict'; - function _slicedToArray(arr, i) { - return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); - } - - function _arrayWithHoles(arr) { - if (Array.isArray(arr)) return arr; - } - - function _iterableToArrayLimit(arr, i) { - var _arr = []; - var _n = true; - var _d = false; - var _e = undefined; - - try { - for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { - _arr.push(_s.value); - - if (i && _arr.length === i) break; - } - } catch (err) { - _d = true; - _e = err; - } finally { - try { - if (!_n && _i["return"] != null) _i["return"](); - } finally { - if (_d) throw _e; - } - } - - return _arr; - } - - function _nonIterableRest() { - throw new TypeError("Invalid attempt to destructure non-iterable instance"); - } - - // Adapted from vega-statistics by Jeffrey Heer - // License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE - // Source: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/packages/vega-statistics/src/regression/points.js + /** + * Adapted from vega-statistics by Jeffrey Heer + * License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE + * Source: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/packages/vega-statistics/src/regression/points.js + */ function points(data, x, y, sort) { - data = data.filter(function (d, i) { - var u = x(d, i), - v = y(d, i); - return u != null && isFinite(u) && v != null && isFinite(v); - }); - - if (sort) { - data.sort(function (a, b) { - return x(a) - x(b); + data = data.filter(function (d, i) { + var u = x(d, i), v = y(d, i); + return u != null && isFinite(u) && v != null && isFinite(v); }); - } - - var n = data.length, - X = new Float64Array(n), - Y = new Float64Array(n); // extract values, calculate means - - var ux = 0, - uy = 0, - xv, - yv, - d; - - for (var i = 0; i < n;) { - d = data[i]; - X[i] = xv = +x(d, i, data); - Y[i] = yv = +y(d, i, data); - ++i; - ux += (xv - ux) / i; - uy += (yv - uy) / i; - } // mean center the data - - - for (var _i = 0; _i < n; ++_i) { - X[_i] -= ux; - Y[_i] -= uy; - } - - return [X, Y, ux, uy]; + if (sort) { + data.sort(function (a, b) { return x(a) - x(b); }); + } + var n = data.length, X = new Float64Array(n), Y = new Float64Array(n); + // extract values, calculate means + var ux = 0, uy = 0, xv, yv, d; + for (var i = 0; i < n;) { + d = data[i]; + X[i] = xv = +x(d, i, data); + Y[i] = yv = +y(d, i, data); + ++i; + ux += (xv - ux) / i; + uy += (yv - uy) / i; + } + // mean center the data + for (var i = 0; i < n; ++i) { + X[i] -= ux; + Y[i] -= uy; + } + return [X, Y, ux, uy]; } + /** + * Iterates over valid data points, invoking a callback for each. + */ function visitPoints(data, x, y, cb) { - var iterations = 0; - - for (var i = 0, n = data.length; i < n; i++) { - var d = data[i], - dx = +x(d, i, data), - dy = +y(d, i, data); - - if (dx != null && isFinite(dx) && dy != null && isFinite(dy)) { - cb(dx, dy, iterations++); + var iterations = 0; + for (var i = 0; i < data.length; i++) { + var d = data[i]; + var dx = +x(d, i, data); + var dy = +y(d, i, data); + if (dx != null && isFinite(dx) && dy != null && isFinite(dy)) { + cb(dx, dy, iterations++); + } } - } } - // return the coefficient of determination, or R squared. - + /** + * Given a dataset, x- and y-accessors, the mean center of the y-values (uY), + * and a prediction function, return the coefficient of determination, R^2. + */ function determination(data, x, y, uY, predict) { - var SSE = 0, - SST = 0; - visitPoints(data, x, y, function (dx, dy) { - var sse = dy - predict(dx), - sst = dy - uY; - SSE += sse * sse; - SST += sst * sst; - }); - return 1 - SSE / SST; + var SSE = 0, // Sum of Squared Errors + SST = 0; // Total Sum of Squares + visitPoints(data, x, y, function (dx, dy) { + var sse = dy - predict(dx); + var sst = dy - uY; + SSE += sse * sse; + SST += sst * sst; + }); + return 1 - SSE / SST; } - // Returns the angle of a line in degrees. + /** + * Returns the angle of a line in degrees. + */ function angle(line) { - return Math.atan2(line[1][1] - line[0][1], line[1][0] - line[0][0]) * 180 / Math.PI; - } // Returns the midpoint of a line. - + return (Math.atan2(line[1][1] - line[0][1], line[1][0] - line[0][0]) * + (180 / Math.PI)); + } + /** + * Returns the midpoint of a line. + */ function midpoint(line) { - return [(line[0][0] + line[1][0]) / 2, (line[0][1] + line[1][1]) / 2]; + return [ + (line[0][0] + line[1][0]) / 2, + (line[0][1] + line[1][1]) / 2 + ]; } - // returns a smooth line. - + /** + * Given a start point (xmin), an end point (xmax), + * and a prediction function, returns a smooth line. + */ function interpose(xmin, xmax, predict) { - var l = Math.log(xmax - xmin) * Math.LOG10E + 1 | 0; - var precision = 1 * Math.pow(10, -l / 2 - 1), - maxIter = 1e4; - var points = [px(xmin), px(xmax)], - iter = 0; - - while (find(points) && iter < maxIter) { - } - - return points; - - function px(x) { - return [x, predict(x)]; - } - - function find(points) { - iter++; - var n = points.length; - var found = false; - - for (var i = 0; i < n - 1; i++) { - var p0 = points[i], - p1 = points[i + 1], - m = midpoint([p0, p1]), - mp = px(m[0]), - a0 = angle([p0, m]), - a1 = angle([p0, mp]), - a = Math.abs(a0 - a1); - - if (a > precision) { - points.splice(i + 1, 0, mp); - found = true; - } + var l = (Math.log(xmax - xmin) * Math.LOG10E + 1) | 0; + var precision = Math.pow(10, -l / 2 - 1); + var maxIter = 1e4; + var points = [px(xmin), px(xmax)]; + var iter = 0; + while (find(points) && iter < maxIter) + ; + return points; + function px(x) { + return [x, predict(x)]; + } + function find(points) { + iter++; + var n = points.length; + var found = false; + for (var i = 0; i < n - 1; i++) { + var p0 = points[i]; + var p1 = points[i + 1]; + var m = midpoint([p0, p1]); + var mp = px(m[0]); + var a0 = angle([p0, m]); + var a1 = angle([p0, mp]); + var a = Math.abs(a0 - a1); + if (a > precision) { + points.splice(i + 1, 0, mp); + found = true; + } + } + return found; } - - return found; - } } - // Ordinary Least Squares from vega-statistics by Jeffrey Heer - // License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE - // Source: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/packages/vega-statistics/src/regression/ols.js + /** + * Ordinary Least Squares from vega-statistics by Jeffrey Heer + * License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE + * Source: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/packages/vega-statistics/src/regression/ols.js + */ function ols(uX, uY, uXY, uX2) { - var delta = uX2 - uX * uX, - slope = Math.abs(delta) < 1e-24 ? 0 : (uXY - uX * uY) / delta, - intercept = uY - slope * uX; - return [intercept, slope]; + var delta = uX2 - uX * uX, slope = Math.abs(delta) < 1e-24 ? 0 : (uXY - uX * uY) / delta, intercept = uY - slope * uX; + return [intercept, slope]; } - function exponential () { - var x = function x(d) { - return d[0]; - }, - y = function y(d) { - return d[1]; - }, - domain; - - function exponential(data) { - var n = 0, - Y = 0, - YL = 0, - XY = 0, - XYL = 0, - X2Y = 0, - xmin = domain ? +domain[0] : Infinity, - xmax = domain ? +domain[1] : -Infinity; - visitPoints(data, x, y, function (dx, dy) { - var ly = Math.log(dy), - xy = dx * dy; - ++n; - Y += (dy - Y) / n; - XY += (xy - XY) / n; - X2Y += (dx * xy - X2Y) / n; - YL += (dy * ly - YL) / n; - XYL += (xy * ly - XYL) / n; - - if (!domain) { - if (dx < xmin) xmin = dx; - if (dx > xmax) xmax = dx; - } - }); - - var _ols = ols(XY / Y, YL / Y, XYL / Y, X2Y / Y), - _ols2 = _slicedToArray(_ols, 2), - a = _ols2[0], - b = _ols2[1]; - - a = Math.exp(a); - - var fn = function fn(x) { - return a * Math.exp(b * x); - }, - out = interpose(xmin, xmax, fn); - - out.a = a; - out.b = b; - out.predict = fn; - out.rSquared = determination(data, x, y, Y, fn); - return out; - } - - exponential.domain = function (arr) { - return arguments.length ? (domain = arr, exponential) : domain; - }; - - exponential.x = function (fn) { - return arguments.length ? (x = fn, exponential) : x; - }; - - exponential.y = function (fn) { - return arguments.length ? (y = fn, exponential) : y; - }; - - return exponential; + function exponential() { + var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, domain; + var exponentialRegression = function (data) { + var n = 0, Y = 0, YL = 0, XY = 0, XYL = 0, X2Y = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; + visitPoints(data, x, y, function (dx, dy) { + var ly = Math.log(dy), xy = dx * dy; + ++n; + Y += (dy - Y) / n; + XY += (xy - XY) / n; + X2Y += (dx * xy - X2Y) / n; + YL += (dy * ly - YL) / n; + XYL += (xy * ly - XYL) / n; + if (!domain) { + if (dx < xmin) + xmin = dx; + if (dx > xmax) + xmax = dx; + } + }); + var _a = ols(XY / Y, YL / Y, XYL / Y, X2Y / Y), a = _a[0], b = _a[1]; + a = Math.exp(a); + var fn = function (xx) { return a * Math.exp(b * xx); }; + var out = interpose(xmin, xmax, fn); + out.a = a; + out.b = b; + out.predict = fn; + out.rSquared = determination(data, x, y, Y, fn); + return out; + }; + exponentialRegression.domain = function (arr) { + if (!arguments.length) + return domain; + domain = arr; + return exponentialRegression; + }; + exponentialRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return exponentialRegression; + }; + exponentialRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return exponentialRegression; + }; + return exponentialRegression; } - function linear () { - var x = function x(d) { - return d[0]; - }, - y = function y(d) { - return d[1]; - }, - domain; - - function linear(data) { - var n = 0, - X = 0, - // sum of x - Y = 0, - // sum of y - XY = 0, - // sum of x * y - X2 = 0, - // sum of x * x - xmin = domain ? +domain[0] : Infinity, - xmax = domain ? +domain[1] : -Infinity; - visitPoints(data, x, y, function (dx, dy) { - ++n; - X += (dx - X) / n; - Y += (dy - Y) / n; - XY += (dx * dy - XY) / n; - X2 += (dx * dx - X2) / n; - - if (!domain) { - if (dx < xmin) xmin = dx; - if (dx > xmax) xmax = dx; - } - }); - - var _ols = ols(X, Y, XY, X2), - _ols2 = _slicedToArray(_ols, 2), - intercept = _ols2[0], - slope = _ols2[1], - fn = function fn(x) { - return slope * x + intercept; - }, - out = [[xmin, fn(xmin)], [xmax, fn(xmax)]]; - - out.a = slope; - out.b = intercept; - out.predict = fn; - out.rSquared = determination(data, x, y, Y, fn); - return out; - } - - linear.domain = function (arr) { - return arguments.length ? (domain = arr, linear) : domain; - }; - - linear.x = function (fn) { - return arguments.length ? (x = fn, linear) : x; - }; - - linear.y = function (fn) { - return arguments.length ? (y = fn, linear) : y; - }; - - return linear; + function linear() { + var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, domain; + var linearRegression = function (data) { + var n = 0, X = 0, // sum of x + Y = 0, // sum of y + XY = 0, // sum of x*y + X2 = 0, // sum of x*x + xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; + visitPoints(data, x, y, function (dx, dy) { + ++n; + X += (dx - X) / n; + Y += (dy - Y) / n; + XY += (dx * dy - XY) / n; + X2 += (dx * dx - X2) / n; + if (!domain) { + if (dx < xmin) + xmin = dx; + if (dx > xmax) + xmax = dx; + } + }); + var _a = ols(X, Y, XY, X2), intercept = _a[0], slope = _a[1]; + var fn = function (xx) { return slope * xx + intercept; }; + var out = [[xmin, fn(xmin)], [xmax, fn(xmax)]]; + out.a = slope; + out.b = intercept; + out.predict = fn; + out.rSquared = determination(data, x, y, Y, fn); + return out; + }; + linearRegression.domain = function (arr) { + if (!arguments.length) + return domain; + domain = arr; + return linearRegression; + }; + linearRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return linearRegression; + }; + linearRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return linearRegression; + }; + return linearRegression; } - // Returns the medium value of an array of numbers. + /** + * Returns the median value of an array of numbers. + */ function median(arr) { - arr.sort(function (a, b) { - return a - b; - }); - var i = arr.length / 2; - return i % 1 === 0 ? (arr[i - 1] + arr[i]) / 2 : arr[Math.floor(i)]; + arr.sort(function (a, b) { return a - b; }); + var i = arr.length / 2; + return i % 1 === 0 ? (arr[i - 1] + arr[i]) / 2 : arr[Math.floor(i)]; } - var maxiters = 2, - epsilon = 1e-12; - function loess () { - var x = function x(d) { - return d[0]; - }, - y = function y(d) { - return d[1]; - }, - bandwidth = .3; - - function loess(data) { - var _points = points(data, x, y, true), - _points2 = _slicedToArray(_points, 4), - xv = _points2[0], - yv = _points2[1], - ux = _points2[2], - uy = _points2[3], - n = xv.length, - bw = Math.max(2, ~~(bandwidth * n)), - yhat = new Float64Array(n), - residuals = new Float64Array(n), - robustWeights = new Float64Array(n).fill(1); - - for (var iter = -1; ++iter <= maxiters;) { - var interval = [0, bw - 1]; - - for (var i = 0; i < n; ++i) { - var dx = xv[i], - i0 = interval[0], - i1 = interval[1], - edge = dx - xv[i0] > xv[i1] - dx ? i0 : i1; - var W = 0, - X = 0, - Y = 0, - XY = 0, - X2 = 0, - denom = 1 / Math.abs(xv[edge] - dx || 1); // Avoid singularity - - for (var k = i0; k <= i1; ++k) { - var xk = xv[k], - yk = yv[k], - w = tricube(Math.abs(dx - xk) * denom) * robustWeights[k], - xkw = xk * w; - W += w; - X += xkw; - Y += yk * w; - XY += yk * xkw; - X2 += xk * xkw; - } // Linear regression fit - - - var _ols = ols(X / W, Y / W, XY / W, X2 / W), - _ols2 = _slicedToArray(_ols, 2), - a = _ols2[0], - b = _ols2[1]; - - yhat[i] = a + b * dx; - residuals[i] = Math.abs(yv[i] - yhat[i]); - updateInterval(xv, i + 1, interval); - } - - if (iter === maxiters) { - break; - } - - var medianResidual = median(residuals); - if (Math.abs(medianResidual) < epsilon) break; - - for (var _i = 0, arg, _w; _i < n; ++_i) { - arg = residuals[_i] / (6 * medianResidual); // Default to epsilon (rather than zero) for large deviations - // Keeping weights tiny but non-zero prevents singularites - - robustWeights[_i] = arg >= 1 ? epsilon : (_w = 1 - arg * arg) * _w; - } - } - - return output(xv, yhat, ux, uy); - } - - loess.bandwidth = function (bw) { - return arguments.length ? (bandwidth = bw, loess) : bandwidth; - }; - - loess.x = function (fn) { - return arguments.length ? (x = fn, loess) : x; - }; - - loess.y = function (fn) { - return arguments.length ? (y = fn, loess) : y; - }; - - return loess; - } // Weighting kernel for local regression - + // Adapted from science.js by Jason Davies + var maxiters = 2, epsilon = 1e-12; + function loess() { + var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, bandwidth = .3; + var loessRegression = function loessRegression(data) { + var _a = points(data, x, y, true), xv = _a[0], yv = _a[1], ux = _a[2], uy = _a[3]; + var n = xv.length; + var bw = Math.max(2, ~~(bandwidth * n)); // # of nearest neighbors + var yhat = new Float64Array(n); + var residuals = new Float64Array(n); + var robustWeights = new Float64Array(n).fill(1); + for (var iter = -1; ++iter <= maxiters;) { + var interval = [0, bw - 1]; + for (var i = 0; i < n; ++i) { + var dx = xv[i]; + var i0 = interval[0]; + var i1 = interval[1]; + var edge = (dx - xv[i0]) > (xv[i1] - dx) ? i0 : i1; + var W = 0, X = 0, Y = 0, XY = 0, X2 = 0; + var denom = 1 / Math.abs(xv[edge] - dx || 1); + for (var k = i0; k <= i1; ++k) { + var xk = xv[k]; + var yk = yv[k]; + var w = tricube(Math.abs(dx - xk) * denom) * robustWeights[k]; + var xkw = xk * w; + W += w; + X += xkw; + Y += yk * w; + XY += yk * xkw; + X2 += xk * xkw; + } + // Linear regression fit + var _b = ols(X / W, Y / W, XY / W, X2 / W), a = _b[0], b = _b[1]; + yhat[i] = a + b * dx; + residuals[i] = Math.abs(yv[i] - yhat[i]); + updateInterval(xv, i + 1, interval); + } + if (iter === maxiters) { + break; + } + var medianResidual = median(residuals); + if (Math.abs(medianResidual) < epsilon) + break; + for (var i = 0, arg = void 0, w = void 0; i < n; ++i) { + arg = residuals[i] / (6 * medianResidual); + // Default to epsilon (rather than zero) for large deviations + // Keeping weights tiny but non-zero prevents singularites + robustWeights[i] = (arg >= 1) ? epsilon : ((w = 1 - arg * arg) * w); + } + } + return output(xv, yhat, ux, uy); + }; + loessRegression.bandwidth = function (bw) { + if (!arguments.length) + return bandwidth; + bandwidth = bw; + return loessRegression; + }; + loessRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return loessRegression; + }; + loessRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return loessRegression; + }; + return loessRegression; + } + // Weighting kernel for local regression function tricube(x) { - return (x = 1 - x * x * x) * x * x; - } // Advance sliding window interval of nearest neighbors - - + return (x = 1 - x * x * x) * x * x; + } + // Advance sliding window interval of nearest neighbors function updateInterval(xv, i, interval) { - var val = xv[i], - left = interval[0], - right = interval[1] + 1; - if (right >= xv.length) return; // Step right if distance to new right edge is <= distance to old left edge - // Step when distance is equal to ensure movement over duplicate x values - - while (i > left && xv[right] - val <= val - xv[left]) { - interval[0] = ++left; - interval[1] = right; - ++right; - } - } // Generate smoothed output points + var val = xv[i], left = interval[0], right = interval[1] + 1; + if (right >= xv.length) + return; + // Step right if distance to new right edge is <= distance to old left edge + // Step when distance is equal to ensure movement over duplicate x values + while (i > left && (xv[right] - val) <= (val - xv[left])) { + interval[0] = ++left; + interval[1] = right; + ++right; + } + } + // Generate smoothed output points // Average points with repeated x values - - function output(xv, yhat, ux, uy) { - var n = xv.length, - out = []; - var i = 0, - cnt = 0, - prev = [], - v; - - for (; i < n; ++i) { - v = xv[i] + ux; - - if (prev[0] === v) { - // Average output values via online update - prev[1] += (yhat[i] - prev[1]) / ++cnt; - } else { - // Add new output point - cnt = 0; - prev[1] += uy; - prev = [v, yhat[i]]; - out.push(prev); + var n = xv.length, out = []; + var i = 0, cnt = 0, prev = [], v; + for (; i < n; ++i) { + v = xv[i] + ux; + if (prev[0] === v) { + // Average output values via online update + prev[1] += (yhat[i] - prev[1]) / (++cnt); + } + else { + // Add new output point + cnt = 0; + prev[1] += uy; + prev = [v, yhat[i]]; + out.push(prev); + } } - } - - prev[1] += uy; - return out; - } - - function logarithmic () { - var x = function x(d) { - return d[0]; - }, - y = function y(d) { - return d[1]; - }, - base = Math.E, - domain; - - function logarithmic(data) { - var n = 0, - X = 0, - Y = 0, - XY = 0, - X2 = 0, - xmin = domain ? +domain[0] : Infinity, - xmax = domain ? +domain[1] : -Infinity, - lb = Math.log(base); - visitPoints(data, x, y, function (dx, dy) { - var lx = Math.log(dx) / lb; - ++n; - X += (lx - X) / n; - Y += (dy - Y) / n; - XY += (lx * dy - XY) / n; - X2 += (lx * lx - X2) / n; - - if (!domain) { - if (dx < xmin) xmin = dx; - if (dx > xmax) xmax = dx; - } - }); - - var _ols = ols(X, Y, XY, X2), - _ols2 = _slicedToArray(_ols, 2), - intercept = _ols2[0], - slope = _ols2[1], - fn = function fn(x) { - return slope * Math.log(x) / lb + intercept; - }, - out = interpose(xmin, xmax, fn); - - out.a = slope; - out.b = intercept; - out.predict = fn; - out.rSquared = determination(data, x, y, Y, fn); + prev[1] += uy; return out; - } - - logarithmic.domain = function (arr) { - return arguments.length ? (domain = arr, logarithmic) : domain; - }; - - logarithmic.x = function (fn) { - return arguments.length ? (x = fn, logarithmic) : x; - }; - - logarithmic.y = function (fn) { - return arguments.length ? (y = fn, logarithmic) : y; - }; - - logarithmic.base = function (n) { - return arguments.length ? (base = n, logarithmic) : base; - }; - - return logarithmic; } - function quad () { - var x = function x(d) { - return d[0]; - }, - y = function y(d) { - return d[1]; - }, - domain; - - function quadratic(data) { - var _points = points(data, x, y), - _points2 = _slicedToArray(_points, 4), - xv = _points2[0], - yv = _points2[1], - ux = _points2[2], - uy = _points2[3], - n = xv.length; - - var X2 = 0, - X3 = 0, - X4 = 0, - XY = 0, - X2Y = 0, - i, - dx, - dy, - x2; - - for (i = 0; i < n;) { - dx = xv[i]; - dy = yv[i++]; - x2 = dx * dx; - X2 += (x2 - X2) / i; - X3 += (x2 * dx - X3) / i; - X4 += (x2 * x2 - X4) / i; - XY += (dx * dy - XY) / i; - X2Y += (x2 * dy - X2Y) / i; - } - - var Y = 0, - n0 = 0, - xmin = domain ? +domain[0] : Infinity, - xmax = domain ? +domain[1] : -Infinity; - visitPoints(data, x, y, function (dx, dy) { - n0++; - Y += (dy - Y) / n0; - - if (!domain) { - if (dx < xmin) xmin = dx; - if (dx > xmax) xmax = dx; - } - }); - - var X2X2 = X4 - X2 * X2, - d = X2 * X2X2 - X3 * X3, - a = (X2Y * X2 - XY * X3) / d, - b = (XY * X2X2 - X2Y * X3) / d, - c = -a * X2, - fn = function fn(x) { - x = x - ux; - return a * x * x + b * x + c + uy; + function logarithmic() { + var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, base = Math.E, domain; + var logarithmicRegression = function logarithmicRegression(data) { + var n = 0, X = 0, Y = 0, XY = 0, X2 = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity, lb = Math.log(base); + visitPoints(data, x, y, function (dx, dy) { + var lx = Math.log(dx) / lb; + ++n; + X += (lx - X) / n; + Y += (dy - Y) / n; + XY += (lx * dy - XY) / n; + X2 += (lx * lx - X2) / n; + if (!domain) { + if (dx < xmin) + xmin = dx; + if (dx > xmax) + xmax = dx; + } + }); + var _a = ols(X, Y, XY, X2), intercept = _a[0], slope = _a[1]; + var fn = function (xx) { return slope * Math.log(xx) / lb + intercept; }; + var out = interpose(xmin, xmax, fn); + out.a = slope; + out.b = intercept; + out.predict = fn; + out.rSquared = determination(data, x, y, Y, fn); + return out; }; - - var out = interpose(xmin, xmax, fn); - out.a = a; - out.b = b - 2 * a * ux; - out.c = c - b * ux + a * ux * ux + uy; - out.predict = fn; - out.rSquared = determination(data, x, y, Y, fn); - return out; - } - - quadratic.domain = function (arr) { - return arguments.length ? (domain = arr, quadratic) : domain; - }; - - quadratic.x = function (fn) { - return arguments.length ? (x = fn, quadratic) : x; - }; - - quadratic.y = function (fn) { - return arguments.length ? (y = fn, quadratic) : y; - }; - - return quadratic; + logarithmicRegression.domain = function (arr) { + if (!arguments.length) + return domain; + domain = arr; + return logarithmicRegression; + }; + logarithmicRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return logarithmicRegression; + }; + logarithmicRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return logarithmicRegression; + }; + logarithmicRegression.base = function (b) { + if (!arguments.length) + return base; + base = b; + return logarithmicRegression; + }; + return logarithmicRegression; } - // Source: https://github.com/Tom-Alexander/regression-js/blob/master/src/regression.js#L246 - // License: https://github.com/Tom-Alexander/regression-js/blob/master/LICENSE - // ...with ideas from vega-statistics by Jeffrey Heer - // Source: https://github.com/vega/vega/blob/f21cb8792b4e0cbe2b1a3fd44b0f5db370dbaadb/packages/vega-statistics/src/regression/poly.js - // License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE - - function polynomial () { - var x = function x(d) { - return d[0]; - }, - y = function y(d) { - return d[1]; - }, - order = 3, - domain; - - function polynomial(data) { - // Use more efficient methods for lower orders - if (order === 1) { - var o = linear().x(x).y(y).domain(domain)(data); - o.coefficients = [o.b, o.a]; - delete o.a; - delete o.b; - return o; - } - - if (order === 2) { - var _o = quad().x(x).y(y).domain(domain)(data); - - _o.coefficients = [_o.c, _o.b, _o.a]; - delete _o.a; - delete _o.b; - delete _o.c; - return _o; - } - - var _points = points(data, x, y), - _points2 = _slicedToArray(_points, 4), - xv = _points2[0], - yv = _points2[1], - ux = _points2[2], - uy = _points2[3], - n = xv.length, - lhs = [], - rhs = [], - k = order + 1; - - var Y = 0, - n0 = 0, - xmin = domain ? +domain[0] : Infinity, - xmax = domain ? +domain[1] : -Infinity; - visitPoints(data, x, y, function (dx, dy) { - ++n0; - Y += (dy - Y) / n0; - - if (!domain) { - if (dx < xmin) xmin = dx; - if (dx > xmax) xmax = dx; - } - }); - var i, j, l, v, c; - - for (i = 0; i < k; ++i) { - for (l = 0, v = 0; l < n; ++l) { - v += Math.pow(xv[l], i) * yv[l]; - } - - lhs.push(v); - c = new Float64Array(k); - - for (j = 0; j < k; ++j) { - for (l = 0, v = 0; l < n; ++l) { - v += Math.pow(xv[l], i + j); + function quadratic() { + var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, domain; + var quadraticRegression = function quadraticRegression(data) { + var _a = points(data, x, y), xv = _a[0], yv = _a[1], ux = _a[2], uy = _a[3]; + var n = xv.length; + var X2 = 0, X3 = 0, X4 = 0, XY = 0, X2Y = 0, i, dx, dy, x2; + for (i = 0; i < n;) { + dx = xv[i]; + dy = yv[i++]; + x2 = dx * dx; + X2 += (x2 - X2) / i; + X3 += ((x2 * dx) - X3) / i; + X4 += ((x2 * x2) - X4) / i; + XY += ((dx * dy) - XY) / i; + X2Y += ((x2 * dy) - X2Y) / i; } - - c[j] = v; - } - - rhs.push(c); - } - - rhs.push(lhs); - - var coef = gaussianElimination(rhs), - fn = function fn(x) { - x -= ux; - var y = uy + coef[0] + coef[1] * x + coef[2] * x * x; - - for (i = 3; i < k; ++i) { - y += coef[i] * Math.pow(x, i); - } - - return y; - }, - out = interpose(xmin, xmax, fn); - - out.coefficients = uncenter(k, coef, -ux, uy); - out.predict = fn; - out.rSquared = determination(data, x, y, Y, fn); - return out; - } - - polynomial.domain = function (arr) { - return arguments.length ? (domain = arr, polynomial) : domain; - }; - - polynomial.x = function (fn) { - return arguments.length ? (x = fn, polynomial) : x; - }; - - polynomial.y = function (fn) { - return arguments.length ? (y = fn, polynomial) : y; - }; - - polynomial.order = function (n) { - return arguments.length ? (order = n, polynomial) : order; - }; - - return polynomial; + var Y = 0, n0 = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; + visitPoints(data, x, y, function (dx2, dy2) { + n0++; + Y += (dy2 - Y) / n0; + if (!domain) { + if (dx2 < xmin) + xmin = dx2; + if (dx2 > xmax) + xmax = dx2; + } + }); + var X2X2 = X4 - (X2 * X2); + var d = (X2 * X2X2 - X3 * X3); + var a = (X2Y * X2 - XY * X3) / d; + var b = (XY * X2X2 - X2Y * X3) / d; + var c = -a * X2; + var fn = function (xx) { + var shifted = xx - ux; + return a * shifted * shifted + b * shifted + c + uy; + }; + var out = interpose(xmin, xmax, fn); + out.a = a; + out.b = b - 2 * a * ux; + out.c = c - b * ux + a * ux * ux + uy; + out.predict = fn; + out.rSquared = determination(data, x, y, Y, fn); + return out; + }; + quadraticRegression.domain = function (arr) { + if (!arguments.length) + return domain; + domain = arr; + return quadraticRegression; + }; + quadraticRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return quadraticRegression; + }; + quadraticRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return quadraticRegression; + }; + return quadraticRegression; } + function polynomial() { + var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, order = 3, domain; + var polynomialRegression = function polynomialRegression(data) { + // Shortcut for lower-order polynomials: + if (order === 1) { + var o = linear().x(x).y(y).domain(domain)(data); + var result = [ + o[0], + o[1], + ]; + result.coefficients = [o.b, o.a]; + result.predict = o.predict; + result.rSquared = o.rSquared; + return result; + } + if (order === 2) { + var o = quadratic().x(x).y(y).domain(domain)(data); + var result = [ + o[0], + o[1], + ]; + result.coefficients = [o.c, o.b, o.a]; + result.predict = o.predict; + result.rSquared = o.rSquared; + return result; + } + var _a = points(data, x, y), xv = _a[0], yv = _a[1], ux = _a[2], uy = _a[3]; + var n = xv.length; + var k = order + 1; + var lhs = []; + var rhs = []; + var Y = 0, n0 = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; + visitPoints(data, x, y, function (dx, dy) { + n0++; + Y += (dy - Y) / n0; + if (!domain) { + if (dx < xmin) + xmin = dx; + if (dx > xmax) + xmax = dx; + } + }); + // Build normal equations + for (var i = 0; i < k; i++) { + // LHS + var v = 0; + for (var l = 0; l < n; l++) { + v += Math.pow(xv[l], i) * yv[l]; + } + lhs.push(v); + // RHS + var c = new Float64Array(k); + for (var j = 0; j < k; j++) { + var v2 = 0; + for (var l = 0; l < n; l++) { + v2 += Math.pow(xv[l], i + j); + } + c[j] = v2; + } + rhs.push(c); + } + rhs.push(new Float64Array(lhs)); + var coef = gaussianElimination(rhs); + var fn = function (xx) { + var shifted = xx - ux; + var val = uy + coef[0]; + for (var i = 1; i < k; i++) { + val += coef[i] * Math.pow(shifted, i); + } + return val; + }; + var out = interpose(xmin, xmax, fn); + out.coefficients = uncenter(k, coef, -ux, uy); + out.predict = fn; + out.rSquared = determination(data, x, y, Y, fn); + return out; + }; + polynomialRegression.domain = function (arr) { + if (!arguments.length) + return domain; + domain = arr; + return polynomialRegression; + }; + polynomialRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return polynomialRegression; + }; + polynomialRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return polynomialRegression; + }; + polynomialRegression.order = function (n) { + if (!arguments.length) + return order; + order = n; + return polynomialRegression; + }; + return polynomialRegression; + } function uncenter(k, a, x, y) { - var z = Array(k); - var i, j, v, c; // initialize to zero - - for (i = 0; i < k; ++i) { - z[i] = 0; - } // polynomial expansion - - - for (i = k - 1; i >= 0; --i) { - v = a[i]; - c = 1; - z[i] += v; - - for (j = 1; j <= i; ++j) { - c *= (i + 1 - j) / j; // binomial coefficent - - z[i - j] += v * Math.pow(x, j) * c; + var z = new Array(k).fill(0); + for (var i = k - 1; i >= 0; --i) { + var v = a[i]; + z[i] += v; + var c = 1; + for (var j = 1; j <= i; ++j) { + c *= (i + 1 - j) / j; // binomial coefficient + z[i - j] += v * Math.pow(x, j) * c; + } } - } // bias term - - - z[0] += y; - return z; - } // Given an array for a two-dimensional matrix and the polynomial order, - // solve A * x = b using Gaussian elimination. - - + // bias term + z[0] += y; + return z; + } + // Solve A * x = b using Gaussian elimination function gaussianElimination(matrix) { - var n = matrix.length - 1, - coef = []; - var i, j, k, r, t; - - for (i = 0; i < n; ++i) { - r = i; // max row - - for (j = i + 1; j < n; ++j) { - if (Math.abs(matrix[i][j]) > Math.abs(matrix[i][r])) { - r = j; - } - } - - for (k = i; k < n + 1; ++k) { - t = matrix[k][i]; - matrix[k][i] = matrix[k][r]; - matrix[k][r] = t; - } - - for (j = i + 1; j < n; ++j) { - for (k = n; k >= i; k--) { - matrix[k][j] -= matrix[k][i] * matrix[i][j] / matrix[i][i]; - } + var n = matrix.length - 1; + var coef = new Array(n); + for (var i = 0; i < n; i++) { + var r = i; + // find pivot row + for (var j = i + 1; j < n; j++) { + if (Math.abs(matrix[i][j]) > Math.abs(matrix[i][r])) { + r = j; + } + } + // swap columns + for (var k = i; k < n + 1; k++) { + var t = matrix[k][i]; + matrix[k][i] = matrix[k][r]; + matrix[k][r] = t; + } + // reduce + for (var j = i + 1; j < n; j++) { + for (var k = n; k >= i; k--) { + matrix[k][j] -= (matrix[k][i] * matrix[i][j]) / matrix[i][i]; + } + } } - } - - for (j = n - 1; j >= 0; --j) { - t = 0; - - for (k = j + 1; k < n; ++k) { - t += matrix[k][j] * coef[k]; + for (var j = n - 1; j >= 0; j--) { + var t = 0; + for (var k = j + 1; k < n; k++) { + t += matrix[k][j] * coef[k]; + } + coef[j] = (matrix[n][j] - t) / matrix[j][j]; } - - coef[j] = (matrix[n][j] - t) / matrix[j][j]; - } - - return coef; + return coef; } - function power () { - var x = function x(d) { - return d[0]; - }, - y = function y(d) { - return d[1]; - }, - domain; - - function power(data) { - var n = 0, - X = 0, - Y = 0, - XY = 0, - X2 = 0, - YS = 0, - xmin = domain ? +domain[0] : Infinity, - xmax = domain ? +domain[1] : -Infinity; - visitPoints(data, x, y, function (dx, dy) { - var lx = Math.log(dx), - ly = Math.log(dy); - ++n; - X += (lx - X) / n; - Y += (ly - Y) / n; - XY += (lx * ly - XY) / n; - X2 += (lx * lx - X2) / n; - YS += (dy - YS) / n; - - if (!domain) { - if (dx < xmin) xmin = dx; - if (dx > xmax) xmax = dx; - } - }); - - var _ols = ols(X, Y, XY, X2), - _ols2 = _slicedToArray(_ols, 2), - a = _ols2[0], - b = _ols2[1]; - - a = Math.exp(a); - - var fn = function fn(x) { - return a * Math.pow(x, b); - }, - out = interpose(xmin, xmax, fn); - - out.a = a; - out.b = b; - out.predict = fn; - out.rSquared = determination(data, x, y, YS, fn); - return out; - } - - power.domain = function (arr) { - return arguments.length ? (domain = arr, power) : domain; - }; - - power.x = function (fn) { - return arguments.length ? (x = fn, power) : x; - }; - - power.y = function (fn) { - return arguments.length ? (y = fn, power) : y; - }; - - return power; + function power() { + var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, domain; + var powerRegression = function powerRegression(data) { + var n = 0, X = 0, Y = 0, XY = 0, X2 = 0, YS = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; + visitPoints(data, x, y, function (dx, dy) { + var lx = Math.log(dx), ly = Math.log(dy); + ++n; + X += (lx - X) / n; + Y += (ly - Y) / n; + XY += (lx * ly - XY) / n; + X2 += (lx * lx - X2) / n; + YS += (dy - YS) / n; + if (!domain) { + if (dx < xmin) + xmin = dx; + if (dx > xmax) + xmax = dx; + } + }); + var _a = ols(X, Y, XY, X2), a = _a[0], b = _a[1]; + a = Math.exp(a); + var fn = function (xx) { return a * Math.pow(xx, b); }; + var out = interpose(xmin, xmax, fn); + out.a = a; + out.b = b; + out.predict = fn; + out.rSquared = determination(data, x, y, YS, fn); + return out; + }; + powerRegression.domain = function (arr) { + if (!arguments.length) + return domain; + domain = arr; + return powerRegression; + }; + powerRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return powerRegression; + }; + powerRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return powerRegression; + }; + return powerRegression; } exports.regressionExp = exponential; @@ -878,7 +681,7 @@ exports.regressionLog = logarithmic; exports.regressionPoly = polynomial; exports.regressionPow = power; - exports.regressionQuad = quad; + exports.regressionQuad = quadratic; Object.defineProperty(exports, '__esModule', { value: true }); diff --git a/dist/d3-regression.min.js b/dist/d3-regression.min.js deleted file mode 100644 index 1a93fd8..0000000 --- a/dist/d3-regression.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(n,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports):"function"==typeof define&&define.amd?define(["exports"],r):(n=n||self,r(n.d3={}))}(this,function(n){"use strict";function r(n,r){return t(n)||e(n,r)||u()}function t(n){if(Array.isArray(n))return n}function e(n,r){var t=[],e=!0,u=!1,o=void 0;try{for(var i,a=n[Symbol.iterator]();!(e=(i=a.next()).done)&&(t.push(i.value),!r||t.length!==r);e=!0);}catch(n){u=!0,o=n}finally{try{e||null==a.return||a.return()}finally{if(u)throw o}}return t}function u(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}function o(n,r,t,e){n=n.filter(function(n,e){var u=r(n,e),o=t(n,e);return null!=u&&isFinite(u)&&null!=o&&isFinite(o)}),e&&n.sort(function(n,t){return r(n)-r(t)});for(var u,o,i,a=n.length,f=new Float64Array(a),c=new Float64Array(a),l=0,h=0,v=0;vo&&(n.splice(u+1,0,v),t=!0)}return t}(i)&&a<1e4;);return i}function h(n,r,t,e){var u=e-n*n,o=Math.abs(u)<1e-24?0:(t-n*r)/u;return[r-o*n,o]}function v(){function n(n){var o=0,f=0,c=0,v=0,s=0,g=0,d=t?+t[0]:1/0,p=t?+t[1]:-1/0;i(n,e,u,function(n,r){var e=Math.log(r),u=n*r;++o,f+=(r-f)/o,v+=(u-v)/o,g+=(n*u-g)/o,c+=(r*e-c)/o,s+=(u*e-s)/o,t||(np&&(p=n))});var M=h(v/f,c/f,s/f,g/f),y=r(M,2),b=y[0],x=y[1];b=Math.exp(b);var w=function(n){return b*Math.exp(x*n)},m=l(d,p,w);return m.a=b,m.b=x,m.predict=w,m.rSquared=a(n,e,u,f,w),m}var t,e=function(n){return n[0]},u=function(n){return n[1]};return n.domain=function(r){return arguments.length?(t=r,n):t},n.x=function(r){return arguments.length?(e=r,n):e},n.y=function(r){return arguments.length?(u=r,n):u},n}function s(){function n(n){var o=0,f=0,c=0,l=0,v=0,s=t?+t[0]:1/0,g=t?+t[1]:-1/0;i(n,e,u,function(n,r){++o,f+=(n-f)/o,c+=(r-c)/o,l+=(n*r-l)/o,v+=(n*n-v)/o,t||(ng&&(g=n))});var d=h(f,c,l,v),p=r(d,2),M=p[0],y=p[1],b=function(n){return y*n+M},x=[[s,b(s)],[g,b(g)]];return x.a=y,x.b=M,x.predict=b,x.rSquared=a(n,e,u,c,b),x}var t,e=function(n){return n[0]},u=function(n){return n[1]};return n.domain=function(r){return arguments.length?(t=r,n):t},n.x=function(r){return arguments.length?(e=r,n):e},n.y=function(r){return arguments.length?(u=r,n):u},n}function g(n){n.sort(function(n,r){return n-r});var r=n.length/2;return r%1==0?(n[r-1]+n[r])/2:n[Math.floor(r)]}function d(){function n(n){for(var i=o(n,t,e,!0),a=r(i,4),f=a[0],c=a[1],l=a[2],v=a[3],s=f.length,d=Math.max(2,~~(u*s)),b=new Float64Array(s),x=new Float64Array(s),w=new Float64Array(s).fill(1),m=-1;++m<=S;){for(var F=[0,d-1],A=0;Af[P]-E?L:P,k=0,I=0,O=0,_=0,G=0,Q=1/Math.abs(f[j]-E||1),T=L;T<=P;++T){var z=f[T],B=c[T],C=p(Math.abs(E-z)*Q)*w[T],D=z*C;k+=C,I+=D,O+=B*C,_+=B*D,G+=z*D}var H=h(I/k,O/k,_/k,G/k),J=r(H,2),K=J[0],N=J[1];b[A]=K+N*E,x[A]=Math.abs(c[A]-b[A]),M(f,A+1,F)}if(m===S)break;var R=g(x);if(Math.abs(R)=1?q:(V=1-U*U)*V}return y(f,b,l,v)}var t=function(n){return n[0]},e=function(n){return n[1]},u=.3;return n.bandwidth=function(r){return arguments.length?(u=r,n):u},n.x=function(r){return arguments.length?(t=r,n):t},n.y=function(r){return arguments.length?(e=r,n):e},n}function p(n){return(n=1-n*n*n)*n*n}function M(n,r,t){var e=n[r],u=t[0],o=t[1]+1;if(!(o>=n.length))for(;r>u&&n[o]-e<=e-n[u];)t[0]=++u,t[1]=o,++o}function y(n,r,t,e){for(var u,o=n.length,i=[],a=0,f=0,c=[];ap&&(p=n))});var y=h(c,v,s,g),b=r(y,2),x=b[0],w=b[1],m=function(n){return w*Math.log(n)/M+x},F=l(d,p,m);return F.a=w,F.b=x,F.predict=m,F.rSquared=a(n,e,u,v,m),F}var t,e=function(n){return n[0]},u=function(n){return n[1]},o=Math.E;return n.domain=function(r){return arguments.length?(t=r,n):t},n.x=function(r){return arguments.length?(e=r,n):e},n.y=function(r){return arguments.length?(u=r,n):u},n.base=function(r){return arguments.length?(o=r,n):o},n}function x(){function n(n){var f,c,h,v,s=o(n,e,u),g=r(s,4),d=g[0],p=g[1],M=g[2],y=g[3],b=d.length,x=0,w=0,m=0,F=0,A=0;for(f=0;fL&&(L=n))});var P=m-x*x,j=x*P-w*w,k=(A*x-F*w)/j,I=(F*P-A*w)/j,O=-k*x,_=function(n){return n-=M,k*n*n+I*n+O+y},G=l(E,L,_);return G.a=k,G.b=I-2*k*M,G.c=O-I*M+k*M*M+y,G.predict=_,G.rSquared=a(n,e,u,S,_),G}var t,e=function(n){return n[0]},u=function(n){return n[1]};return n.domain=function(r){return arguments.length?(t=r,n):t},n.x=function(r){return arguments.length?(e=r,n):e},n.y=function(r){return arguments.length?(u=r,n):u},n}function w(){function n(n){if(1===f){var c=s().x(e).y(u).domain(t)(n);return c.coefficients=[c.b,c.a],delete c.a,delete c.b,c}if(2===f){var h=x().x(e).y(u).domain(t)(n);return h.coefficients=[h.c,h.b,h.a],delete h.a,delete h.b,delete h.c,h}var v=o(n,e,u),g=r(v,4),d=g[0],p=g[1],M=g[2],y=g[3],b=d.length,w=[],A=[],S=f+1,q=0,E=0,L=t?+t[0]:1/0,P=t?+t[1]:-1/0;i(n,e,u,function(n,r){++E,q+=(r-q)/E,t||(nP&&(P=n))});var j,k,I,O,_;for(j=0;j=0;--u)for(i=r[u],a=1,f[u]+=i,o=1;o<=u;++o)a*=(u+1-o)/o,f[u-o]+=i*Math.pow(t,o)*a;return f[0]+=e,f}function F(n){var r,t,e,u,o,i=n.length-1,a=[];for(r=0;rMath.abs(n[r][u])&&(u=t);for(e=r;e=r;e--)n[e][t]-=n[e][r]*n[r][t]/n[r][r]}for(t=i-1;t>=0;--t){for(o=0,e=t+1;ep&&(p=n))});var M=h(f,c,v,s),y=r(M,2),b=y[0],x=y[1];b=Math.exp(b);var w=function(n){return b*Math.pow(n,x)},m=l(d,p,w);return m.a=b,m.b=x,m.predict=w,m.rSquared=a(n,e,u,g,w),m}var t,e=function(n){return n[0]},u=function(n){return n[1]};return n.domain=function(r){return arguments.length?(t=r,n):t},n.x=function(r){return arguments.length?(e=r,n):e},n.y=function(r){return arguments.length?(u=r,n):u},n}var S=2,q=1e-12;n.regressionExp=v,n.regressionLinear=s,n.regressionLoess=d,n.regressionLog=b,n.regressionPoly=w,n.regressionPow=A,n.regressionQuad=x,Object.defineProperty(n,"__esModule",{value:!0})}); \ No newline at end of file diff --git a/dist/d3-regression.zip b/dist/d3-regression.zip deleted file mode 100644 index f9a108dd7b5550acfecfcc88806186bed766d90a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23007 zcmZshV|OM{w`HH$wr$%sE4FRhwr$(Cok~)%Z95gC>+SAw`;PAZaQ?wrd+fRPRFDAy zMFju=kboQ)`CmB9LCP2)0KhpI0005N1;|Q?h{-F9sj5H$KqLoBbo;c%4P8B806?H* ztxI&EOw}i@sY-J8o1BQfkLs{qR_Gg7ZQdK(D0K7eK$=cc)OGPuq8y+mObKV8Z!aH` zJQ3Y=T2DsGIhik`nrA`Z?|cLsi#C-mxp?MN8aD*`gm_s_3JnLUK7Q{~>yyJdmEhM*&p=y~7f8=WtIpMfw>Dmb%{Uwx&duqX zvEMWYpBzqa@>d-7<$?lj-1WRT)BR`J>mULjw)oFVN|8HJ8RWjXpumiQU!gb7DkwVd zdgFL)EDjKv1OaVs@n8|qg5m60z>qa&vp~q{>t6a-;oH2MV<6+nftH-3>)0dm%;S2H zri@&dUKXBuki$;ZyF7YP!D!yJmV%!Bi*(&e*ovzrWND;2m>o^=Q4tdx{f=Yoq&qFT zM=Qm>XLZPm3QbbBEfo;B%P0*==pRWn&vn!$EmKfHm6b^8mSixyvUy^PFOT@&BzECr zYoCWu+R}9jA{oo7iB?doayoVK6S+w=Tb$O~R>C!-&?V2wV{z1W0|=5x9!0DLYrV8x zSFBe5V@D#wBnIh0WE35ArN}K&9{Y0KNg@5r#GNRevEWx)gRp8}x51?Yx>sUL+7;#lo1! zqIu>}avG8pt2XhKWw@MM#AqX~af`%-+G-OtsAVexA!Bf=&lorBKyNezF#s}9)r|x45qDl{!$IQ;jr063t z+?jv(u^wKx_FPFt(dsX9-Dp1(DEwEhio)1bNb{klNnrs1SxEo@>R+yu#DqlU#OQ5J z{%5iTX)X;V|Gob!S=Tz7PMe&_zN_j5N8yQPrqX@K%!#VWGbYwe$CD;wk0;V(h)`0J zl0o~UtnSv;&m7M(&%Oet{U+T&dVj1VJST(IlhCW<4W z0v=+zJdT#rlBkOr5=`xtGF9+MnxR7^j@0mYH%tVV1;HZ5R&e0z&NsDCu7{8Nrm~OW z{ic1S|q=Hv4iMtgy|LW~+=tE$qXU5Kfw$ zp@C&>9cG1Sua`tpohbHy!e{gF5HM~fMgc}pPW9&trr8WiH!p01Tk#_Mr0g%N;jKbr z!GnW9o`=D3Iv83I_G+XkP=S_7?YDke3Gse=NOc>R=${se`G;^Y%J_{?j-nUcLENBK z6KET3QG;3Z#YojLQN87M;D z;XBLt-F2li{AWb=hqFeJ3W;bPkU@!KGK~Yv#5g>_pNOp0X${XkMAu?3p0*9{?hnW1 zt~!G~O~QF2F0C_P2Txm73fb##<7-eZEzGhS$9*rAS#_q%rFV)DdoW=EFbfJ|=1%a< zO;rzIFIaFAhd@LtGZRFoFb5hOO&MsTvgmmGiZ}6fW++aq*}Vk)n6OnqLL{9F47
Bwzp&E;bD@%uNx*-}<&-%z0A$z)i z)oM~_ZbP!)hODK>FM9Y)i5x9AEaaE>1p51WY+zyf0q0y~{D0Tp8Y-6(Y=qmm3EEol z=;2S4y9769)1%EUeY$jF#*PGj$ko${p=?=->>ZEE3Tgsa11vA38v)SFD!}1~P+Hku zfm3bIR%Bv0;jqp~B8)@T356KI)4plQ%jystS#Pi_;vtAi2XKySQRH^Abtlu>Thrxt zw?vrgd@uWEw7RnFW;0{3*tR$$QH)931{0t|qp3kA%ZjPve_uW4bJp{W&F!rDJn-{p zZjgAj%~p_}2Wvs9DNjAJ9z(N5A{fLKhQ2_4ZouRqFlK24fq+9WNFjk@Ch7h~t84!` zY~;y#$COMsUWEp>5E4cuFz{0fFxuxgp@x3q3l$4Li^nfSO{C1_YWdve-kH^uP75WU=hLK9RR>g zAYLOJ2xlcR3gvO-@__z8CW#61YJxuWZm!SwkO2>%6FV?bBzqg-Kxzzy#Jed*(KKQ7 zI2Q-zu097Xgw()vRuJBh%!F*L$EhUC@|7aQhSrxhuSRR7hay_e6!AG67@<%rB6rjFa3CLZk?S zbZYhdJ-SB_70Akz$i|fDYD7%Kl=wF?vY7;gyorZt{y9m2ki6-`=)kVlZd7z7HnP}G zmNID$R9tT}6nj^dppUvDhRepaKA~*>qBWl(V z57MmtI~Ov=-9h+x!i>cwAT}t1u)4(tW%1|xQD5M7DTfS(qNvRV$Vw1U4htHB}kvo^i1fTPpO^Y?%QWuS4&zGzS@-Z+xQ#)oEzs(Ftt z0%=yowLIAd$csSMz%bq^vQ6iQLQroEMbhe+=JlIK(dLCm_+sSxNh?XzN-1~wS*ogv zDP+U9Jhf{Lo(}E|_biQ>g^jO;VH0b7k^vD`XV8pK6k7lIIoU%90LdNC$ctxyH&4Is z{ge1m_MEe7=^>*po=$F-tNK1(W=sW^Rs-qNayw?s3%I;eNllrGrFx0t(ysF9Nj{ZX zx3s2IDVWx|(v$Oa4NQ(jd<%8;zni zIY%`_AMr5Nitf3b#X502RPS`8++odg?)K7jpGefA#l2UaGDs$^g#=TGa{T!Wc2fW= zt~&)+EctF0YX$K1)?W!U$+3R#i^oLX&)p;lEZr)TFxpn$@|PU*;ov`U?nDU8v@0sV zr>XyDHCb0ZnP5C9jNWDGU6&}AZh@HQU|Z$!Zz6aKUZ=4dvALRtDr(wLsj7zNq4_df zpR85|b~{5=MA^8`vOE|b|N!i?U8#ZWM2kC+mTu%OA&;4tn=znS9;UKOT6t}4^Y z>HA}Pq8@pv>|neR?tUo?;Je>(`~0#abZhDgUN_v_soYLKp!=>HsY7kStEK7Q&0pFt z#;cKM-H;UKC17-g*GYwr4epg(&qJ66Zk#lYR8Qt9-~fGqiy$c?Am-rL4*xR+;N zXNr8LQR)Xxt?pfJD}das9kE?9c7dv%OzwT;(MeHhpxmXTXY--7%UXY<{43s#$dg)n z#q~G0%SG}jn+x}5=&>bHZ=FW;>G=j9?0og*+tH268lSVMNBN%tG80#b^ntcs=g5Md zhjyCG3R2r~@~ZEba+Fsah};A@?%a%)&XB8QhIr^uM4dXq6hd>A+9t-a1ot3&2O=v+ z6%hSDzt<#`woq`f_nryu$@NvWaQ&iUE+4Y*;Ptz%z{NoySKoi(l$_*Fa(kPxZEX1S z)iTk0$F72MFR4~OTnPqs3Fs*gzYLDfOHnj49XNidsHV_j@F!t!DJN{aM(v}Hj5XEd z?92s$(P2nj09^+uR8PsedYXvL(S;0XI~LudYA#vGO-4QlwU>(gR#^ig4_u`T!c0w> zni+;NLyvXKdOWmN7D6=(kozc3IQol7^Qx=&w_x_!v%HynStZJ&J(U$stQtG$N zm(`kNT42QgMCU$Vg+$0dd2@YfN*$ne#L$4lC{|1OfFq&6Q7TWdo!)pMX_NbpNLoZN{5WTPzKT|WDHRq1dRtQlKH}7iOJ{^`qvQU4dRk|pRW*O?a)T$#XTb}sB z&9LOguqJ3s+XoY92yPea_A_dd|H2bnctXn~Y?58#{D|II$O+GI&a?cNa@!OKCpis= zq<@w3cME#%q90bj@O*9iy6lu+|LOu7dXwSD2 z)+@hYxDXo&$R+dXjW&l>?IW1L+qhO+hf8m}x&Fs8oHi`Vk!57R<2c=CYHO3Wg$-_9 zEW?nN%;m)DPf?P6o+s>~mzIl-9;MZWS!);Q zwE<;$9#84T0snzpAEeGV4qiTHnCr3_7o6*&7-}4~x*uzuQE2|n^KHGGYq-=V`qcN{ zG1aP;#p+&h3#$sXW%mjVw>f&QRJPvA&!wlYM)o_p%IvayV81B{3Q!+4N9Xf&R#23| zvt)6%@jt#nw3;~w=?*MdPw`6_A*CI^jhE);!3AKa>orG-|NJQD4E>Plj^aywTjuG0 zOYkfR>2CEgf*B|$G$*_g8$ zjDP$$%&7W@8N&l96e9m<-b)n#K>UXpCM$yGz^7ho(uX3Nlg7H6`d#IB3-pP%N2Q5Y*fs!%3B>ouT%&>&G z*A1^Z55sGBJkrWXp?`cuG}f%$c?^2=MJCglnwy(nDPGaN@p_N+y@|Wl8~fupJ)=F_ zk>oQ3MSR4s#Y3l)jJK~T$0`Rvr9{C9Q*(RWY(T&sL_7bLEb?Gw;}o??vUeLh8s2QD zJ>D+@O$PA&fExJq+qRBLw9C7pl;D|7_Z{82X9)k+%pwDlb@Blvm9Egl26w*ckIJWr z)aE4o4G$AifGOkACI=WB?OSay5f~@>g;WvBI};Q`QHSBg_0FpSp&1DbRK)2;W$1Tk zc>*Yo+1`LM*ow8w74vB9qK202BlQbKN0ROcPB22m}8ti#0wUG)UA8zRTsRL4XRF>2rxLW(Hyd zyD%JZO;jvD9!9i}WfiJLW+NT;&an3eD)#2$2-hD8MbZk!k~AbptggeIlgRD_U$@^2e=;*cf4!WtgI@p$NVr_yLAIn!7S0I zl~2&F`d^I_?}EOjJ&DD0hQFhgzFQ{QiGlCqA$a=wF?~MPaCkir9y>1u?t5$j})o@rRF$|rm3;XM3N zAQaP{(<(bji{|gQr>`4&hNIwR1{Eqp2i+7nKF{ca5Jzm+Sa;XPjCkyT*fFkimFx>( zvS8+GQp7JN)u@Q6EfT)TA`GN*ZDIOvus__8M{74ME7HiPg3j^Tv3iECc%4tB-#ZW6 zG%)yiYu}>=6fI4O$$%Tf|1Ocw1!{eyGrBe3%7^O4#B}PjgTyGJ4fK)j31hCq-Jv^k zFb10I z$mn#oY0Se9rWkdhB7zB_${}9672q3!+cMS$)WOWst(bRJ7t{rHK^I@5n}#GAG>{41 z4@f!?JE&wX%gS4mpMbfThiS>znGINA^oZ7Js>_A8E-6vek>k0o19`mmXFz)!U1jJd zfUnp8wPkscO()-i87LpoSrm4u@+wse1G{ePt&c%teo4(=O&hWC5QYIFe2x%F19)K-;_3d*bvc9)#Mp`#E6&iL07hS|y>xhGJdkE%Mq8lU z;c<|?_=L~*B##>A4tO6Yo-7G(PgQ>uXZ5(Uu?=tn3oda)Cu{oHo5HiaIBTyAV2E?> zI3nh17UY8M^${v}r#W_o=+zeE+S^Qim)&(ASc*D#Jqg$2uWY2h@GPmI?>jrqZ7JeGf<-n zX339ifXZl~#;iLi_{KZv-(ccWaw}~qpgLG>EO~%buiR3WWuegRQd8%#WHdx50L!v{ ze5_7HXi`udTdvp{X;@K^0J%y6u=rJ|LKCJ2?WCYop`ks-E>etu(Y(+fcBAB3&)yJ% zGuHz>4eogK2itY!#woF7EsfPf7X(ucz|IC)8c_#P-VQXqfTtEuO7C6v_fHPLa*`Z} z2fV9A6rOm9bTBe4`hx z8i=cfV;jo;ejCcWxk(mbemH8C2+Mmm6ebFQ0fPeW5RM}?cu%_lEv$!!+f<+l$oqG| zkSW(YvMqTa)-wp*L5}@gqb-uko|slzaThfZ53p$Vj+1x>a^%2Y2)hYfXKKvl6a~cX zCDOicS-@hZXp#mV{mI!q_sSOCSxe1<4w5J_}%Zksw)V%qa~& zvJvxaDJU1*uhV%`=MMrQqZovaT2%)EYO5o{*(-I#{#dtDT zT#lio)LhY#6L=iW0t*UA+@%Sdm)~w%R1(-3YS`?dhZ{Zg#LkO!#EWm~AAeLG;fU`X zmY>cCO7QLHt60Z%q9swlJMfv0<6^;0wpnmY1_D3D%)E(l;c_eB@k!{(#H{fdH=uQ4 zN#>I`XAr|Od6tVL>)NgBf-%~$*#_(pZ`a*_CQq$o?XMDs+SGO3VADD zR?=AY{D;*aE5Jq7rr^Pn8qWarTz((@83rHSYCLG8Nj>#$CzT zYeFY@HaiunA}k6yRgR8^JRl1;^X$Aq*&2XGyi^f|M^nSU8K-z&a)q<*8@ldp^jA#f zvtrp>klPy#ez=Ld82)2i0GF=O7`>IYFB*r#TR#>uodoW)R%YeLx1h0Iu6Y&LUI!O2 zF06ZoX-SX^Kw0mZpBO&Q7u0~J~hW~@xx_g&2<4PuK%OfZK>xgt- zOB!x#Nf67WKvh%gf*|W_IR(dt>?bRF(JUQO@bw`EpVAU;Mu0f7JiuIM|J;>LeyCro zCd|KeBAPH;+j<`3`;9khHRbU75*3y)a$1Icx6f2W5!0tH8YI6|$fXx<8&tT81Vo$a z2`vh&q;E(J)R5)x=^ zOvB6?eXEGH5%H1lxclbS+_&B#RAH>j&^c`gJ#2b#urbvRv+~^%B zhE&HMG~M0X0oNxC$8jKZ*NmA^YTa{y{?=eKL&HBUs*P+5U4M<>$R(ukzd0tEPZmO_ z7$^+q#Egz@t^zZbQodVz%$3_USu}$~0p-JHA0o%bTA4@K2CbBhUR&mW+zGFtO*i^} zCNXZ;&@D&%>jnOL#}M`FS=|SWo#I-v6+}*CU{IVViuFzgVXh2A+K725M#2d9O{@iG2d$5S_mSnjXTttl92IG6+x-qRZ$4xeFw3h2`1&FU!OU6 z7YZ1Ye(>Nhu>&YayR9xg##ddY3?bA8c8z@D7~YQ_9^zGF;RyYRxOaVmlZf)>)QW2Y z$UX}sAq>mJYgM9Qju!2VUph88M)-#+x;AVNFKZV9^F2b+xjJfMhxavYoUyi}7q^@< zVql7r3V-+kXun>=x;;+if6Xk#h>Q&>M1mBy%l@m$ML~GxvLrIM16C5l&dPEwq=O2yA`(hqzHQCBAVtuXWQ}fMVR@oSx7W>34jS9~gD9iPF)r6RX&W%_|16xZaW?OT^JH zPVUl#c%1bdkeiY|i+&;ZWE&?)Ik%QqH3vGyx0 zU#=wT#PQQ`;_$I|N+%rhr*J38+ge`D8u8j;TJ?Tm-oZ%STkifMG4o_w2(Hu%z5yXo zi&mqvTQ&AaQfN!It2VE>Dd zBhh+gxP2)nZ$($`exKJ`Hqb|6s~_1`!qntk0&z3WLgHO{&AVMU#w*=z+j2ruX4iMb zR-Y0t9gd2bOHrk~O!BJ=u^d}?kF!>oRh>@`($ii%f$3%@g|YqQVJQR~j$bk5A%T$; z`)soaE^uV8Spp~->70+2@;8B+5p&ZL%7-Y6?jgu>z-jWuHXZ~9N}xp{RLISR>g@w( zk@5jHUOel67 zN@e8Nt=?JJQ|~Qte7Mt{!`u9r9%cRvZ=WN$?c`8@uM0Tz-S?fz7m!_N-QDi->|jHp zI+7m&{cd(+c2exo%ULfTPI;fIjJzI(jKyiSA}++WpRx>qEaxHvPpzjL%17n&;Y}d8 zq7oRug(2x_9ScVdVS~wmlp(*>>vc%1-XSWDm3l$21@}^yH$!^XV>3z*HPTxTB1@O0 zY@aBD)5gZ)(JGC!A}3gG;iSQyF1$7&|R)bZFVt2LZp6O*;vR_Is&loK}@kINd(umSH!1HUV#I zja54XBr$5~pIiW}>IzTG`tE+o6vkY`0AndePyBrfio6{Bl!O9CBJmDZ8TfGBMsJF0 zwN|Juv|C!#ZRyM(K2CuVp0kq$YFnHfkZg6Cny@QuinNNz8ErNhh3CPm>pT2w)Pf$j z_C3z+GcnARd16?rZHk_@9S!s~M}fo31yS*yAIV=0FeWLnyW+~a^UYv!QBF>higRK? zuux)*Z2Dr;GcV7!L{P?+hwlh8AZk}UlA(HUZfbZ&6~kR>if_tbR~yy-JrTNxyr@k$ zDg>y_n<)>$qWGw-o1#&{qAH}WyP^fy>Lg-#vE`s}>c2p?^2aFqmSB4tQejaU3Bey0EC5v6<*+IqXO;UfJ7HeN@q`Hv&30Yf))t z@@)mDwDp`xysn#@&MY&wi86K9a@o3h%*V}Td)}a2($7BASgjcnVt)5R8!d(H!Rf~8 zLOY>tHi{xJuZp+i^k59ULA;db+~Y7?nork}^c9MgWVtjPCiaoXBs*%h#drGww1SI3 zZdUBlK)D3pTqf5L8L4C?ats$Zw;Z2yV9Cf4+dKlpzDQ@-4>#;yuHIdfO)*HT$!z{D zp;&2i6)G?chRaP-qk>d}!X}4izEx^fj@qCt?3kjY_kC^CEipsG;;pG|_6kVt1&n(r z+K9QVE~JZT*9-~YO+Q8^z9F;rEGE$qmwB%|*tJkf7$YKSdfX|bbzCsiq zu!-ttL1(w?_zdN&r346!m^`Lsv6}ks*)rIrCij|-6#LTpXkWSpOK8v3L%UHIwJI%D zLpJ%F*ZI-${n%=uqBf|Am7?(@Bb#bU%bQ2or=))SMh#y+yNQHvGSoZ>%ldX%eIJh! z?0qh347Ar5uI#)mYx(vs_`UWm_<77O^buM5+I7FC*L?Vwsk@glaQKm3%J@3J9M}c& zX#~V$E#AHju6BUdLWn;g`_n~8EFr|~l3kp{@VKU%>3&C;{wfdCKYDd0Pfd5fG072}1aVfj)V-M6p2~fSL5B|bVu5Cg9mNW1UN>Z)?`9#peL4=Y)o?>{KD&f1g zPVOha52Mh0J1oX~wqQRz-#u%WCU9N5JwV=5_WF?02;D^g<~|bu`ajM?^}jN5{-6(U z5(WSWA^-qT|DQ6_*7Cm!Nu_^fr1Jk;NFHli|2iDQ{-y~~Icgm5Y^c6~G#5O#6SgdD z2;KfN(424_iyUkWX6Q^Q>Hp%bA5U*kNUf5PsG>GJ;eXW2dtpxY6^QSljUb^rfb!;! zka$^`f)ANkamM=ac4CW9rsd=1ohWX63YLsRc&;AQ*k|iyLwfihKFC( zbo^(mysBy);Z<=tro2 zoe~~7^H{1S-SEJSB)V^ge08lYPg3MpVEy0Z5#9En7RveY-=&HysjZG$BN8^#=&cHWO6MdSq;*M+3%$XgUIh@$d&ummJf*rMzbD(0*Ga$-RV1W{62JTVHl&a*z!<6BD5mGDmDN z>IfhKIWEl~SjEpbR9H@G?A z2l6^xnq}t9H22bmsTBrn4Wm0TM3FS_xuO2h;v5E1vZ(}H>D|DIg3mwDj)-eL>qLhE1ceU!exh_T zBGc``;2Uzejtosy!4GTP%^_;ph1K-#DXSPeM_I{fMDZzKSz=N>UN13;Mc7v4q%}4A z-rOhr$`#)dBDu*D5-K>qD=?dn@(x792}|PLX9u4Yt%Wf}Y!$7j(w1KMjw|`n`reVR z57&zcEW+in$4T0XBF(D?iNwU1PL-~d^t*{o*(NiCPYrw;Nh#1U@fy<=0rdiyy3cf6 zv!A}25Fh7l|F}HKaAddX03IZxuj+yYSekfL9*VZ9Hu1t+qdQkmXUz1PGiy^9W1O(8 z2^?#;ep9xK@5Z4Ek0SpYlyVne0g^3@y=n@MKA68+Mq)CEKMyWyHnA|b;i&4X-%sw9 zF5NmZ+vBI{rAEtaJC~48P?5L)rqmfODM(|xm>&%SplEK%%vS$xfrt*y5CP(bf}+a% zmTm(g;XqqT*~q)RX#B47in$dRLxyR{Pn63_&O`DB$#;9_ys*3(RrALU@Z#fc8i(#J z01HQN-M5`8I6jLb4qJs9P|_L6c*2PHiX6j6&!_Je=NeN?Sq+~08e%5nte)cd(6-_z zVQw^dU!Oc?1BX>0Z9IPT^~%J+{X@I%;nS*R*El&=I$@fGPiU>v8bUDJsXm>dQrL)DN&f`e_K-V8|m^R z6>uK8^jEsFT6LHXnpY%i?)>v6n1Gu!it@I2Pv|#>YC%IyecI@*u!NpcA16}U5Z9_j zbj`ITfJ6Rd;)u?Ske_rNev4gGWzmdK92nB1gsgX?6S1s`ndH1a97r9I+18cm;(+P2^Ew&0%dX=LKo;y%$ya zedbQ^)ophl!$^`=r+8r6n~Bl)V~Fei+Ik!}M-Ny35d!m&tB=OV{q@hCFY>k5`iS$Z(2WMH$NdEJv`i~ z{8;@bAbrJF{tc0-5=9N>n(lZFUK8ytP&45O9CqoF4~4x8b*6c>=^@G9XZ00tT62}A z&*}cVdc=oS;R*e9^TwurZrf|`FZDBc)%!P5mtO?&tqeuhek%ejUovR-tDOES9vG&Z z{x<9W22a~VXWF;ekNBPQ9#}EW=lX5E?OLyO${xj`x16D42Pbe89j9(osX`j1{xdmK z)W#~ApqWgsr4xb}#L}$YCHcN|{FS)?;}UEduEFC7B@g9iN=0F8b0#e+Sd!BgwUG|H zkr~5Fb$Te5`WjiTf{!}waGK4=Ej`%WZdlFOYi{wdXvk*_Vu8OA>>-3M*?NhPIAQ)Z zXf)A8QandF41Lgr zkf92F6EkEW_R_Hu3rXp{Pk~>HD~uKh9Q`T3CaB0avS2;Q#7p+cpkGVZt>^SFW-D0K zwE1Zl8#U=hh={L}5TaddG$hurE*OZffTv#XZbjFq;RrrOgz0$2sCV0_)v6E7PrAME z;wDtfO6G_y7PiqNWLr{*Pc&pDYn@RQF3F-ueixCWGD#TeWUfO)>K$b7;~W%2ia(zz zuj6P=qZn_NSFde7!vzP`m3#Yu?a@u64cbYmZnLB>WuV1|autsu!u`t660v%UPOMy) zC>A_~llLCs@Guj=u>ZH`!3FQ4k~#FO1Y2!03x{QxgV}p+ ztqY{qwT>_J>kG_bm8}%^o{djm12AX2hTgSEFIsiOK+l^9uXfqaKg*I(EFwrR=LBrm}6WbMw)EXjV|Ld55OQj~V6h68={0@SnQ<_UU@6_72+;!D|24IUKH^=Xe`Who zao^#Gn33(?H{a?xvNm~WC3*cf@FeacbYHJ`qf+}kUJx9?YdNu|j%=rVTBrR_M9g-1 zH!9s-B@5mYOXo_xykZKba^56Wr!vAvlJrP^&9Tn(NZNoT&PA8dbmfp^6Bnc_(A-4k z>?~(g!+7bl8hh;zz_OHa!7(!9vuxLv+@f?On7_jf4pXP4*Ds1X1PTGsvfOZe|Y4=e-=ke;ozK=t%)pHJLClo{7_7DcNgtr#z&W zTAiBW2uDS$&c>^JfTr;l&d4UCC9{mzxGl~36jzSoTxmXwq0MIG_|HA@fE9d|2 zDf|Zw{%URvZ2p_F=MIaGl+OuXBuupP?Mtfb(dcsxIvX;$ZgO0}g z7@RTHc{2#L$=1#PCO>DfTdpB}!Y4c?lAlxw&C9Dw}p2#93yAWc9?#+s8mw zR4GB~HLtgZ{nIn8H1p*+8k7}1beaLWZwIwTQWH|S=^8h}89b%yw~9Tz5x8&76L)|pnJSL`0(N&hao4V#HZsc<=w9#`!K(s&ryQ>pW9JqQvXD| z=C|(U43fmwo#|3uy;Hb-UZjLFu3yw0>l%GH?>>R|M^SB9v9 zEO(sP{x7XS_O(B&h+xjFG5Vq6^?2^=G!Tk*XdA>${s5P{OSv7T)DyjR^EtD@Z6GJI zfmfj)tOnb~zXX>~)|MN`PznO#gk88gjSJ!t&=AN-yH1M|(ze~^kgb&7q5O!dW5OD5 zaI4V;*o9$PMTBs03JbG+YTe~*q%7yh_f z;cNCmqMKat$uq_TjdekzSW23A&clH2>qU*002=UcJYo7)D`ptA5GoFR5Z+h|69g`Q zMp7Nk(T7S)e*QedK0rR3F=sNtLo5_z+e_v$3G{*rIU?GcT>d`5;Na76VkTZ&c7Xl? z5_xAHV8AN_fZ#A@v7IM7F){tyIHW+YdDZ+9~*v8IV!#U6P4S}r! z#%BG$9XSJLLVLYP<{KCl3!7v$UCBAk2Mm||eUBDSo8m?-EYC*@g?nPg>! z*-0fKu!;O{rZV|&lCmguCjKaaTpkG$p?Mi{;pq;2>arsTHu>ZVp)3o7IG9w$>O97% zpbeGJFat=h*UuXHcq$RHXeHi@1!B;X%~Dm{E$i^Y6&bD~!@$+Ou`gg@s& zxDMa>wC(w0c2O|9z1O0mxz{0nu`!R3p0ZN(utu~Q0VDvEP9#rQgo8F9L^l{%pNZ~b zmurd0OE+3YO8iYnjz;5-iJ0s9)0=_owl8S{eiMZE-6q8k#7_OtC|I;78qnxy1s7tV*(pFk84 z9W2zv?7WL~UI8aLW{H$x0m~wapN-#9L*OUXu(y=TM&c|;fV0TMm5~o6rzXD2dhKAR$6p4Ha(yZMQCF~j z=uVmi(Wxuc#ZT}JC}uN3@U018OVwCuAlMVH7?W;=wW5AQ^OJA83@~@A1#A2ou|Vyn zcSntPjkt}Xq^%OT2wb&Ve_EfAJ|lV7w~@5X0is9TltSW1GZqW!i?D*MLG4$3Xoy&3 zeJo1*=bVFJQt{^=4&p*Ro@DbziOmGLhY!rXzM|p>@S7GueUffT5V2Ql+?Jp_C}aeC zuq+-Yh4q23P1D+wC}iQr1-PtLhRTcCvW?$!q=Gbl!J%!lnV5)B<2V@!AyXHuzJnA* z_ev8OPW32;e?8{s&CfE)Xrm)GhX{}PzAOZ>8r@byqUuZmJh>4Vjo%@&U{L!BB4k{U zL+9Ygo=_ly!(Aif=`k~!td=e*QgxTYuh57Z<}dj0E8zE9;&Ezr?B48=!&wthwWW;< zC;9`auCi~VeH0`iCN!;>_hT5GSoPUDeXMYr#N=Q0XBJ7VI99sa9keQ-r|zNJD2qe2 zwy@(#eJH$oD=*+hZN=bnpr&$S71mwwEtbFV3un+Yl`W{Bdzd;Pg-)R*f+7Dg2O88f zt~g0j6oI<<#Ho~B89j~0tWiXfRq+KY)_m!k?3MA1qANJLoni*$eGIbogc8vG$uDjp zf7-TOcX+Ud@=wAQJ}o^EOKpJ>h_W2{L!tv7hVKjQ5h=aesd-f!44v9kO}Fd@79TJk zJ_EqqGHN8MSV|LjxmS@VL~^j|4K}k}IR>-D4Wo&#>Xl?`wxbfN!B)2tBGYzr!%W$+ zuAlfKy4o`*{cuZA@z^&x+TkrBnyd#{qlR}3^F4Qi%&c|JDZe8bK5b<=;8X_wG9xBy zr6=h2oM>(kGwqcG-9o+5Blog?%%Avk?haU*d7tM*Q&wsKI;nOv1d%m3b_~f)a=r3! zSRCRvWHCW&j;Op+2wE(DWpHdJr=KIgV)`E{=3dV{Yh;@s&(5?F8Vg1%!YMBzl@snX z5BE$a1by)}aeG@e+(HIrY*_}R@*p>do0LR(Xi~f<_^2S+N=hJ+W?LCWJJhT5%6QPq zlH>;8F>Yt?#k|pv^8?l} zqfkq*GLrWoT+Nm@FNPD0F|=qea_cYr^aq_dZ17`Ux4z;-2( z1MtKT-r@6jr%gZu4!l#0r<;)$I8lv=J|irxK5+6dMKi{K;_M(1oRbb?3thVotuM@O z_e8_BujckrW0dq38{S=zOpr$otLqgANDht#IiQcL}A2$JP=pI>YSupJ(!um`~ih_m7IZRd!)bmmTrj zE(Z79b(=M3;LUP=AFPTGGckr*ICw3nncY`nXYo(~KVz)O!jcTP@Yo6u&2gCk1%i7k z8*?-UT=~6r;>c2h?2z+5J-9D@evel9rtMZqG%2`UWevF+Jd12kLDHnN#<;{};mzC>14m?(Krb@b zHhhZmLLVBQ9ZJ~}8zRV&x7Cf72aw_}7VqIo%lpcLbr&;cw(WAPQ?uCaqcl}!Oz=N_ zJ|*xkd(Ol=vbPAOjt8Aak}snCEJNB*AZm03?#pk<}AbPp=KYrx9F^LO%+?#igml&iXmAzUieGVN0(_vYb|ITH>4_(R-|E z{}S-ZcPWR^wUqZ91P}W`p1sG!Nr}si31y|nsZb2*Xf8a8wg*%Myjv~i`NfqOwn zSg;ErJPTi%r)iX3=xIyF;!gFWr&+6d*fE*=8?WZa0CY3l2&Z!BgCR4$bu;pR6myqB zQ7G&lz!z9TVJYcuq@`s+KF!t%q?ayfK{$(aEZw1WNP`#8dC$4d ziTBQZKioUa&ahwpvpf4`_xC){zkJ$z{)4h5&sR9J7|<12-nCwDeqN#{oVi$O;kyIW zD=jXm9CiN0{54r0{_N2^ZQhWu?Rz0Y0hbsj& zyXpCQd-v})x#J#m%bU{8r@&N=Kl5pK+vgR1`G&NTx%bdg2n9ziha-(fWk)+j@u;V) z41a0hnbwuQ)pNmYY;X=KxaE21$4z+oxbzj0t>SGyE&GNbQF@#abOEi(C|Pbw{szUP zLaEh?sp2r1w@o^jFBT7PGC9C@fm;AolMmz2Cl z61qyV6f}OdoI#z_PLEjXhH$o98f0uQT^1d?l@}zU50~^`+z!hQ3g@K4@;}~54 z1Sn=w(>l58H;^*-+>@&rAt5W8m4b-B-#QrXJq==nqdy~%uQ`EovZHY1mn0`K^x=S0 zRyHg@tZb8u2zc4dFMq>0$#X7^pd6g8ZjM*U(uO-xCYUPgve?A$%G|}Xb7AjuZXa5- zAzfh+b!?8cm?zi)VC-ro%idp;_UoSdAk4C)Lryt!paBQwlCT&~U@b3vJ^;X$iq?UM@cxpe^ z<0fpia%weZm6--fhWbKjc3FLNRb^GK?K`eo=f|7fwGXiiPrBAx-prrD!WIv6Y_v7F zx1?zkRuo~OE{3SF@rmEv^#&8@vy;!Ffe$ObQZw{%bU|*HD=>&WN0*i705(q=Sm5LE zN75I}%x$KHeJb*AI&)>H1HOlsy-){J(q2pa_o)Ae>CFg8Q%K*Mp7h_E-b*Lj|BdOn z+~3l7ona~-?VCl^dThLz)ZS?6T^Y8JcYLV{lc!ctFz0S;yGB9Uhr4crXgxHr?SKt*7ns?j1ATWzJ931Az)2x(1xlIYw!H67748=+%DlyvRP?Zi&)l*#}Nz&=;ySl zTxL-^ZJ&+%)?3>+O+!m|FP6xhuoY5K0`g6LX}Ruw&5jZ&Lw^Jfs1Qcy&>-nduo1;v z&OmurUPVU2?6Jh^bW{6az$d!}>sqBls;+lLaOS|e4Vz3Rfpl05^0@m3%0oh4fgH?$ zg!$rbu=br-7nnguyR+$@2Hu$N@5CGLA6xcr_?!vgwEDj0Bg?{V1$8}sxUAa6>hDYF zBYJ$fQE_v2*v4bTa1M1&|181%EmGpe`J~w1q}JqMwa0>c(hW;w9K#-$Q#Hu67yG(% z4_?((jEfj8#ZULoGgdwu)|cjej~u<%qDCw0SX1Yx8$KLW0|K-gGh+ms$iG3d^Gh8; z4<%&o*yPmPE)5zo+Qp?>p0TV$zX*Z&Yc1Y*M9Nzi zKwGL%W#2eX&{n`HcOu*>hhp->=kfe5Zc)EG-%AQMF>7?UVPfn)A_5m4#;8z-Q@_mk zhoRxSV>{B8Su#6y-Ylim4xJlBOU&Ykwe8V2Rg(6Hgq^j zLI_~4Z9Ug)!5H)Im>4=K`DaF?XcBk(X=lISN0f|Nlbo~{x;OP@*#~flhdbtH^%D{y z2pV$u!vnpx26s!!>+WvrTyNK{EZx?yBy(%=L0+5y*{1M&R(+cygV^W`M&aFg0OJo2 zkI23k4^Nub&5uO_R)4O7dZ*zcQtI)l|G z)ev8D-OXd?312mrhL136X>(cEF=?M+v?=}nj0jg`#R1_jP3_WN)9^JHAeDr0uFEL1JVnD#qC2=7r! zC3iD~#CJjLj`}B0dB6knU*n{@!G zQ0Nemy(`XLwrF(QBxGkXZgPd&aze&~WNK|=PCUb(2-3u_H@nxp0#P8)umJYM%FflRM-I^0UKOMGZZ3y@nT{r$+|hxl ziPf#xnSOGJC7+QPoLh)TT_@ry^BB~MhR%=$v|NYd$PwLFnj``6t2H#*;? zP0)@sL);SBc=J-R0LLF4t(U#oM0Df23^JK?Fq>JUBWfKq2l){Lw+B9Ugy;`Vva;mA zfuZKuQ5mmU+Z_xxHXHctV`l?NRTOX=5!kpGqVh5s#%^m9HLQC0ko0W17=0S%9XbXgQ2kn3Dvz zF&hYqD>b+R(-eJz7vguoi>Zdzk8LD)DZ0xM)ZJ#(%gqdTpwrmAG@N9`>1iLbM2-ifEl~zTdeqKX*?O#E+Q4N?-|Pq@#AV%GFfY z|Ll0BvLF?G0elv|>aK$!9-i^8G9na_rO}m&9!CvO?9Xa|ETN6&;QnZV&v;zaU6sXv3i*LkG2BC%c zxD0iCgK=%ikI%l9ta4q1VeZBW=x}_Oyqy$5unjUmOq)X?xYlYkMotI$|%vH z&p3mZXk)MVbNF1%Jyu>Zp4q>C=se{&E+7P^!uE(OFKR^!%K-6l(34;-Z$5>%$(gw1(vr0H?v4X4441TIY8*NAyAD??f}*qqANhYNd*3k%n9?L*PqRnc zP4&dIbPi5@rgzuJ5vSZ=t?`KlT_^8MG#8Rm*)@aUm-m1u2?CIp8zuoj83^!Wh>8~cQ@Wa1T&`4XRw@Zb+%D`J< z$hmUx+N1=A&zId*CALY)uzgNmPq|-nl_(}*>`%?I75i1$a`kke7I=sc>ES@uy_!>j z7pNm)SeGS4_pIv~R;@Y&h0S4WZiObPDzc*9c(7gDS5>r_Y%-yrPd=APP5WBGN78j&5PrMi0(xp3prE6b_Flnl(ADY5w)kC#x@;fZ{!E z?$01^svk|Tq<(a&=ISLIGJV!H=KPT@>~#BqJzu`DZ*=KE7R9z`03C}Ph4EU{$8BEn zA_k+0x8f|c&!s6x)Pa2kX-J0IE#g5!8thT|4dbhxQ=R81YZgj{WwJ^gD*2%%#SBF} zaf48Y&}98Z5$3ynRWK&yQtIQk zrcK|3uwoFbAGGCCc6Mc~x|>;K?w+MJO^H4nULp|{aA(d-m=q`#Hw2~v56;#p$1wW> z#YqH#%Zr$6RAKz%)Pi|TLrTq&?UmT%3_ASr!}a6adkJm3GQDD{(l~##SC&txT}{@KB+X;pd1OMy%PG3$ z;I5QObV^tepG4f;gXyPo%RJqdR;0vdtPDm&#)S8?q9QfAgC##Y?!KTB#ILqSf9k>8 z(v#y@9krf)I?OZaU774gLKEqQS1L|Z6Y@1PcW{V|@66G--oxR%OwJ`zvCvvt`~7lG zt_)Ln)Ik?C>Hsr53K;#}(Ai6Vc-VlC;L;_UV%2-*(TflJ76V`8O2jGRBAMl(D|uDo zp-NNzi|XV#UAL1KI%?RGBQ4465&C;Tfz@=1Pmw6_%cW$y2e~-z>H9;71@)s#){+xl zpAs5x7S`H@LfUYnTL0cwTB{eBwG(1hTW*oUKB>v_%uSfBg%!QI^OB1@ zfsvY!0R&d38!rSqE)`;MuV**yuZySnBSb*~{w{^|8kVtIUMjYIi~Qy&ZGuCrXf7q? z^agmX@*grIdS9D#seQ`X>Feba3JQDNgo8eVyP!JTOhjWx0vi${M4fYgy{F}l%Je0I z;$U6J^Te8OmN>Gn=1WhbUard}EJ3A1(r4hnuLg+4y#`}2}ABU+)odaV6YSYh*u&^QF`&#ZC1xC zv%Hzd)aXK?mw&6+#4Qyn8euIFYFJ_@z0GwbkrDm0?Q+N#aj8*nr+wo2$a5n4$?n4U zUpCNwlexZA)xXMI*W&8suQDgL_&KkkQz2GnIFhGZ(`OznWVIF2*~FJwK+!WwD@%@K&#P^s5YhfXUW z$APH96nB1{1}vpffarSKWf$ky#@W( zl92vg_LjuCwQLx*YX6!7(E_Afd?$neiCT=sq<1MplITY~GOnZ)YmPzPe{du)?|2eG zMIkO^f8dFBsQ}jMiG=J-&GoSiav&Q)io6A!_v#c*8GcZ+0;N|M(LCVTLEhwP+5eYDv3syUT32km62SF(_z|57*Mu3rx@4K zc=p_)%%H45>tK+^Nv#Sa0Z08Am{`O@mJlNEGUGdG2RE*u<5nn_Kx7P#$4Wmo-jd8=~Gl(h$e6t#MV z>r-pXFJPgUsV^qt)iuBS{w8y0YCmLdc3mjQN5<9b2+Qcq-kz{VQirI0&`oYdz$)&mdbzahsdFz(xClQl`q+C z#V-JWa{I{l|MA}+#lGmj75n~a$?oT{zxJ2@9Hw*I7W`A2>22JPHq(C-_t&1HpX1u_ z0Dse3besC4wdmiZ{`KJK=Tv2;Kd1hFesr7sH#>$uzx}`NEdHEq_TbOSzi%-9&#(Ef ia{6N=C={@yTM`{sB+{fIjUX&;AQMzoRe! diff --git a/dist/index.d.ts b/dist/index.d.ts new file mode 100644 index 0000000..6cac199 --- /dev/null +++ b/dist/index.d.ts @@ -0,0 +1,7 @@ +export { default as regressionExp } from "./src/exponential"; +export { default as regressionLinear } from "./src/linear"; +export { default as regressionLoess } from "./src/loess"; +export { default as regressionLog } from "./src/logarithmic"; +export { default as regressionPoly } from "./src/polynomial"; +export { default as regressionPow } from "./src/power"; +export { default as regressionQuad } from "./src/quadratic"; diff --git a/dist/src/exponential.d.ts b/dist/src/exponential.d.ts new file mode 100644 index 0000000..2de7c09 --- /dev/null +++ b/dist/src/exponential.d.ts @@ -0,0 +1,19 @@ +import { PredictFunction, Domain, DataPoint, Accessor } from "./types"; +export type ExponentialOutput = [DataPoint, DataPoint] & { + a: number; + b: number; + predict: PredictFunction; + rSquared: number; +}; +type ExponentialRegressionRoot = (data: DataPoint[]) => ExponentialOutput; +export interface ExponentialRegression extends ExponentialRegressionRoot { + (data: DataPoint[]): ExponentialOutput; + domain(): Domain; + domain(arr: Domain): this; + x(): Accessor; + x(fn: Accessor): this; + y(): Accessor; + y(fn: Accessor): this; +} +export default function exponential(): ExponentialRegression; +export {}; diff --git a/dist/src/linear.d.ts b/dist/src/linear.d.ts new file mode 100644 index 0000000..80e1e2d --- /dev/null +++ b/dist/src/linear.d.ts @@ -0,0 +1,19 @@ +import { PredictFunction, Accessor, DataPoint, Domain } from "./types"; +export type LinearOutput = [DataPoint, DataPoint] & { + a: number; + b: number; + predict: PredictFunction; + rSquared: number; +}; +type LinearRegressionRoot = (data: DataPoint[]) => LinearOutput; +export interface LinearRegression extends LinearRegressionRoot { + (data: DataPoint[]): LinearOutput; + domain(): Domain; + domain(arr: Domain): this; + x(): Accessor; + x(fn: Accessor): this; + y(): Accessor; + y(fn: Accessor): this; +} +export default function linear(): LinearRegression; +export {}; diff --git a/dist/src/loess.d.ts b/dist/src/loess.d.ts new file mode 100644 index 0000000..fff1774 --- /dev/null +++ b/dist/src/loess.d.ts @@ -0,0 +1,13 @@ +import { Accessor, DataPoint } from "./types"; +type LoessRegressionRoot = (data: DataPoint[]) => Array; +export interface LoessRegression extends LoessRegressionRoot { + (data: DataPoint[]): Array; + bandwidth(): number; + bandwidth(bw: number): this; + x(): Accessor; + x(fn: Accessor): this; + y(): Accessor; + y(fn: Accessor): this; +} +export default function loess(): LoessRegression; +export {}; diff --git a/dist/src/logarithmic.d.ts b/dist/src/logarithmic.d.ts new file mode 100644 index 0000000..bb0e2b5 --- /dev/null +++ b/dist/src/logarithmic.d.ts @@ -0,0 +1,22 @@ +import { PredictFunction, DataPoint, Accessor, Domain } from "./types"; +type OutputRoot = [DataPoint, DataPoint]; +type LogarithmicOutput = OutputRoot & { + a: number; + b: number; + predict: PredictFunction; + rSquared: number; +}; +type LogarithmicRegressionRoot = (data: DataPoint[]) => LogarithmicOutput; +export interface LogarithmicRegression extends LogarithmicRegressionRoot { + (data: DataPoint[]): LogarithmicOutput; + domain(): Domain; + domain(arr: Domain): this; + x(): Accessor; + x(fn: Accessor): this; + y(): Accessor; + y(fn: Accessor): this; + base(): number; + base(b: number): this; +} +export default function logarithmic(): LogarithmicRegression; +export {}; diff --git a/dist/src/polynomial.d.ts b/dist/src/polynomial.d.ts new file mode 100644 index 0000000..f9c4706 --- /dev/null +++ b/dist/src/polynomial.d.ts @@ -0,0 +1,20 @@ +import { PredictFunction, Accessor, DataPoint, Domain } from "./types"; +type PolynomialOutputRoot = [DataPoint, DataPoint]; +export type PolynomialOutput = PolynomialOutputRoot & { + coefficients: number[]; + predict: PredictFunction; + rSquared: number; +}; +interface PolynomialRegression { + (data: DataPoint[]): PolynomialOutput; + domain(): Domain; + domain(domain?: Domain): PolynomialRegression; + x(): Accessor; + x(x: Accessor): PolynomialRegression; + y(): Accessor; + y(y: Accessor): PolynomialRegression; + order(): number; + order(order: number): PolynomialRegression; +} +export default function polynomial(): PolynomialRegression; +export {}; diff --git a/dist/src/power.d.ts b/dist/src/power.d.ts new file mode 100644 index 0000000..2950a94 --- /dev/null +++ b/dist/src/power.d.ts @@ -0,0 +1,20 @@ +import { PredictFunction, DataPoint, Accessor, Domain } from "./types"; +type PowerOutputRoot = [DataPoint, DataPoint]; +interface PowerOutput extends PowerOutputRoot { + a: number; + b: number; + predict: PredictFunction; + rSquared: number; +} +type PowerRegressionRoot = (data: DataPoint[]) => PowerOutput; +interface PowerRegression extends PowerRegressionRoot { + (data: DataPoint[]): PowerOutput; + domain(): Domain; + domain(domain?: Domain): PowerRegression; + x(): Accessor; + x(x: Accessor): PowerRegression; + y(): Accessor; + y(y: Accessor): PowerRegression; +} +export default function power(): PowerRegression; +export {}; diff --git a/dist/src/quadratic.d.ts b/dist/src/quadratic.d.ts new file mode 100644 index 0000000..4dc566e --- /dev/null +++ b/dist/src/quadratic.d.ts @@ -0,0 +1,21 @@ +import { Accessor, DataPoint, PredictFunction, Domain } from "./types"; +type QuadraticOutputRoot = [DataPoint, DataPoint]; +interface QuadraticOutput extends QuadraticOutputRoot { + a: number; + b: number; + c: number; + predict: PredictFunction; + rSquared: number; +} +type QuadraticRegressionRoot = (data: DataPoint[]) => QuadraticOutput; +interface QuadraticRegression extends QuadraticRegressionRoot { + (data: DataPoint[]): QuadraticOutput; + domain(): Domain; + domain(domain?: Domain): QuadraticRegression; + x(): Accessor; + x(x: Accessor): QuadraticRegression; + y(): Accessor; + y(y: Accessor): QuadraticRegression; +} +export default function quadratic(): QuadraticRegression; +export {}; diff --git a/dist/src/types.d.ts b/dist/src/types.d.ts new file mode 100644 index 0000000..9da5237 --- /dev/null +++ b/dist/src/types.d.ts @@ -0,0 +1,4 @@ +export type DataPoint = [number, number]; +export type Accessor = (d: DataPoint, i?: number, data?: DataPoint[]) => number; +export type PredictFunction = (x: number) => number; +export type Domain = [number, number] | undefined; diff --git a/dist/src/utils/determination.d.ts b/dist/src/utils/determination.d.ts new file mode 100644 index 0000000..01aebbb --- /dev/null +++ b/dist/src/utils/determination.d.ts @@ -0,0 +1,6 @@ +import { Accessor, DataPoint, PredictFunction } from "../types"; +/** + * Given a dataset, x- and y-accessors, the mean center of the y-values (uY), + * and a prediction function, return the coefficient of determination, R^2. + */ +export declare function determination(data: DataPoint[], x: Accessor, y: Accessor, uY: number, predict: PredictFunction): number; diff --git a/dist/src/utils/geometry.d.ts b/dist/src/utils/geometry.d.ts new file mode 100644 index 0000000..b6f871f --- /dev/null +++ b/dist/src/utils/geometry.d.ts @@ -0,0 +1,9 @@ +import { DataPoint } from "../types"; +/** + * Returns the angle of a line in degrees. + */ +export declare function angle(line: [DataPoint, DataPoint]): number; +/** + * Returns the midpoint of a line. + */ +export declare function midpoint(line: [DataPoint, DataPoint]): DataPoint; diff --git a/dist/src/utils/interpose.d.ts b/dist/src/utils/interpose.d.ts new file mode 100644 index 0000000..1c5dd07 --- /dev/null +++ b/dist/src/utils/interpose.d.ts @@ -0,0 +1,6 @@ +import { PredictFunction, DataPoint } from "../types"; +/** + * Given a start point (xmin), an end point (xmax), + * and a prediction function, returns a smooth line. + */ +export declare function interpose(xmin: number, xmax: number, predict: PredictFunction): [DataPoint, DataPoint]; diff --git a/dist/src/utils/median.d.ts b/dist/src/utils/median.d.ts new file mode 100644 index 0000000..0022487 --- /dev/null +++ b/dist/src/utils/median.d.ts @@ -0,0 +1,4 @@ +/** + * Returns the median value of an array of numbers. + */ +export declare function median(arr: Float64Array): number; diff --git a/dist/src/utils/ols.d.ts b/dist/src/utils/ols.d.ts new file mode 100644 index 0000000..fbca901 --- /dev/null +++ b/dist/src/utils/ols.d.ts @@ -0,0 +1,6 @@ +/** + * Ordinary Least Squares from vega-statistics by Jeffrey Heer + * License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE + * Source: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/packages/vega-statistics/src/regression/ols.js + */ +export declare function ols(uX: number, uY: number, uXY: number, uX2: number): [number, number]; diff --git a/dist/src/utils/points.d.ts b/dist/src/utils/points.d.ts new file mode 100644 index 0000000..e88a526 --- /dev/null +++ b/dist/src/utils/points.d.ts @@ -0,0 +1,11 @@ +import { Accessor, DataPoint } from "../types"; +/** + * Adapted from vega-statistics by Jeffrey Heer + * License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE + * Source: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/packages/vega-statistics/src/regression/points.js + */ +export declare function points(data: DataPoint[], x: Accessor, y: Accessor, sort?: boolean): [Float64Array, Float64Array, number, number]; +/** + * Iterates over valid data points, invoking a callback for each. + */ +export declare function visitPoints(data: DataPoint[], x: Accessor, y: Accessor, cb: (dx: number, dy: number, index: number) => void): void; diff --git a/index.js b/index.ts similarity index 100% rename from index.js rename to index.ts diff --git a/package-lock.json b/package-lock.json index cb1315d..3a163ba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,24 +1,44 @@ { "name": "d3-regression", "version": "1.3.10", - "lockfileVersion": 1, + "lockfileVersion": 3, "requires": true, - "dependencies": { - "@babel/code-frame": { + "packages": { + "": { + "name": "d3-regression", + "version": "1.3.10", + "license": "BSD-3-Clause", + "devDependencies": { + "@babel/core": "^7.4.4", + "@babel/plugin-transform-block-scoping": "^7.25.9", + "@babel/preset-env": "^7.4.4", + "babel": "^6.23.0", + "package-preamble": "^0.1.0", + "rollup": "^2.10.0", + "rollup-plugin-babel": "^4.4.0", + "rollup-plugin-commonjs": "^10.1.0", + "rollup-plugin-node-resolve": "^5.2.0", + "rollup-plugin-typescript2": "^0.35.0", + "tape": "^4.10.1", + "typescript": "^4.9.5", + "uglify-js": "^2.8.29" + } + }, + "node_modules/@babel/code-frame": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", "dev": true, - "requires": { + "dependencies": { "@babel/highlight": "^7.0.0" } }, - "@babel/core": { + "node_modules/@babel/core": { "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.4.4.tgz", "integrity": "sha512-lQgGX3FPRgbz2SKmhMtYgJvVzGZrmjaF4apZ2bLwofAKiSjxU0drPh4S/VasyYXwaTs+A1gvQ45BN8SQJzHsQQ==", "dev": true, - "requires": { + "dependencies": { "@babel/code-frame": "^7.0.0", "@babel/generator": "^7.4.4", "@babel/helpers": "^7.4.4", @@ -34,93 +54,100 @@ "semver": "^5.4.1", "source-map": "^0.5.0" }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core/node_modules/@babel/generator": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.4.4.tgz", + "integrity": "sha512-53UOLK6TVNqKxf7RUh8NE851EHRxOOeVXKbK2bivdb+iziMyk03Sr4eaE9OELCbyZAAafAKPDwF2TPUES5QbxQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.4.4", + "jsesc": "^2.5.1", + "lodash": "^4.17.11", + "source-map": "^0.5.0", + "trim-right": "^1.0.1" + } + }, + "node_modules/@babel/core/node_modules/@babel/helper-split-export-declaration": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz", + "integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==", + "dev": true, + "dependencies": { + "@babel/types": "^7.4.4" + } + }, + "node_modules/@babel/core/node_modules/@babel/helpers": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.4.4.tgz", + "integrity": "sha512-igczbR/0SeuPR8RFfC7tGrbdTbFL3QTvH6D+Z6zNxnTe//GyqmtHmDkzrqDmyZ3eSwPqB/LhyKoU5DXsp+Vp2A==", + "dev": true, + "dependencies": { + "@babel/template": "^7.4.4", + "@babel/traverse": "^7.4.4", + "@babel/types": "^7.4.4" + } + }, + "node_modules/@babel/core/node_modules/@babel/parser": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.4.tgz", + "integrity": "sha512-5pCS4mOsL+ANsFZGdvNLybx4wtqAZJ0MJjMHxvzI3bvIsz6sQvzW8XX92EYIkiPtIvcfG3Aj+Ir5VNyjnZhP7w==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/core/node_modules/@babel/template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz", + "integrity": "sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.4.4", + "@babel/types": "^7.4.4" + } + }, + "node_modules/@babel/core/node_modules/@babel/traverse": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.4.4.tgz", + "integrity": "sha512-Gw6qqkw/e6AGzlyj9KnkabJX7VcubqPtkUQVAwkc0wUMldr3A/hezNB3Rc5eIvId95iSGkGIOe5hh1kMKf951A==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.4.4", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.4.4", + "@babel/parser": "^7.4.4", + "@babel/types": "^7.4.4", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.11" + } + }, + "node_modules/@babel/core/node_modules/@babel/types": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.4.tgz", + "integrity": "sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==", + "dev": true, "dependencies": { - "@babel/generator": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.4.4.tgz", - "integrity": "sha512-53UOLK6TVNqKxf7RUh8NE851EHRxOOeVXKbK2bivdb+iziMyk03Sr4eaE9OELCbyZAAafAKPDwF2TPUES5QbxQ==", - "dev": true, - "requires": { - "@babel/types": "^7.4.4", - "jsesc": "^2.5.1", - "lodash": "^4.17.11", - "source-map": "^0.5.0", - "trim-right": "^1.0.1" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz", - "integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==", - "dev": true, - "requires": { - "@babel/types": "^7.4.4" - } - }, - "@babel/helpers": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.4.4.tgz", - "integrity": "sha512-igczbR/0SeuPR8RFfC7tGrbdTbFL3QTvH6D+Z6zNxnTe//GyqmtHmDkzrqDmyZ3eSwPqB/LhyKoU5DXsp+Vp2A==", - "dev": true, - "requires": { - "@babel/template": "^7.4.4", - "@babel/traverse": "^7.4.4", - "@babel/types": "^7.4.4" - } - }, - "@babel/parser": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.4.tgz", - "integrity": "sha512-5pCS4mOsL+ANsFZGdvNLybx4wtqAZJ0MJjMHxvzI3bvIsz6sQvzW8XX92EYIkiPtIvcfG3Aj+Ir5VNyjnZhP7w==", - "dev": true - }, - "@babel/template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz", - "integrity": "sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.4.4", - "@babel/types": "^7.4.4" - } - }, - "@babel/traverse": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.4.4.tgz", - "integrity": "sha512-Gw6qqkw/e6AGzlyj9KnkabJX7VcubqPtkUQVAwkc0wUMldr3A/hezNB3Rc5eIvId95iSGkGIOe5hh1kMKf951A==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/generator": "^7.4.4", - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/parser": "^7.4.4", - "@babel/types": "^7.4.4", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.11" - } - }, - "@babel/types": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.4.tgz", - "integrity": "sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.11", - "to-fast-properties": "^2.0.0" - } - } - } - }, - "@babel/generator": { + "esutils": "^2.0.2", + "lodash": "^4.17.11", + "to-fast-properties": "^2.0.0" + } + }, + "node_modules/@babel/generator": { "version": "7.4.0", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.4.0.tgz", "integrity": "sha512-/v5I+a1jhGSKLgZDcmAUZ4K/VePi43eRkUs3yePW1HB1iANOD5tqJXwGSG4BZhSksP8J9ejSlwGeTiiOFZOrXQ==", "dev": true, - "requires": { + "dependencies": { "@babel/types": "^7.4.0", "jsesc": "^2.5.1", "lodash": "^4.17.11", @@ -128,79 +155,79 @@ "trim-right": "^1.0.1" } }, - "@babel/helper-annotate-as-pure": { + "node_modules/@babel/helper-annotate-as-pure": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz", "integrity": "sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q==", "dev": true, - "requires": { + "dependencies": { "@babel/types": "^7.0.0" } }, - "@babel/helper-builder-binary-assignment-operator-visitor": { + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz", "integrity": "sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-explode-assignable-expression": "^7.1.0", "@babel/types": "^7.0.0" } }, - "@babel/helper-explode-assignable-expression": { + "node_modules/@babel/helper-explode-assignable-expression": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz", "integrity": "sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA==", "dev": true, - "requires": { + "dependencies": { "@babel/traverse": "^7.1.0", "@babel/types": "^7.0.0" } }, - "@babel/helper-function-name": { + "node_modules/@babel/helper-function-name": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-get-function-arity": "^7.0.0", "@babel/template": "^7.1.0", "@babel/types": "^7.0.0" } }, - "@babel/helper-get-function-arity": { + "node_modules/@babel/helper-get-function-arity": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", "dev": true, - "requires": { + "dependencies": { "@babel/types": "^7.0.0" } }, - "@babel/helper-member-expression-to-functions": { + "node_modules/@babel/helper-member-expression-to-functions": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0.tgz", "integrity": "sha512-avo+lm/QmZlv27Zsi0xEor2fKcqWG56D5ae9dzklpIaY7cQMK5N8VSpaNVPPagiqmy7LrEjK1IWdGMOqPu5csg==", "dev": true, - "requires": { + "dependencies": { "@babel/types": "^7.0.0" } }, - "@babel/helper-module-imports": { + "node_modules/@babel/helper-module-imports": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz", "integrity": "sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A==", "dev": true, - "requires": { + "dependencies": { "@babel/types": "^7.0.0" } }, - "@babel/helper-module-transforms": { + "node_modules/@babel/helper-module-transforms": { "version": "7.2.2", "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.2.2.tgz", "integrity": "sha512-YRD7I6Wsv+IHuTPkAmAS4HhY0dkPobgLftHp0cRGZSdrRvmZY8rFvae/GVu3bD00qscuvK3WPHB3YdNpBXUqrA==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-module-imports": "^7.0.0", "@babel/helper-simple-access": "^7.1.0", "@babel/helper-split-export-declaration": "^7.0.0", @@ -209,36 +236,40 @@ "lodash": "^4.17.10" } }, - "@babel/helper-optimise-call-expression": { + "node_modules/@babel/helper-optimise-call-expression": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz", "integrity": "sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g==", "dev": true, - "requires": { + "dependencies": { "@babel/types": "^7.0.0" } }, - "@babel/helper-plugin-utils": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz", - "integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==", - "dev": true + "node_modules/@babel/helper-plugin-utils": { + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.26.5.tgz", + "integrity": "sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } }, - "@babel/helper-regex": { + "node_modules/@babel/helper-regex": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.0.0.tgz", "integrity": "sha512-TR0/N0NDCcUIUEbqV6dCO+LptmmSQFQ7q70lfcEB4URsjD0E1HzicrwUH+ap6BAQ2jhCX9Q4UqZy4wilujWlkg==", "dev": true, - "requires": { + "dependencies": { "lodash": "^4.17.10" } }, - "@babel/helper-remap-async-to-generator": { + "node_modules/@babel/helper-remap-async-to-generator": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz", "integrity": "sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-annotate-as-pure": "^7.0.0", "@babel/helper-wrap-function": "^7.1.0", "@babel/template": "^7.1.0", @@ -246,298 +277,396 @@ "@babel/types": "^7.0.0" } }, - "@babel/helper-replace-supers": { + "node_modules/@babel/helper-replace-supers": { "version": "7.4.0", "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.4.0.tgz", "integrity": "sha512-PVwCVnWWAgnal+kJ+ZSAphzyl58XrFeSKSAJRiqg5QToTsjL+Xu1f9+RJ+d+Q0aPhPfBGaYfkox66k86thxNSg==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-member-expression-to-functions": "^7.0.0", "@babel/helper-optimise-call-expression": "^7.0.0", "@babel/traverse": "^7.4.0", "@babel/types": "^7.4.0" } }, - "@babel/helper-simple-access": { + "node_modules/@babel/helper-simple-access": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz", "integrity": "sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w==", "dev": true, - "requires": { + "dependencies": { "@babel/template": "^7.1.0", "@babel/types": "^7.0.0" } }, - "@babel/helper-split-export-declaration": { + "node_modules/@babel/helper-split-export-declaration": { "version": "7.4.0", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.0.tgz", "integrity": "sha512-7Cuc6JZiYShaZnybDmfwhY4UYHzI6rlqhWjaIqbsJGsIqPimEYy5uh3akSRLMg65LSdSEnJ8a8/bWQN6u2oMGw==", "dev": true, - "requires": { + "dependencies": { "@babel/types": "^7.4.0" } }, - "@babel/helper-wrap-function": { + "node_modules/@babel/helper-wrap-function": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz", "integrity": "sha512-o9fP1BZLLSrYlxYEYyl2aS+Flun5gtjTIG8iln+XuEzQTs0PLagAGSXUcqruJwD5fM48jzIEggCKpIfWTcR7pQ==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-function-name": "^7.1.0", "@babel/template": "^7.1.0", "@babel/traverse": "^7.1.0", "@babel/types": "^7.2.0" } }, - "@babel/highlight": { + "node_modules/@babel/highlight": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", "dev": true, - "requires": { + "dependencies": { "chalk": "^2.0.0", "esutils": "^2.0.2", "js-tokens": "^4.0.0" } }, - "@babel/parser": { + "node_modules/@babel/parser": { "version": "7.4.2", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.2.tgz", "integrity": "sha512-9fJTDipQFvlfSVdD/JBtkiY0br9BtfvW2R8wo6CX/Ej2eMuV0gWPk1M67Mt3eggQvBqYW1FCEk8BN7WvGm/g5g==", - "dev": true + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } }, - "@babel/plugin-proposal-async-generator-functions": { + "node_modules/@babel/plugin-proposal-async-generator-functions": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz", "integrity": "sha512-+Dfo/SCQqrwx48ptLVGLdE39YtWRuKc/Y9I5Fy0P1DDBB9lsAHpjcEJQt+4IifuSOSTLBKJObJqMvaO1pIE8LQ==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-async-generator-functions instead.", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/helper-remap-async-to-generator": "^7.1.0", "@babel/plugin-syntax-async-generators": "^7.2.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-proposal-json-strings": { + "node_modules/@babel/plugin-proposal-json-strings": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz", "integrity": "sha512-MAFV1CA/YVmYwZG0fBQyXhmj0BHCB5egZHCKWIFVv/XCxAeVGIHfos3SwDck4LvCllENIAg7xMKOG5kH0dzyUg==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-json-strings instead.", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/plugin-syntax-json-strings": "^7.2.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-proposal-object-rest-spread": { + "node_modules/@babel/plugin-proposal-object-rest-spread": { "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.4.4.tgz", "integrity": "sha512-dMBG6cSPBbHeEBdFXeQ2QLc5gUpg4Vkaz8octD4aoW/ISO+jBOcsuxYL7bsb5WSu8RLP6boxrBIALEHgoHtO9g==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-object-rest-spread instead.", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/plugin-syntax-object-rest-spread": "^7.2.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-proposal-optional-catch-binding": { + "node_modules/@babel/plugin-proposal-optional-catch-binding": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz", "integrity": "sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-catch-binding instead.", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/plugin-syntax-optional-catch-binding": "^7.2.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-async-generators": { + "node_modules/@babel/plugin-syntax-async-generators": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz", "integrity": "sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-json-strings": { + "node_modules/@babel/plugin-syntax-json-strings": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.2.0.tgz", "integrity": "sha512-5UGYnMSLRE1dqqZwug+1LISpA403HzlSfsg6P9VXU6TBjcSHeNlw4DxDx7LgpF+iKZoOG/+uzqoRHTdcUpiZNg==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-object-rest-spread": { + "node_modules/@babel/plugin-syntax-object-rest-spread": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz", "integrity": "sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-optional-catch-binding": { + "node_modules/@babel/plugin-syntax-optional-catch-binding": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz", "integrity": "sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-arrow-functions": { + "node_modules/@babel/plugin-transform-arrow-functions": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz", "integrity": "sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-block-scoped-functions": { + "node_modules/@babel/plugin-transform-block-scoped-functions": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz", "integrity": "sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.9.tgz", + "integrity": "sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-computed-properties": { + "node_modules/@babel/plugin-transform-computed-properties": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz", "integrity": "sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-duplicate-keys": { + "node_modules/@babel/plugin-transform-duplicate-keys": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.2.0.tgz", "integrity": "sha512-q+yuxW4DsTjNceUiTzK0L+AfQ0zD9rWaTLiUqHA8p0gxx7lu1EylenfzjeIWNkPy6e/0VG/Wjw9uf9LueQwLOw==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-exponentiation-operator": { + "node_modules/@babel/plugin-transform-exponentiation-operator": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz", "integrity": "sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-builder-binary-assignment-operator-visitor": "^7.1.0", "@babel/helper-plugin-utils": "^7.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-literals": { + "node_modules/@babel/plugin-transform-literals": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz", "integrity": "sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-member-expression-literals": { + "node_modules/@babel/plugin-transform-member-expression-literals": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.2.0.tgz", "integrity": "sha512-HiU3zKkSU6scTidmnFJ0bMX8hz5ixC93b4MHMiYebmk2lUVNGOboPsqQvx5LzooihijUoLR/v7Nc1rbBtnc7FA==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-modules-amd": { + "node_modules/@babel/plugin-transform-modules-amd": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.2.0.tgz", "integrity": "sha512-mK2A8ucqz1qhrdqjS9VMIDfIvvT2thrEsIQzbaTdc5QFzhDjQv2CkJJ5f6BXIkgbmaoax3zBr2RyvV/8zeoUZw==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-module-transforms": "^7.1.0", "@babel/helper-plugin-utils": "^7.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-modules-umd": { + "node_modules/@babel/plugin-transform-modules-umd": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.2.0.tgz", "integrity": "sha512-BV3bw6MyUH1iIsGhXlOK6sXhmSarZjtJ/vMiD9dNmpY8QXFFQTj+6v92pcfy1iqa8DeAfJFwoxcrS/TUZda6sw==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-module-transforms": "^7.1.0", "@babel/helper-plugin-utils": "^7.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-object-super": { + "node_modules/@babel/plugin-transform-object-super": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.2.0.tgz", "integrity": "sha512-VMyhPYZISFZAqAPVkiYb7dUe2AsVi2/wCT5+wZdsNO31FojQJa9ns40hzZ6U9f50Jlq4w6qwzdBB2uwqZ00ebg==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/helper-replace-supers": "^7.1.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-property-literals": { + "node_modules/@babel/plugin-transform-property-literals": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.2.0.tgz", "integrity": "sha512-9q7Dbk4RhgcLp8ebduOpCbtjh7C0itoLYHXd9ueASKAG/is5PQtMR5VJGka9NKqGhYEGn5ITahd4h9QeBMylWQ==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-reserved-words": { + "node_modules/@babel/plugin-transform-reserved-words": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.2.0.tgz", "integrity": "sha512-fz43fqW8E1tAB3DKF19/vxbpib1fuyCwSPE418ge5ZxILnBhWyhtPgz8eh1RCGGJlwvksHkyxMxh0eenFi+kFw==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-shorthand-properties": { + "node_modules/@babel/plugin-transform-shorthand-properties": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz", "integrity": "sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-spread": { + "node_modules/@babel/plugin-transform-spread": { "version": "7.2.2", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.2.tgz", "integrity": "sha512-KWfky/58vubwtS0hLqEnrWJjsMGaOeSBn90Ezn5Jeg9Z8KKHmELbP1yGylMlm5N6TPKeY9A2+UaSYLdxahg01w==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-sticky-regex": { + "node_modules/@babel/plugin-transform-sticky-regex": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz", "integrity": "sha512-KKYCoGaRAf+ckH8gEL3JHUaFVyNHKe3ASNsZ+AlktgHevvxGigoIttrEJb8iKN03Q7Eazlv1s6cx2B2cQ3Jabw==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/helper-regex": "^7.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-typeof-symbol": { + "node_modules/@babel/plugin-transform-typeof-symbol": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.2.0.tgz", "integrity": "sha512-2LNhETWYxiYysBtrBTqL8+La0jIoQQnIScUJc74OYvUGRmkskNY4EzLCnjHBzdmb38wqtTaixpo1NctEcvMDZw==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/preset-env": { + "node_modules/@babel/preset-env": { "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.4.4.tgz", "integrity": "sha512-FU1H+ACWqZZqfw1x2G1tgtSSYSfxJLkpaUQL37CenULFARDo+h4xJoVHzRoHbK+85ViLciuI7ME4WTIhFRBBlw==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-module-imports": "^7.0.0", "@babel/helper-plugin-utils": "^7.0.0", "@babel/plugin-proposal-async-generator-functions": "^7.2.0", @@ -587,326 +716,375 @@ "js-levenshtein": "^1.1.3", "semver": "^5.5.0" }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/@babel/generator": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.4.4.tgz", + "integrity": "sha512-53UOLK6TVNqKxf7RUh8NE851EHRxOOeVXKbK2bivdb+iziMyk03Sr4eaE9OELCbyZAAafAKPDwF2TPUES5QbxQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.4.4", + "jsesc": "^2.5.1", + "lodash": "^4.17.11", + "source-map": "^0.5.0", + "trim-right": "^1.0.1" + } + }, + "node_modules/@babel/preset-env/node_modules/@babel/helper-call-delegate": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.4.4.tgz", + "integrity": "sha512-l79boDFJ8S1c5hvQvG+rc+wHw6IuH7YldmRKsYtpbawsxURu/paVy57FZMomGK22/JckepaikOkY0MoAmdyOlQ==", + "dev": true, + "dependencies": { + "@babel/helper-hoist-variables": "^7.4.4", + "@babel/traverse": "^7.4.4", + "@babel/types": "^7.4.4" + } + }, + "node_modules/@babel/preset-env/node_modules/@babel/helper-define-map": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.4.4.tgz", + "integrity": "sha512-IX3Ln8gLhZpSuqHJSnTNBWGDE9kdkTEWl21A/K7PQ00tseBwbqCHTvNLHSBd9M0R5rER4h5Rsvj9vw0R5SieBg==", + "dev": true, + "dependencies": { + "@babel/helper-function-name": "^7.1.0", + "@babel/types": "^7.4.4", + "lodash": "^4.17.11" + } + }, + "node_modules/@babel/preset-env/node_modules/@babel/helper-hoist-variables": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.4.4.tgz", + "integrity": "sha512-VYk2/H/BnYbZDDg39hr3t2kKyifAm1W6zHRfhx8jGjIHpQEBv9dry7oQ2f3+J703TLu69nYdxsovl0XYfcnK4w==", + "dev": true, "dependencies": { - "@babel/generator": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.4.4.tgz", - "integrity": "sha512-53UOLK6TVNqKxf7RUh8NE851EHRxOOeVXKbK2bivdb+iziMyk03Sr4eaE9OELCbyZAAafAKPDwF2TPUES5QbxQ==", - "dev": true, - "requires": { - "@babel/types": "^7.4.4", - "jsesc": "^2.5.1", - "lodash": "^4.17.11", - "source-map": "^0.5.0", - "trim-right": "^1.0.1" - } - }, - "@babel/helper-call-delegate": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.4.4.tgz", - "integrity": "sha512-l79boDFJ8S1c5hvQvG+rc+wHw6IuH7YldmRKsYtpbawsxURu/paVy57FZMomGK22/JckepaikOkY0MoAmdyOlQ==", - "dev": true, - "requires": { - "@babel/helper-hoist-variables": "^7.4.4", - "@babel/traverse": "^7.4.4", - "@babel/types": "^7.4.4" - } - }, - "@babel/helper-define-map": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.4.4.tgz", - "integrity": "sha512-IX3Ln8gLhZpSuqHJSnTNBWGDE9kdkTEWl21A/K7PQ00tseBwbqCHTvNLHSBd9M0R5rER4h5Rsvj9vw0R5SieBg==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.1.0", - "@babel/types": "^7.4.4", - "lodash": "^4.17.11" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.4.4.tgz", - "integrity": "sha512-VYk2/H/BnYbZDDg39hr3t2kKyifAm1W6zHRfhx8jGjIHpQEBv9dry7oQ2f3+J703TLu69nYdxsovl0XYfcnK4w==", - "dev": true, - "requires": { - "@babel/types": "^7.4.4" - } - }, - "@babel/helper-module-transforms": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.4.4.tgz", - "integrity": "sha512-3Z1yp8TVQf+B4ynN7WoHPKS8EkdTbgAEy0nU0rs/1Kw4pDgmvYH3rz3aI11KgxKCba2cn7N+tqzV1mY2HMN96w==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.0.0", - "@babel/helper-simple-access": "^7.1.0", - "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/template": "^7.4.4", - "@babel/types": "^7.4.4", - "lodash": "^4.17.11" - } - }, - "@babel/helper-regex": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.4.4.tgz", - "integrity": "sha512-Y5nuB/kESmR3tKjU8Nkn1wMGEx1tjJX076HBMeL3XLQCu6vA/YRzuTW0bbb+qRnXvQGn+d6Rx953yffl8vEy7Q==", - "dev": true, - "requires": { - "lodash": "^4.17.11" - } - }, - "@babel/helper-replace-supers": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.4.4.tgz", - "integrity": "sha512-04xGEnd+s01nY1l15EuMS1rfKktNF+1CkKmHoErDppjAAZL+IUBZpzT748x262HF7fibaQPhbvWUl5HeSt1EXg==", - "dev": true, - "requires": { - "@babel/helper-member-expression-to-functions": "^7.0.0", - "@babel/helper-optimise-call-expression": "^7.0.0", - "@babel/traverse": "^7.4.4", - "@babel/types": "^7.4.4" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz", - "integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==", - "dev": true, - "requires": { - "@babel/types": "^7.4.4" - } - }, - "@babel/parser": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.4.tgz", - "integrity": "sha512-5pCS4mOsL+ANsFZGdvNLybx4wtqAZJ0MJjMHxvzI3bvIsz6sQvzW8XX92EYIkiPtIvcfG3Aj+Ir5VNyjnZhP7w==", - "dev": true - }, - "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.4.4.tgz", - "integrity": "sha512-j1NwnOqMG9mFUOH58JTFsA/+ZYzQLUZ/drqWUqxCYLGeu2JFZL8YrNC9hBxKmWtAuOCHPcRpgv7fhap09Fb4kA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-regex": "^7.4.4", - "regexpu-core": "^4.5.4" - } - }, - "@babel/plugin-transform-async-to-generator": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.4.4.tgz", - "integrity": "sha512-YiqW2Li8TXmzgbXw+STsSqPBPFnGviiaSp6CYOq55X8GQ2SGVLrXB6pNid8HkqkZAzOH6knbai3snhP7v0fNwA==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.0.0", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-remap-async-to-generator": "^7.1.0" - } - }, - "@babel/plugin-transform-block-scoping": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.4.4.tgz", - "integrity": "sha512-jkTUyWZcTrwxu5DD4rWz6rDB5Cjdmgz6z7M7RLXOJyCUkFBawssDGcGh8M/0FTSB87avyJI1HsTwUXp9nKA1PA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "lodash": "^4.17.11" - } - }, - "@babel/plugin-transform-classes": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.4.4.tgz", - "integrity": "sha512-/e44eFLImEGIpL9qPxSRat13I5QNRgBLu2hOQJCF7VLy/otSM/sypV1+XaIw5+502RX/+6YaSAPmldk+nhHDPw==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.0.0", - "@babel/helper-define-map": "^7.4.4", - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-optimise-call-expression": "^7.0.0", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.4.4", - "@babel/helper-split-export-declaration": "^7.4.4", - "globals": "^11.1.0" - } - }, - "@babel/plugin-transform-destructuring": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.4.4.tgz", - "integrity": "sha512-/aOx+nW0w8eHiEHm+BTERB2oJn5D127iye/SUQl7NjHy0lf+j7h4MKMMSOwdazGq9OxgiNADncE+SRJkCxjZpQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-dotall-regex": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.4.4.tgz", - "integrity": "sha512-P05YEhRc2h53lZDjRPk/OektxCVevFzZs2Gfjd545Wde3k+yFDbXORgl2e0xpbq8mLcKJ7Idss4fAg0zORN/zg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-regex": "^7.4.4", - "regexpu-core": "^4.5.4" - } - }, - "@babel/plugin-transform-for-of": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.4.4.tgz", - "integrity": "sha512-9T/5Dlr14Z9TIEXLXkt8T1DU7F24cbhwhMNUziN3hB1AXoZcdzPcTiKGRn/6iOymDqtTKWnr/BtRKN9JwbKtdQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-function-name": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.4.4.tgz", - "integrity": "sha512-iU9pv7U+2jC9ANQkKeNF6DrPy4GBa4NWQtl6dHB4Pb3izX2JOEvDTFarlNsBj/63ZEzNNIAMs3Qw4fNCcSOXJA==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-modules-commonjs": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.4.4.tgz", - "integrity": "sha512-4sfBOJt58sEo9a2BQXnZq+Q3ZTSAUXyK3E30o36BOGnJ+tvJ6YSxF0PG6kERvbeISgProodWuI9UVG3/FMY6iw==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.4.4", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-simple-access": "^7.1.0" - } - }, - "@babel/plugin-transform-modules-systemjs": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.4.4.tgz", - "integrity": "sha512-MSiModfILQc3/oqnG7NrP1jHaSPryO6tA2kOMmAQApz5dayPxWiHqmq4sWH2xF5LcQK56LlbKByCd8Aah/OIkQ==", - "dev": true, - "requires": { - "@babel/helper-hoist-variables": "^7.4.4", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.4.4.tgz", - "integrity": "sha512-Ki+Y9nXBlKfhD+LXaRS7v95TtTGYRAf9Y1rTDiE75zf8YQz4GDaWRXosMfJBXxnk88mGFjWdCRIeqDbon7spYA==", - "dev": true, - "requires": { - "regexp-tree": "^0.1.0" - } - }, - "@babel/plugin-transform-new-target": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.4.4.tgz", - "integrity": "sha512-r1z3T2DNGQwwe2vPGZMBNjioT2scgWzK9BCnDEh+46z8EEwXBq24uRzd65I7pjtugzPSj921aM15RpESgzsSuA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-parameters": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.4.4.tgz", - "integrity": "sha512-oMh5DUO1V63nZcu/ZVLQFqiihBGo4OpxJxR1otF50GMeCLiRx5nUdtokd+u9SuVJrvvuIh9OosRFPP4pIPnwmw==", - "dev": true, - "requires": { - "@babel/helper-call-delegate": "^7.4.4", - "@babel/helper-get-function-arity": "^7.0.0", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-regenerator": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.4.4.tgz", - "integrity": "sha512-Zz3w+pX1SI0KMIiqshFZkwnVGUhDZzpX2vtPzfJBKQQq8WsP/Xy9DNdELWivxcKOCX/Pywge4SiEaPaLtoDT4g==", - "dev": true, - "requires": { - "regenerator-transform": "^0.13.4" - } - }, - "@babel/plugin-transform-template-literals": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.4.4.tgz", - "integrity": "sha512-mQrEC4TWkhLN0z8ygIvEL9ZEToPhG5K7KDW3pzGqOfIGZ28Jb0POUkeWcoz8HnHvhFy6dwAT1j8OzqN8s804+g==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.0.0", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-unicode-regex": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.4.4.tgz", - "integrity": "sha512-il+/XdNw01i93+M9J9u4T7/e/Ue/vWfNZE4IRUQjplu2Mqb/AFTDimkw2tdEdSH50wuQXZAbXSql0UphQke+vA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-regex": "^7.4.4", - "regexpu-core": "^4.5.4" - } - }, - "@babel/template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz", - "integrity": "sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.4.4", - "@babel/types": "^7.4.4" - } - }, - "@babel/traverse": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.4.4.tgz", - "integrity": "sha512-Gw6qqkw/e6AGzlyj9KnkabJX7VcubqPtkUQVAwkc0wUMldr3A/hezNB3Rc5eIvId95iSGkGIOe5hh1kMKf951A==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/generator": "^7.4.4", - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/parser": "^7.4.4", - "@babel/types": "^7.4.4", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.11" - } - }, - "@babel/types": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.4.tgz", - "integrity": "sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.11", - "to-fast-properties": "^2.0.0" - } - } - } - }, - "@babel/template": { + "@babel/types": "^7.4.4" + } + }, + "node_modules/@babel/preset-env/node_modules/@babel/helper-module-transforms": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.4.4.tgz", + "integrity": "sha512-3Z1yp8TVQf+B4ynN7WoHPKS8EkdTbgAEy0nU0rs/1Kw4pDgmvYH3rz3aI11KgxKCba2cn7N+tqzV1mY2HMN96w==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-simple-access": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.4.4", + "@babel/template": "^7.4.4", + "@babel/types": "^7.4.4", + "lodash": "^4.17.11" + } + }, + "node_modules/@babel/preset-env/node_modules/@babel/helper-regex": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.4.4.tgz", + "integrity": "sha512-Y5nuB/kESmR3tKjU8Nkn1wMGEx1tjJX076HBMeL3XLQCu6vA/YRzuTW0bbb+qRnXvQGn+d6Rx953yffl8vEy7Q==", + "dev": true, + "dependencies": { + "lodash": "^4.17.11" + } + }, + "node_modules/@babel/preset-env/node_modules/@babel/helper-replace-supers": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.4.4.tgz", + "integrity": "sha512-04xGEnd+s01nY1l15EuMS1rfKktNF+1CkKmHoErDppjAAZL+IUBZpzT748x262HF7fibaQPhbvWUl5HeSt1EXg==", + "dev": true, + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.0.0", + "@babel/helper-optimise-call-expression": "^7.0.0", + "@babel/traverse": "^7.4.4", + "@babel/types": "^7.4.4" + } + }, + "node_modules/@babel/preset-env/node_modules/@babel/helper-split-export-declaration": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz", + "integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==", + "dev": true, + "dependencies": { + "@babel/types": "^7.4.4" + } + }, + "node_modules/@babel/preset-env/node_modules/@babel/parser": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.4.tgz", + "integrity": "sha512-5pCS4mOsL+ANsFZGdvNLybx4wtqAZJ0MJjMHxvzI3bvIsz6sQvzW8XX92EYIkiPtIvcfG3Aj+Ir5VNyjnZhP7w==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/preset-env/node_modules/@babel/plugin-proposal-unicode-property-regex": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.4.4.tgz", + "integrity": "sha512-j1NwnOqMG9mFUOH58JTFsA/+ZYzQLUZ/drqWUqxCYLGeu2JFZL8YrNC9hBxKmWtAuOCHPcRpgv7fhap09Fb4kA==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-unicode-property-regex instead.", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.4.4", + "regexpu-core": "^4.5.4" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.4.4.tgz", + "integrity": "sha512-YiqW2Li8TXmzgbXw+STsSqPBPFnGviiaSp6CYOq55X8GQ2SGVLrXB6pNid8HkqkZAzOH6knbai3snhP7v0fNwA==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-remap-async-to-generator": "^7.1.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/@babel/plugin-transform-classes": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.4.4.tgz", + "integrity": "sha512-/e44eFLImEGIpL9qPxSRat13I5QNRgBLu2hOQJCF7VLy/otSM/sypV1+XaIw5+502RX/+6YaSAPmldk+nhHDPw==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-define-map": "^7.4.4", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-optimise-call-expression": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-replace-supers": "^7.4.4", + "@babel/helper-split-export-declaration": "^7.4.4", + "globals": "^11.1.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/@babel/plugin-transform-destructuring": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.4.4.tgz", + "integrity": "sha512-/aOx+nW0w8eHiEHm+BTERB2oJn5D127iye/SUQl7NjHy0lf+j7h4MKMMSOwdazGq9OxgiNADncE+SRJkCxjZpQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.4.4.tgz", + "integrity": "sha512-P05YEhRc2h53lZDjRPk/OektxCVevFzZs2Gfjd545Wde3k+yFDbXORgl2e0xpbq8mLcKJ7Idss4fAg0zORN/zg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.4.4", + "regexpu-core": "^4.5.4" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/@babel/plugin-transform-for-of": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.4.4.tgz", + "integrity": "sha512-9T/5Dlr14Z9TIEXLXkt8T1DU7F24cbhwhMNUziN3hB1AXoZcdzPcTiKGRn/6iOymDqtTKWnr/BtRKN9JwbKtdQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/@babel/plugin-transform-function-name": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.4.4.tgz", + "integrity": "sha512-iU9pv7U+2jC9ANQkKeNF6DrPy4GBa4NWQtl6dHB4Pb3izX2JOEvDTFarlNsBj/63ZEzNNIAMs3Qw4fNCcSOXJA==", + "dev": true, + "dependencies": { + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.4.4.tgz", + "integrity": "sha512-4sfBOJt58sEo9a2BQXnZq+Q3ZTSAUXyK3E30o36BOGnJ+tvJ6YSxF0PG6kERvbeISgProodWuI9UVG3/FMY6iw==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.4.4", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-simple-access": "^7.1.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.4.4.tgz", + "integrity": "sha512-MSiModfILQc3/oqnG7NrP1jHaSPryO6tA2kOMmAQApz5dayPxWiHqmq4sWH2xF5LcQK56LlbKByCd8Aah/OIkQ==", + "dev": true, + "dependencies": { + "@babel/helper-hoist-variables": "^7.4.4", + "@babel/helper-plugin-utils": "^7.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.4.4.tgz", + "integrity": "sha512-Ki+Y9nXBlKfhD+LXaRS7v95TtTGYRAf9Y1rTDiE75zf8YQz4GDaWRXosMfJBXxnk88mGFjWdCRIeqDbon7spYA==", + "dev": true, + "dependencies": { + "regexp-tree": "^0.1.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env/node_modules/@babel/plugin-transform-new-target": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.4.4.tgz", + "integrity": "sha512-r1z3T2DNGQwwe2vPGZMBNjioT2scgWzK9BCnDEh+46z8EEwXBq24uRzd65I7pjtugzPSj921aM15RpESgzsSuA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/@babel/plugin-transform-parameters": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.4.4.tgz", + "integrity": "sha512-oMh5DUO1V63nZcu/ZVLQFqiihBGo4OpxJxR1otF50GMeCLiRx5nUdtokd+u9SuVJrvvuIh9OosRFPP4pIPnwmw==", + "dev": true, + "dependencies": { + "@babel/helper-call-delegate": "^7.4.4", + "@babel/helper-get-function-arity": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/@babel/plugin-transform-regenerator": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.4.4.tgz", + "integrity": "sha512-Zz3w+pX1SI0KMIiqshFZkwnVGUhDZzpX2vtPzfJBKQQq8WsP/Xy9DNdELWivxcKOCX/Pywge4SiEaPaLtoDT4g==", + "dev": true, + "dependencies": { + "regenerator-transform": "^0.13.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/@babel/plugin-transform-template-literals": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.4.4.tgz", + "integrity": "sha512-mQrEC4TWkhLN0z8ygIvEL9ZEToPhG5K7KDW3pzGqOfIGZ28Jb0POUkeWcoz8HnHvhFy6dwAT1j8OzqN8s804+g==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.4.4.tgz", + "integrity": "sha512-il+/XdNw01i93+M9J9u4T7/e/Ue/vWfNZE4IRUQjplu2Mqb/AFTDimkw2tdEdSH50wuQXZAbXSql0UphQke+vA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.4.4", + "regexpu-core": "^4.5.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/@babel/template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz", + "integrity": "sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.4.4", + "@babel/types": "^7.4.4" + } + }, + "node_modules/@babel/preset-env/node_modules/@babel/traverse": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.4.4.tgz", + "integrity": "sha512-Gw6qqkw/e6AGzlyj9KnkabJX7VcubqPtkUQVAwkc0wUMldr3A/hezNB3Rc5eIvId95iSGkGIOe5hh1kMKf951A==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.4.4", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.4.4", + "@babel/parser": "^7.4.4", + "@babel/types": "^7.4.4", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.11" + } + }, + "node_modules/@babel/preset-env/node_modules/@babel/types": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.4.tgz", + "integrity": "sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2", + "lodash": "^4.17.11", + "to-fast-properties": "^2.0.0" + } + }, + "node_modules/@babel/template": { "version": "7.4.0", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.0.tgz", "integrity": "sha512-SOWwxxClTTh5NdbbYZ0BmaBVzxzTh2tO/TeLTbF6MO6EzVhHTnff8CdBXx3mEtazFBoysmEM6GU/wF+SuSx4Fw==", "dev": true, - "requires": { + "dependencies": { "@babel/code-frame": "^7.0.0", "@babel/parser": "^7.4.0", "@babel/types": "^7.4.0" } }, - "@babel/traverse": { + "node_modules/@babel/traverse": { "version": "7.4.0", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.4.0.tgz", "integrity": "sha512-/DtIHKfyg2bBKnIN+BItaIlEg5pjAnzHOIQe5w+rHAw/rg9g0V7T4rqPX8BJPfW11kt3koyjAnTNwCzb28Y1PA==", "dev": true, - "requires": { + "dependencies": { "@babel/code-frame": "^7.0.0", "@babel/generator": "^7.4.0", "@babel/helper-function-name": "^7.1.0", @@ -918,843 +1096,1251 @@ "lodash": "^4.17.11" } }, - "@babel/types": { + "node_modules/@babel/types": { "version": "7.4.0", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.0.tgz", "integrity": "sha512-aPvkXyU2SPOnztlgo8n9cEiXW755mgyvueUPcpStqdzoSPm0fjO0vQBjLkt3JKJW7ufikfcnMTTPsN1xaTsBPA==", "dev": true, - "requires": { + "dependencies": { "esutils": "^2.0.2", "lodash": "^4.17.11", "to-fast-properties": "^2.0.0" } }, - "@types/estree": { + "node_modules/@rollup/pluginutils": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", + "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "estree-walker": "^2.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/@rollup/pluginutils/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { "version": "0.0.39", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", "dev": true }, - "@types/node": { + "node_modules/@types/node": { "version": "14.0.1", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.1.tgz", "integrity": "sha512-FAYBGwC+W6F9+huFIDtn43cpy7+SzG+atzRiTfdp3inUKL2hXnd4rG8hylJLIh4+hqrQy1P17kvJByE/z825hA==", "dev": true }, - "@types/resolve": { + "node_modules/@types/resolve": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz", "integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==", "dev": true, - "requires": { + "dependencies": { "@types/node": "*" } }, - "align-text": { + "node_modules/align-text": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", "dev": true, - "requires": { + "dependencies": { "kind-of": "^3.0.2", "longest": "^1.0.1", "repeat-string": "^1.5.2" + }, + "engines": { + "node": ">=0.10.0" } }, - "ansi-styles": { + "node_modules/ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, - "requires": { + "dependencies": { "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" } }, - "babel": { + "node_modules/babel": { "version": "6.23.0", "resolved": "https://registry.npmjs.org/babel/-/babel-6.23.0.tgz", "integrity": "sha1-0NHn2APpdHZb7qMjLU4VPA77kPQ=", - "dev": true + "deprecated": "In 6.x, the babel package has been deprecated in favor of babel-cli. Check https://opencollective.com/babel to support the Babel maintainers", + "dev": true, + "bin": { + "babel": "lib/cli.js", + "babel-external-helpers": "lib/cli.js", + "babel-node": "lib/cli.js" + } }, - "balanced-match": { + "node_modules/balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, - "brace-expansion": { + "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, - "requires": { + "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, - "browserslist": { + "node_modules/browserslist": { "version": "4.16.6", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", "dev": true, - "requires": { + "dependencies": { "caniuse-lite": "^1.0.30001219", "colorette": "^1.2.2", "electron-to-chromium": "^1.3.723", "escalade": "^3.1.1", "node-releases": "^1.1.71" }, - "dependencies": { - "caniuse-lite": { - "version": "1.0.30001228", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz", - "integrity": "sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A==", - "dev": true - }, - "electron-to-chromium": { - "version": "1.3.736", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.736.tgz", - "integrity": "sha512-DY8dA7gR51MSo66DqitEQoUMQ0Z+A2DSXFi7tK304bdTVqczCAfUuyQw6Wdg8hIoo5zIxkU1L24RQtUce1Ioig==", - "dev": true - }, - "node-releases": { - "version": "1.1.72", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz", - "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==", - "dev": true - } - } - }, - "builtin-modules": { + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } + }, + "node_modules/browserslist/node_modules/caniuse-lite": { + "version": "1.0.30001228", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz", + "integrity": "sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } + }, + "node_modules/browserslist/node_modules/electron-to-chromium": { + "version": "1.3.736", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.736.tgz", + "integrity": "sha512-DY8dA7gR51MSo66DqitEQoUMQ0Z+A2DSXFi7tK304bdTVqczCAfUuyQw6Wdg8hIoo5zIxkU1L24RQtUce1Ioig==", + "dev": true + }, + "node_modules/browserslist/node_modules/node-releases": { + "version": "1.1.72", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz", + "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==", + "dev": true + }, + "node_modules/builtin-modules": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.1.0.tgz", "integrity": "sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "camelcase": { + "node_modules/camelcase": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "center-align": { + "node_modules/center-align": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", "dev": true, - "requires": { + "dependencies": { "align-text": "^0.1.3", "lazy-cache": "^1.0.3" + }, + "engines": { + "node": ">=0.10.0" } }, - "chalk": { + "node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, - "requires": { + "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" } }, - "cliui": { + "node_modules/cliui": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", "dev": true, - "requires": { + "dependencies": { "center-align": "^0.1.1", "right-align": "^0.1.1", "wordwrap": "0.0.2" - }, - "dependencies": { - "wordwrap": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", - "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", - "dev": true - } } }, - "color-convert": { + "node_modules/cliui/node_modules/wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, - "requires": { + "dependencies": { "color-name": "1.1.3" } }, - "color-name": { + "node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, - "colorette": { + "node_modules/colorette": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", "dev": true }, - "concat-map": { + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, - "convert-source-map": { + "node_modules/convert-source-map": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", "dev": true, - "requires": { + "dependencies": { "safe-buffer": "~5.1.1" } }, - "core-js-compat": { + "node_modules/core-js-compat": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.0.1.tgz", "integrity": "sha512-2pC3e+Ht/1/gD7Sim/sqzvRplMiRnFQVlPpDVaHtY9l7zZP7knamr3VRD6NyGfHd84MrDC0tAM9ulNxYMW0T3g==", "dev": true, - "requires": { - "browserslist": "^4.5.4", - "core-js": "3.0.1", - "core-js-pure": "3.0.1", - "semver": "^6.0.0" - }, - "dependencies": { - "caniuse-lite": { - "version": "1.0.30000966", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000966.tgz", - "integrity": "sha512-qqLQ/uYrpZmFhPY96VuBkMEo8NhVFBZ9y/Bh+KnvGzGJ5I8hvpIaWlF2pw5gqe4PLAL+ZjsPgMOvoXSpX21Keg==" - }, - "core-js": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.0.1.tgz", - "integrity": "sha512-sco40rF+2KlE0ROMvydjkrVMMG1vYilP2ALoRXcYR4obqbYIuV3Bg+51GEDW+HF8n7NRA+iaA4qD0nD9lo9mew==", - "dev": true - }, - "electron-to-chromium": { - "version": "1.3.130", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.130.tgz", - "integrity": "sha512-UY2DI+gsnqGtQJqO8wXN0DnpJY+29FwJafACj0h18ZShn5besKnrRq6+lXWUbKzdxw92QQcnTqRLgNByOKXcUg==" - }, - "node-releases": { - "version": "1.1.17", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.17.tgz", - "integrity": "sha512-/SCjetyta1m7YXLgtACZGDYJdCSIBAWorDWkGCGZlydP2Ll7J48l7j/JxNYZ+xsgSPbWfdulVS/aY+GdjUsQ7Q==", - "requires": { - "semver": "^5.3.0" - }, - "dependencies": { - "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" - } - } - }, - "semver": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.0.0.tgz", - "integrity": "sha512-0UewU+9rFapKFnlbirLi3byoOuhrSsli/z/ihNnvM24vgF+8sNBiI1LZPBSH9wJKUwaUbw+s3hToDLCXkrghrQ==", - "dev": true - } - } - }, - "core-js-pure": { + "dependencies": { + "browserslist": "^4.5.4", + "core-js": "3.0.1", + "core-js-pure": "3.0.1", + "semver": "^6.0.0" + } + }, + "node_modules/core-js-compat/node_modules/core-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.0.1.tgz", + "integrity": "sha512-sco40rF+2KlE0ROMvydjkrVMMG1vYilP2ALoRXcYR4obqbYIuV3Bg+51GEDW+HF8n7NRA+iaA4qD0nD9lo9mew==", + "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.", + "dev": true + }, + "node_modules/core-js-compat/node_modules/semver": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.0.0.tgz", + "integrity": "sha512-0UewU+9rFapKFnlbirLi3byoOuhrSsli/z/ihNnvM24vgF+8sNBiI1LZPBSH9wJKUwaUbw+s3hToDLCXkrghrQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/core-js-pure": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.0.1.tgz", "integrity": "sha512-mSxeQ6IghKW3MoyF4cz19GJ1cMm7761ON+WObSyLfTu/Jn3x7w4NwNFnrZxgl4MTSvYYepVLNuRtlB4loMwJ5g==", + "deprecated": "core-js-pure@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js-pure.", "dev": true }, - "debug": { + "node_modules/debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", "dev": true, - "requires": { + "dependencies": { "ms": "^2.1.1" } }, - "decamelize": { + "node_modules/decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "deep-equal": { + "node_modules/deep-equal": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", "dev": true }, - "define-properties": { + "node_modules/define-properties": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", "dev": true, - "requires": { + "dependencies": { "object-keys": "^1.0.12" + }, + "engines": { + "node": ">= 0.4" } }, - "defined": { + "node_modules/defined": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", "dev": true }, - "es-abstract": { + "node_modules/es-abstract": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz", "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==", "dev": true, - "requires": { + "dependencies": { "es-to-primitive": "^1.2.0", "function-bind": "^1.1.1", "has": "^1.0.3", "is-callable": "^1.1.4", "is-regex": "^1.0.4", "object-keys": "^1.0.12" + }, + "engines": { + "node": ">= 0.4" } }, - "es-to-primitive": { + "node_modules/es-to-primitive": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", "dev": true, - "requires": { + "dependencies": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" } }, - "escalade": { + "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "escape-string-regexp": { + "node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.8.0" + } }, - "estree-walker": { + "node_modules/estree-walker": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", "dev": true }, - "esutils": { + "node_modules/esutils": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "license": "MIT", + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } }, - "for-each": { + "node_modules/for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", "dev": true, - "requires": { + "dependencies": { "is-callable": "^1.1.3" } }, - "fs.realpath": { + "node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, - "fsevents": { + "node_modules/fsevents": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", "dev": true, - "optional": true + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } }, - "function-bind": { + "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, - "glob": { + "node_modules/glob": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, - "requires": { + "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" } }, - "globals": { + "node_modules/globals": { "version": "11.11.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.11.0.tgz", "integrity": "sha512-WHq43gS+6ufNOEqlrDBxVEbb8ntfXrfAUU2ZOpCxrBdGKW3gyv8mCxAfIBD0DroPKGrJ2eSsXsLtY9MPntsyTw==", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "has": { + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "dev": true, - "requires": { + "dependencies": { "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" } }, - "has-flag": { + "node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "has-symbols": { + "node_modules/has-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.4" + } }, - "inflight": { + "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, - "requires": { + "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, - "inherits": { + "node_modules/inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true }, - "invariant": { + "node_modules/invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", "dev": true, - "requires": { + "dependencies": { "loose-envify": "^1.0.0" } }, - "is-buffer": { + "node_modules/is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true }, - "is-callable": { + "node_modules/is-callable": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.4" + } }, - "is-date-object": { + "node_modules/is-date-object": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.4" + } }, - "is-module": { + "node_modules/is-module": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", "dev": true }, - "is-reference": { + "node_modules/is-reference": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.1.4.tgz", "integrity": "sha512-uJA/CDPO3Tao3GTrxYn6AwkM4nUPJiGGYu5+cB8qbC7WGFlrKZbiRo7SFKxUAEpFUfiHofWCXBUNhvYJMh+6zw==", "dev": true, - "requires": { + "dependencies": { "@types/estree": "0.0.39" } }, - "is-regex": { + "node_modules/is-regex": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", "dev": true, - "requires": { + "dependencies": { "has": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" } }, - "is-symbol": { + "node_modules/is-symbol": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", "dev": true, - "requires": { + "dependencies": { "has-symbols": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" } }, - "js-levenshtein": { + "node_modules/js-levenshtein": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "js-tokens": { + "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true }, - "jsesc": { + "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } }, - "json5": { + "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } }, - "kind-of": { + "node_modules/kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, - "requires": { + "dependencies": { "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" } }, - "lazy-cache": { + "node_modules/lazy-cache": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "lodash": { + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, - "longest": { + "node_modules/longest": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "loose-envify": { + "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", "dev": true, - "requires": { + "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" } }, - "magic-string": { + "node_modules/magic-string": { "version": "0.25.7", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", "dev": true, - "requires": { + "dependencies": { "sourcemap-codec": "^1.4.4" } }, - "minimatch": { + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, - "requires": { + "dependencies": { "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" } }, - "ms": { + "node_modules/ms": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", "dev": true }, - "object-inspect": { + "node_modules/object-inspect": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==", "dev": true }, - "object-keys": { + "node_modules/object-keys": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.0.tgz", "integrity": "sha512-6OO5X1+2tYkNyNEx6TsCxEqFfRWaqx6EtMiSbGrw8Ob8v9Ne+Hl8rBAgLBZn5wjEz3s/s6U1WXFUFOcxxAwUpg==", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.4" + } }, - "once": { + "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, - "requires": { + "dependencies": { "wrappy": "1" } }, - "package-preamble": { + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/package-preamble": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/package-preamble/-/package-preamble-0.1.0.tgz", "integrity": "sha1-xDlzgbcDU0SOQlXqmkml5bQYymg=", - "dev": true + "dev": true, + "bin": { + "preamble": "bin/preamble" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } }, - "path-is-absolute": { + "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "path-parse": { + "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, - "private": { + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/private": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.6" + } }, - "regenerate": { + "node_modules/regenerate": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", "dev": true }, - "regenerate-unicode-properties": { + "node_modules/regenerate-unicode-properties": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.0.2.tgz", "integrity": "sha512-SbA/iNrBUf6Pv2zU8Ekv1Qbhv92yxL4hiDa2siuxs4KKn4oOoMDHXjAf7+Nz9qinUQ46B1LcWEi/PhJfPWpZWQ==", "dev": true, - "requires": { + "dependencies": { "regenerate": "^1.4.0" + }, + "engines": { + "node": ">=4" } }, - "regenerator-transform": { + "node_modules/regenerator-transform": { "version": "0.13.4", "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.13.4.tgz", "integrity": "sha512-T0QMBjK3J0MtxjPmdIMXm72Wvj2Abb0Bd4HADdfijwMdoIsyQZ6fWC7kDFhk2YinBBEMZDL7Y7wh0J1sGx3S4A==", "dev": true, - "requires": { + "dependencies": { "private": "^0.1.6" } }, - "regexp-tree": { + "node_modules/regexp-tree": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.5.tgz", "integrity": "sha512-nUmxvfJyAODw+0B13hj8CFVAxhe7fDEAgJgaotBu3nnR+IgGgZq59YedJP5VYTlkEfqjuK6TuRpnymKdatLZfQ==", - "dev": true + "dev": true, + "bin": { + "regexp-tree": "bin/regexp-tree" + } }, - "regexpu-core": { + "node_modules/regexpu-core": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.5.4.tgz", "integrity": "sha512-BtizvGtFQKGPUcTy56o3nk1bGRp4SZOTYrDtGNlqCQufptV5IkkLN6Emw+yunAJjzf+C9FQFtvq7IoA3+oMYHQ==", "dev": true, - "requires": { + "dependencies": { "regenerate": "^1.4.0", "regenerate-unicode-properties": "^8.0.2", "regjsgen": "^0.5.0", "regjsparser": "^0.6.0", "unicode-match-property-ecmascript": "^1.0.4", "unicode-match-property-value-ecmascript": "^1.1.0" + }, + "engines": { + "node": ">=4" } }, - "regjsgen": { + "node_modules/regjsgen": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.0.tgz", "integrity": "sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA==", "dev": true }, - "regjsparser": { + "node_modules/regjsparser": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.0.tgz", "integrity": "sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ==", "dev": true, - "requires": { + "dependencies": { "jsesc": "~0.5.0" }, - "dependencies": { - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", - "dev": true - } + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" } }, - "repeat-string": { + "node_modules/repeat-string": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10" + } }, - "resolve": { + "node_modules/resolve": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", "dev": true, - "requires": { + "dependencies": { "path-parse": "^1.0.6" } }, - "resumer": { + "node_modules/resumer": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=", "dev": true, - "requires": { + "dependencies": { "through": "~2.3.4" } }, - "right-align": { + "node_modules/right-align": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", "dev": true, - "requires": { + "dependencies": { "align-text": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "rollup": { + "node_modules/rollup": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.10.0.tgz", "integrity": "sha512-7BmpEfUN9P6esJzWIn3DmR//90mW6YwYB1t3y48LpF8ITpYtL8s1kEirMKqUu44dVH/6a/rs0EuwYVL3FuRDoA==", "dev": true, - "requires": { + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { "fsevents": "~2.1.2" } }, - "rollup-plugin-babel": { + "node_modules/rollup-plugin-babel": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/rollup-plugin-babel/-/rollup-plugin-babel-4.4.0.tgz", "integrity": "sha512-Lek/TYp1+7g7I+uMfJnnSJ7YWoD58ajo6Oarhlex7lvUce+RCKRuGRSgztDO3/MF/PuGKmUL5iTHKf208UNszw==", + "deprecated": "This package has been deprecated and is no longer maintained. Please use @rollup/plugin-babel.", "dev": true, - "requires": { + "dependencies": { "@babel/helper-module-imports": "^7.0.0", "rollup-pluginutils": "^2.8.1" + }, + "peerDependencies": { + "@babel/core": "7 || ^7.0.0-rc.2", + "rollup": ">=0.60.0 <3" } }, - "rollup-plugin-commonjs": { + "node_modules/rollup-plugin-commonjs": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/rollup-plugin-commonjs/-/rollup-plugin-commonjs-10.1.0.tgz", "integrity": "sha512-jlXbjZSQg8EIeAAvepNwhJj++qJWNJw1Cl0YnOqKtP5Djx+fFGkp3WRh+W0ASCaFG5w1jhmzDxgu3SJuVxPF4Q==", + "deprecated": "This package has been deprecated and is no longer maintained. Please use @rollup/plugin-commonjs.", "dev": true, - "requires": { + "dependencies": { "estree-walker": "^0.6.1", "is-reference": "^1.1.2", "magic-string": "^0.25.2", "resolve": "^1.11.0", "rollup-pluginutils": "^2.8.1" }, + "peerDependencies": { + "rollup": ">=1.12.0" + } + }, + "node_modules/rollup-plugin-commonjs/node_modules/resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, "dependencies": { - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - } + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "rollup-plugin-node-resolve": { + "node_modules/rollup-plugin-node-resolve": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-5.2.0.tgz", "integrity": "sha512-jUlyaDXts7TW2CqQ4GaO5VJ4PwwaV8VUGA7+km3n6k6xtOEacf61u0VXwN80phY/evMcaS+9eIeJ9MOyDxt5Zw==", + "deprecated": "This package has been deprecated and is no longer maintained. Please use @rollup/plugin-node-resolve.", "dev": true, - "requires": { + "dependencies": { "@types/resolve": "0.0.8", "builtin-modules": "^3.1.0", "is-module": "^1.0.0", "resolve": "^1.11.1", "rollup-pluginutils": "^2.8.1" }, + "peerDependencies": { + "rollup": ">=1.11.0" + } + }, + "node_modules/rollup-plugin-node-resolve/node_modules/resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "dependencies": { + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/rollup-plugin-typescript2": { + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-typescript2/-/rollup-plugin-typescript2-0.35.0.tgz", + "integrity": "sha512-szcIO9hPUx3PhQl91u4pfNAH2EKbtrXaES+m163xQVE5O1CC0ea6YZV/5woiDDW3CR9jF2CszPrKN+AFiND0bg==", + "dev": true, + "license": "MIT", "dependencies": { - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - } + "@rollup/pluginutils": "^4.1.2", + "find-cache-dir": "^3.3.2", + "fs-extra": "^10.0.0", + "semver": "^7.3.7", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "rollup": ">=1.26.3", + "typescript": ">=2.4.0" + } + }, + "node_modules/rollup-plugin-typescript2/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "rollup-pluginutils": { + "node_modules/rollup-pluginutils": { "version": "2.8.2", "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz", "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==", "dev": true, - "requires": { + "dependencies": { "estree-walker": "^0.6.1" } }, - "safe-buffer": { + "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, - "semver": { + "node_modules/semver": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", - "dev": true + "dev": true, + "bin": { + "semver": "bin/semver" + } }, - "source-map": { + "node_modules/source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "sourcemap-codec": { + "node_modules/sourcemap-codec": { "version": "1.4.8", "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "deprecated": "Please use @jridgewell/sourcemap-codec instead", "dev": true }, - "string.prototype.trim": { + "node_modules/string.prototype.trim": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz", "integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=", "dev": true, - "requires": { + "dependencies": { "define-properties": "^1.1.2", "es-abstract": "^1.5.0", "function-bind": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" } }, - "supports-color": { + "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, - "requires": { + "dependencies": { "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "tape": { + "node_modules/tape": { "version": "4.10.1", "resolved": "https://registry.npmjs.org/tape/-/tape-4.10.1.tgz", "integrity": "sha512-G0DywYV1jQeY3axeYnXUOt6ktnxS9OPJh97FGR3nrua8lhWi1zPflLxcAHavZ7Jf3qUfY7cxcVIVFa4mY2IY1w==", "dev": true, - "requires": { + "dependencies": { "deep-equal": "~1.0.1", "defined": "~1.0.0", "for-each": "~0.3.3", @@ -1769,97 +2355,158 @@ "string.prototype.trim": "~1.1.2", "through": "~2.3.8" }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } + "bin": { + "tape": "bin/tape" } }, - "through": { + "node_modules/tape/node_modules/minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", "dev": true }, - "to-fast-properties": { + "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "trim-right": { + "node_modules/trim-right": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" + }, + "node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } }, - "uglify-js": { + "node_modules/uglify-js": { "version": "2.8.29", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", "dev": true, - "requires": { + "dependencies": { "source-map": "~0.5.1", - "uglify-to-browserify": "~1.0.0", "yargs": "~3.10.0" + }, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + }, + "optionalDependencies": { + "uglify-to-browserify": "~1.0.0" } }, - "uglify-to-browserify": { + "node_modules/uglify-to-browserify": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", "dev": true, "optional": true }, - "unicode-canonical-property-names-ecmascript": { + "node_modules/unicode-canonical-property-names-ecmascript": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "unicode-match-property-ecmascript": { + "node_modules/unicode-match-property-ecmascript": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", "dev": true, - "requires": { + "dependencies": { "unicode-canonical-property-names-ecmascript": "^1.0.4", "unicode-property-aliases-ecmascript": "^1.0.4" + }, + "engines": { + "node": ">=4" } }, - "unicode-match-property-value-ecmascript": { + "node_modules/unicode-match-property-value-ecmascript": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz", "integrity": "sha512-hDTHvaBk3RmFzvSl0UVrUmC3PuW9wKVnpoUDYH0JDkSIovzw+J5viQmeYHxVSBptubnr7PbH2e0fnpDRQnQl5g==", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "unicode-property-aliases-ecmascript": { + "node_modules/unicode-property-aliases-ecmascript": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz", "integrity": "sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw==", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } }, - "window-size": { + "node_modules/window-size": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.8.0" + } }, - "wrappy": { + "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, - "yargs": { + "node_modules/yargs": { "version": "3.10.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", "dev": true, - "requires": { + "dependencies": { "camelcase": "^1.0.2", "cliui": "^2.1.0", "decamelize": "^1.0.0", diff --git a/package.json b/package.json index 26fd497..6d281cc 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "browser": "dist/d3-regression.js", "module": "dist/d3-regression.esm.js", "main": "dist/d3-regression.cjs.js", + "types": "dist/types/index.d.ts", "license": "BSD-3-Clause", "bugs": { "url": "https://github.com/HarryStevens/d3-regression/issues" @@ -39,8 +40,9 @@ "rollup-plugin-babel": "^4.4.0", "rollup-plugin-commonjs": "^10.1.0", "rollup-plugin-node-resolve": "^5.2.0", + "rollup-plugin-typescript2": "^0.35.0", "tape": "^4.10.1", + "typescript": "^4.9.5", "uglify-js": "^2.8.29" - }, - "dependencies": {} + } } diff --git a/rollup.config.js b/rollup.config.js index b192098..17a58d4 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -2,11 +2,12 @@ import resolve from "rollup-plugin-node-resolve"; import commonjs from "rollup-plugin-commonjs"; import babel from "rollup-plugin-babel"; import pkg from "./package.json"; +import typescript from "rollup-plugin-typescript2"; export default [ // browser-friendly UMD build { - input: "index.js", + input: "index.ts", output: { name: "d3", file: pkg.browser, @@ -15,6 +16,16 @@ export default [ plugins: [ resolve(), commonjs(), + typescript({ + tsconfig: "./tsconfig.json", + tsconfigOverride: { + compilerOptions: { + declaration: true, + declarationDir: "./dist/types", + allowJs: true + } + } + }), babel({ exclude: ["node_modules/**"], }), @@ -22,19 +33,24 @@ export default [ }, // CommonJS (for Node) and ES module (for bundlers) build. - // (We could have three entries in the configuration array - // instead of two, but it's quicker to generate multiple - // builds from a single configuration where possible, using - // an array for the `output` option, where we can specify - // `file` and `format` for each target) { - input: "index.js", - external: [], // list dependencies here + input: "index.ts", + external: [], // list dependencies here if needed output: [ { file: pkg.main, format: "cjs" }, { file: pkg.module, format: "es" }, ], plugins: [ + typescript({ + tsconfig: "./tsconfig.json", + tsconfigOverride: { + compilerOptions: { + declaration: true, + declarationDir: "./dist/types", + allowJs: true + } + } + }), babel({ exclude: ["node_modules/**"], }), diff --git a/src/exponential.js b/src/exponential.js deleted file mode 100644 index 3b33798..0000000 --- a/src/exponential.js +++ /dev/null @@ -1,62 +0,0 @@ -import { determination } from "./utils/determination"; -import { interpose } from "./utils/interpose"; -import { ols } from "./utils/ols"; -import { visitPoints } from "./utils/points"; - -export default function() { - let x = d => d[0], - y = d => d[1], - domain; - - function exponential(data){ - let n = 0, - Y = 0, - YL = 0, - XY = 0, - XYL = 0, - X2Y = 0, - xmin = domain ? +domain[0] : Infinity, - xmax = domain ? +domain[1] : -Infinity; - - visitPoints(data, x, y, (dx, dy) => { - const ly = Math.log(dy), xy = dx * dy; - ++n; - Y += (dy - Y) / n; - XY += (xy - XY) / n; - X2Y += (dx * xy - X2Y) / n; - YL += (dy * ly - YL) / n; - XYL += (xy * ly - XYL) / n; - - if (!domain){ - if (dx < xmin) xmin = dx; - if (dx > xmax) xmax = dx; - } - }); - - let [a, b] = ols(XY / Y, YL / Y, XYL / Y, X2Y / Y); - a = Math.exp(a); - const fn = x => a * Math.exp(b * x), - out = interpose(xmin, xmax, fn); - - out.a = a; - out.b = b; - out.predict = fn; - out.rSquared = determination(data, x, y, Y, fn); - - return out; - } - - exponential.domain = function(arr){ - return arguments.length ? (domain = arr, exponential) : domain; - } - - exponential.x = function(fn){ - return arguments.length ? (x = fn, exponential) : x; - } - - exponential.y = function(fn){ - return arguments.length ? (y = fn, exponential) : y; - } - - return exponential; -} \ No newline at end of file diff --git a/src/exponential.ts b/src/exponential.ts new file mode 100644 index 0000000..9b6ecc7 --- /dev/null +++ b/src/exponential.ts @@ -0,0 +1,94 @@ +import { determination } from "./utils/determination"; +import { interpose } from "./utils/interpose"; +import { ols } from "./utils/ols"; +import { visitPoints } from "./utils/points"; +import { PredictFunction, Domain, DataPoint, Accessor } from "./types"; + + +export type ExponentialOutput = [DataPoint, DataPoint] & { + a: number; // slope + b: number; // intercept + predict: PredictFunction + rSquared: number; +} + +type ExponentialRegressionRoot = (data: DataPoint[]) => ExponentialOutput + +export interface ExponentialRegression extends ExponentialRegressionRoot { + (data: DataPoint[]): ExponentialOutput; + + domain(): Domain; + domain(arr: Domain): this; + + x(): Accessor; + x(fn: Accessor): this; + + y(): Accessor; + y(fn: Accessor): this; +} + +export default function exponential(): ExponentialRegression { + let x: Accessor = d => d[0], + y: Accessor = d => d[1], + domain: Domain; + + const exponentialRegression = function (data: DataPoint[]): ExponentialOutput { + let n = 0, + Y = 0, + YL = 0, + XY = 0, + XYL = 0, + X2Y = 0, + xmin = domain ? +domain[0] : Infinity, + xmax = domain ? +domain[1] : -Infinity; + + visitPoints(data, x, y, (dx, dy) => { + const ly = Math.log(dy), + xy = dx * dy; + ++n; + Y += (dy - Y) / n; + XY += (xy - XY) / n; + X2Y += (dx * xy - X2Y) / n; + YL += (dy * ly - YL) / n; + XYL += (xy * ly - XYL) / n; + + if (!domain) { + if (dx < xmin) xmin = dx; + if (dx > xmax) xmax = dx; + } + }); + + let [a, b] = ols(XY / Y, YL / Y, XYL / Y, X2Y / Y); + a = Math.exp(a); + + const fn = (xx: number) => a * Math.exp(b * xx); + const out = interpose(xmin, xmax, fn); + + out.a = a; + out.b = b; + out.predict = fn; + out.rSquared = determination(data, x, y, Y, fn); + + return out; + } as ExponentialRegression; + + exponentialRegression.domain = function (arr) { + if (!arguments.length) return domain; + domain = arr; + return exponentialRegression; + } as ExponentialRegression["domain"]; + + exponentialRegression.x = function (fn?: Accessor) { + if (!arguments.length) return x; + x = fn!; + return exponentialRegression; + } as ExponentialRegression["x"]; + + exponentialRegression.y = function (fn?: Accessor) { + if (!arguments.length) return y; + y = fn!; + return exponentialRegression; + } as ExponentialRegression["y"]; + + return exponentialRegression; +} diff --git a/src/linear.js b/src/linear.js deleted file mode 100644 index 64eb61e..0000000 --- a/src/linear.js +++ /dev/null @@ -1,57 +0,0 @@ -import { determination } from "./utils/determination"; -import { ols } from "./utils/ols"; -import { visitPoints } from "./utils/points"; - -export default function(){ - let x = d => d[0], - y = d => d[1], - domain; - - function linear(data){ - let n = 0, - X = 0, // sum of x - Y = 0, // sum of y - XY = 0, // sum of x * y - X2 = 0, // sum of x * x - xmin = domain ? +domain[0] : Infinity, - xmax = domain ? +domain[1] : -Infinity; - - visitPoints(data, x, y, (dx, dy) => { - ++n; - X += (dx - X) / n; - Y += (dy - Y) / n; - XY += (dx * dy - XY) / n; - X2 += (dx * dx - X2) / n; - - if (!domain){ - if (dx < xmin) xmin = dx; - if (dx > xmax) xmax = dx; - } - }); - - const [intercept, slope] = ols(X, Y, XY, X2), - fn = x => slope * x + intercept, - out = [[xmin, fn(xmin)], [xmax, fn(xmax)]]; - - out.a = slope; - out.b = intercept; - out.predict = fn; - out.rSquared = determination(data, x, y, Y, fn); - - return out; - } - - linear.domain = function(arr){ - return arguments.length ? (domain = arr, linear) : domain; - } - - linear.x = function(fn){ - return arguments.length ? (x = fn, linear) : x; - } - - linear.y = function(fn){ - return arguments.length ? (y = fn, linear) : y; - } - - return linear; -} diff --git a/src/linear.ts b/src/linear.ts new file mode 100644 index 0000000..693b0b2 --- /dev/null +++ b/src/linear.ts @@ -0,0 +1,87 @@ +import { determination } from "./utils/determination"; +import { ols } from "./utils/ols"; +import { visitPoints } from "./utils/points"; +import { PredictFunction, Accessor, DataPoint, Domain } from "./types"; + + +export type LinearOutput = [DataPoint, DataPoint] & { + a: number; // slope + b: number; // intercept + predict: PredictFunction + rSquared: number; +} +type LinearRegressionRoot = (data: DataPoint[]) => LinearOutput + + +export interface LinearRegression extends LinearRegressionRoot { + (data: DataPoint[]): LinearOutput; + + domain(): Domain; + domain(arr: Domain): this; + + x(): Accessor; + x(fn: Accessor): this; + + y(): Accessor; + y(fn: Accessor): this; +} + +export default function linear():LinearRegression { + let x: Accessor = (d) => d[0], + y: Accessor = (d) => d[1], + domain: Domain; + + const linearRegression = function (data: DataPoint[]): LinearOutput { + let n = 0, + X = 0, // sum of x + Y = 0, // sum of y + XY = 0, // sum of x*y + X2 = 0, // sum of x*x + xmin = domain ? +domain[0] : Infinity, + xmax = domain ? +domain[1] : -Infinity; + + visitPoints(data, x, y, (dx, dy) => { + ++n; + X += (dx - X) / n; + Y += (dy - Y) / n; + XY += (dx * dy - XY) / n; + X2 += (dx * dx - X2) / n; + + if (!domain) { + if (dx < xmin) xmin = dx; + if (dx > xmax) xmax = dx; + } + }); + + const [intercept, slope] = ols(X, Y, XY, X2); + const fn = (xx: number) => slope * xx + intercept; + + const out = [[xmin, fn(xmin)], [xmax, fn(xmax)]] as LinearOutput; + out.a = slope; + out.b = intercept; + out.predict = fn; + out.rSquared = determination(data, x, y, Y, fn); + + return out; + } as LinearRegression + + linearRegression.domain = function (arr) { + if (!arguments.length) return domain; + domain = arr; + return linearRegression; + } as LinearRegression["domain"]; + + linearRegression.x = function (fn?: Accessor) { + if (!arguments.length) return x; + x = fn!; + return linearRegression; + } as LinearRegression["x"]; + + linearRegression.y = function (fn?: Accessor) { + if (!arguments.length) return y; + y = fn!; + return linearRegression; + } as LinearRegression["y"]; + + return linearRegression; +} diff --git a/src/loess.js b/src/loess.js deleted file mode 100644 index 394b9bc..0000000 --- a/src/loess.js +++ /dev/null @@ -1,136 +0,0 @@ -// Adapted from science.js by Jason Davies -// License: https://github.com/jasondavies/science.js/blob/master/LICENSE -// Source: https://github.com/jasondavies/science.js/blob/master/src/stats/loess.js -// Adapted from vega-statistics by Jeffrey Heer -// License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE -// Source: https://github.com/vega/vega/blob/f21cb8792b4e0cbe2b1a3fd44b0f5db370dbaadb/packages/vega-statistics/src/regression/loess.js -import { median } from "./utils/median"; -import { ols } from "./utils/ols"; -import { points } from "./utils/points"; - -const maxiters = 2, epsilon = 1e-12; - -export default function() { - let x = d => d[0], - y = d => d[1], - bandwidth = .3; - - function loess(data) { - const [xv, yv, ux, uy] = points(data, x, y, true), - n = xv.length, - bw = Math.max(2, ~~(bandwidth * n)), // # nearest neighbors - yhat = new Float64Array(n), - residuals = new Float64Array(n), - robustWeights = new Float64Array(n).fill(1); - - for (let iter = -1; ++iter <= maxiters; ) { - const interval = [0, bw - 1]; - - for (let i = 0; i < n; ++i) { - const dx = xv[i], - i0 = interval[0], - i1 = interval[1], - edge = (dx - xv[i0]) > (xv[i1] - dx) ? i0 : i1; - - let W = 0, X = 0, Y = 0, XY = 0, X2 = 0, - denom = 1 / Math.abs(xv[edge] - dx || 1); // Avoid singularity - - for (let k = i0; k <= i1; ++k) { - const xk = xv[k], - yk = yv[k], - w = tricube(Math.abs(dx - xk) * denom) * robustWeights[k], - xkw = xk * w; - - W += w; - X += xkw; - Y += yk * w; - XY += yk * xkw; - X2 += xk * xkw; - } - - // Linear regression fit - const [a, b] = ols(X / W, Y / W, XY / W, X2 / W); - yhat[i] = a + b * dx; - residuals[i] = Math.abs(yv[i] - yhat[i]); - - updateInterval(xv, i + 1, interval); - } - - if (iter === maxiters) { - break; - } - - const medianResidual = median(residuals); - if (Math.abs(medianResidual) < epsilon) break; - - for (let i = 0, arg, w; i < n; ++i){ - arg = residuals[i] / (6 * medianResidual); - // Default to epsilon (rather than zero) for large deviations - // Keeping weights tiny but non-zero prevents singularites - robustWeights[i] = (arg >= 1) ? epsilon : ((w = 1 - arg * arg) * w); - } - } - - return output(xv, yhat, ux, uy); - } - - loess.bandwidth = function(bw) { - return arguments.length ? (bandwidth = bw, loess) : bandwidth; - }; - - loess.x = function(fn) { - return arguments.length ? (x = fn, loess) : x; - }; - - loess.y = function(fn) { - return arguments.length ? (y = fn, loess) : y; - }; - - return loess; -} - -// Weighting kernel for local regression -function tricube(x) { - return (x = 1 - x * x * x) * x * x; -} - -// Advance sliding window interval of nearest neighbors -function updateInterval(xv, i, interval) { - let val = xv[i], - left = interval[0], - right = interval[1] + 1; - - if (right >= xv.length) return; - - // Step right if distance to new right edge is <= distance to old left edge - // Step when distance is equal to ensure movement over duplicate x values - while (i > left && (xv[right] - val) <= (val - xv[left])) { - interval[0] = ++left; - interval[1] = right; - ++right; - } -} - -// Generate smoothed output points -// Average points with repeated x values -function output(xv, yhat, ux, uy) { - const n = xv.length, out = []; - let i = 0, cnt = 0, prev = [], v; - - for (; i Array; + +export interface LoessRegression extends LoessRegressionRoot { + (data: DataPoint[]): Array; + + bandwidth(): number; + + bandwidth(bw: number): this; + + x(): Accessor; + + x(fn: Accessor): this; + + y(): Accessor; + + y(fn: Accessor): this; +} + + +export default function loess(): LoessRegression { + let x: Accessor = d => d[0], + y: Accessor = d => d[1], + bandwidth = .3; + + const loessRegression = function loessRegression(data: DataPoint[]): Array { + const [xv, yv, ux, uy] = points(data, x, y, true); + const n = xv.length; + const bw = Math.max(2, ~~(bandwidth * n)); // # of nearest neighbors + const yhat = new Float64Array(n); + const residuals = new Float64Array(n); + const robustWeights = new Float64Array(n).fill(1); + + for (let iter = -1; ++iter <= maxiters;) { + const interval = [0, bw - 1] as [number, number]; + + for (let i = 0; i < n; ++i) { + const dx = xv[i]; + const i0 = interval[0]; + const i1 = interval[1]; + const edge = (dx - xv[i0]) > (xv[i1] - dx) ? i0 : i1; + + let W = 0, X = 0, Y = 0, XY = 0, X2 = 0; + const denom = 1 / Math.abs(xv[edge] - dx || 1); + + for (let k = i0; k <= i1; ++k) { + const xk = xv[k]; + const yk = yv[k]; + const w = tricube(Math.abs(dx - xk) * denom) * robustWeights[k]; + const xkw = xk * w; + W += w; + X += xkw; + Y += yk * w; + XY += yk * xkw; + X2 += xk * xkw; + } + + // Linear regression fit + const [a, b] = ols(X / W, Y / W, XY / W, X2 / W); + yhat[i] = a + b * dx; + residuals[i] = Math.abs(yv[i] - yhat[i]); + + updateInterval(xv, i + 1, interval); + } + + if (iter === maxiters) { + break; + } + + const medianResidual = median(residuals); + if (Math.abs(medianResidual) < epsilon) break; + + for (let i = 0, arg, w; i < n; ++i) { + arg = residuals[i] / (6 * medianResidual); + // Default to epsilon (rather than zero) for large deviations + // Keeping weights tiny but non-zero prevents singularites + robustWeights[i] = (arg >= 1) ? epsilon : ((w = 1 - arg * arg) * w); + } + } + + return output(xv, yhat, ux, uy); + } as LoessRegression + + loessRegression.bandwidth = function (bw?: number) { + if (!arguments.length) return bandwidth; + bandwidth = bw!; + return loessRegression; + } as LoessRegression["bandwidth"]; + + loessRegression.x = function (fn?: Accessor) { + if (!arguments.length) return x; + x = fn!; + return loessRegression; + } as LoessRegression["x"]; + + loessRegression.y = function (fn?: Accessor) { + if (!arguments.length) return y; + y = fn!; + return loessRegression; + } as LoessRegression["y"]; + + return loessRegression; +} + +// Weighting kernel for local regression +function tricube(x: number): number { + return (x = 1 - x * x * x) * x * x; +} + +// Advance sliding window interval of nearest neighbors +function updateInterval(xv: Float64Array, i: number, interval: [number, number]) { + let val = xv[i], left = interval[0], right = interval[1] + 1; + if (right >= xv.length) return; + + // Step right if distance to new right edge is <= distance to old left edge + // Step when distance is equal to ensure movement over duplicate x values + while (i > left && (xv[right] - val) <= (val - xv[left])) { + interval[0] = ++left; + interval[1] = right; + ++right; + } +} + +// Generate smoothed output points +// Average points with repeated x values +function output(xv: Float64Array, yhat: Float64Array, ux: number, uy: number): Array<[number, number]> { + const n = xv.length, out = []; + + let i = 0, cnt = 0, prev: any = [], v; + + for (; i < n; ++i) { + v = xv[i] + ux; + if (prev[0] === v) { + // Average output values via online update + prev[1] += (yhat[i] - prev[1]) / (++cnt); + } else { + // Add new output point + cnt = 0; + prev[1] += uy; + prev = [v, yhat[i]]; + out.push(prev); + } + } + prev[1] += uy; + + return out; +} diff --git a/src/logarithmic.js b/src/logarithmic.js deleted file mode 100644 index 1d14d37..0000000 --- a/src/logarithmic.js +++ /dev/null @@ -1,65 +0,0 @@ -import { determination } from "./utils/determination"; -import { interpose } from "./utils/interpose"; -import { ols } from "./utils/ols"; -import { visitPoints } from "./utils/points"; - -export default function() { - let x = d => d[0], - y = d => d[1], - base = Math.E, - domain; - - function logarithmic(data){ - let n = 0, - X = 0, - Y = 0, - XY = 0, - X2 = 0, - xmin = domain ? +domain[0] : Infinity, - xmax = domain ? +domain[1] : -Infinity, - lb = Math.log(base); - - visitPoints(data, x, y, (dx, dy) => { - const lx = Math.log(dx) / lb; - ++n; - X += (lx - X) / n; - Y += (dy - Y) / n; - XY += (lx * dy - XY) / n; - X2 += (lx * lx - X2) / n; - - if (!domain){ - if (dx < xmin) xmin = dx; - if (dx > xmax) xmax = dx; - } - }); - - const [intercept, slope] = ols(X, Y, XY, X2), - fn = x => slope * Math.log(x) / lb + intercept, - out = interpose(xmin, xmax, fn); - - out.a = slope; - out.b = intercept; - out.predict = fn; - out.rSquared = determination(data, x, y, Y, fn); - - return out; - } - - logarithmic.domain = function(arr){ - return arguments.length ? (domain = arr, logarithmic) : domain; - } - - logarithmic.x = function(fn){ - return arguments.length ? (x = fn, logarithmic) : x; - } - - logarithmic.y = function(fn){ - return arguments.length ? (y = fn, logarithmic) : y; - } - - logarithmic.base = function(n){ - return arguments.length ? (base = n, logarithmic) : base; - } - - return logarithmic; -} \ No newline at end of file diff --git a/src/logarithmic.ts b/src/logarithmic.ts new file mode 100644 index 0000000..db356f6 --- /dev/null +++ b/src/logarithmic.ts @@ -0,0 +1,100 @@ +import { determination } from "./utils/determination"; +import { interpose } from "./utils/interpose"; +import { ols } from "./utils/ols"; +import { visitPoints } from "./utils/points"; +import { PredictFunction, DataPoint, Accessor, Domain } from "./types"; + + +type OutputRoot = [DataPoint, DataPoint] +type LogarithmicOutput = OutputRoot & { + a: number; // slope + b: number; // intercept + predict: PredictFunction + rSquared: number; +} +type LogarithmicRegressionRoot = (data: DataPoint[]) => LogarithmicOutput + +export interface LogarithmicRegression extends LogarithmicRegressionRoot { + (data: DataPoint[]): LogarithmicOutput; + + domain(): Domain; + domain(arr: Domain): this; + + x(): Accessor; + x(fn: Accessor): this; + + y(): Accessor; + y(fn: Accessor): this; + + base(): number; + base(b: number): this; +} + +export default function logarithmic(): LogarithmicRegression { + let x: Accessor = d => d[0], + y: Accessor = d => d[1], + base: number = Math.E, + domain: Domain; + + const logarithmicRegression = function logarithmicRegression(data: DataPoint[]): LogarithmicOutput { + let n = 0, + X = 0, + Y = 0, + XY = 0, + X2 = 0, + xmin = domain ? +domain[0] : Infinity, + xmax = domain ? +domain[1] : -Infinity, + lb = Math.log(base); + + visitPoints(data, x, y, (dx, dy) => { + const lx = Math.log(dx) / lb; + ++n; + X += (lx - X) / n; + Y += (dy - Y) / n; + XY += (lx * dy - XY) / n; + X2 += (lx * lx - X2) / n; + + if (!domain) { + if (dx < xmin) xmin = dx; + if (dx > xmax) xmax = dx; + } + }); + + const [intercept, slope] = ols(X, Y, XY, X2); + const fn = (xx: number) => slope * Math.log(xx) / lb + intercept; + const out = interpose(xmin, xmax, fn) as LogarithmicOutput; + + out.a = slope; + out.b = intercept; + out.predict = fn; + out.rSquared = determination(data, x, y, Y, fn); + + return out; + } as LogarithmicRegression; + + logarithmicRegression.domain = function (arr?: [number, number]) { + if (!arguments.length) return domain; + domain = arr; + return logarithmicRegression; + } as LogarithmicRegression["domain"]; + + logarithmicRegression.x = function (fn?: Accessor) { + if (!arguments.length) return x; + x = fn!; + return logarithmicRegression; + } as LogarithmicRegression["x"]; + + logarithmicRegression.y = function (fn?: Accessor) { + if (!arguments.length) return y; + y = fn!; + return logarithmicRegression; + } as LogarithmicRegression["y"]; + + logarithmicRegression.base = function (b?: number) { + if (!arguments.length) return base; + base = b!; + return logarithmicRegression; + } as LogarithmicRegression["base"]; + + return logarithmicRegression; +} diff --git a/src/polynomial.js b/src/polynomial.js deleted file mode 100644 index 4b3a650..0000000 --- a/src/polynomial.js +++ /dev/null @@ -1,169 +0,0 @@ -import { determination } from "./utils/determination"; -import { interpose } from "./utils/interpose"; -import { points, visitPoints } from "./utils/points"; -import linear from "./linear"; -import quad from "./quadratic"; - -// Adapted from regression-js by Tom Alexander -// Source: https://github.com/Tom-Alexander/regression-js/blob/master/src/regression.js#L246 -// License: https://github.com/Tom-Alexander/regression-js/blob/master/LICENSE -// ...with ideas from vega-statistics by Jeffrey Heer -// Source: https://github.com/vega/vega/blob/f21cb8792b4e0cbe2b1a3fd44b0f5db370dbaadb/packages/vega-statistics/src/regression/poly.js -// License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE -export default function(){ - let x = d => d[0], - y = d => d[1], - order = 3, - domain; - - function polynomial(data) { - // Use more efficient methods for lower orders - if (order === 1) { - const o = linear().x(x).y(y).domain(domain)(data); - o.coefficients = [o.b, o.a]; - delete o.a; delete o.b; - return o; - } - if (order === 2) { - const o = quad().x(x).y(y).domain(domain)(data); - o.coefficients = [o.c, o.b, o.a]; - delete o.a; delete o.b; delete o.c; - return o; - } - - const [xv, yv, ux, uy] = points(data, x, y), - n = xv.length, - lhs = [], - rhs = [], - k = order + 1; - - let Y = 0, n0 = 0, - xmin = domain ? +domain[0] : Infinity, - xmax = domain ? +domain[1] : -Infinity; - - visitPoints(data, x, y, (dx, dy) => { - ++n0 - Y += (dy - Y) / n0; - if (!domain){ - if (dx < xmin) xmin = dx; - if (dx > xmax) xmax = dx; - } - }); - - let i, j, l, v, c; - - for (i = 0; i < k; ++i) { - for (l = 0, v = 0; l < n; ++l) { - v += Math.pow(xv[l], i) * yv[l]; - } - lhs.push(v); - - c = new Float64Array(k); - for (j=0; j { - x -= ux; - let y = uy + coef[0] + coef[1] * x + coef[2] * x * x; - for (i = 3; i < k; ++i) y += coef[i] * Math.pow(x, i); - return y; - }, - out = interpose(xmin, xmax, fn); - - out.coefficients = uncenter(k, coef, -ux, uy); - out.predict = fn; - out.rSquared = determination(data, x, y, Y, fn); - - return out; - } - - polynomial.domain = function(arr){ - return arguments.length ? (domain = arr, polynomial) : domain; - } - - polynomial.x = function(fn){ - return arguments.length ? (x = fn, polynomial) : x; - } - - polynomial.y = function(fn){ - return arguments.length ? (y = fn, polynomial) : y; - } - - polynomial.order = function(n){ - return arguments.length ? (order = n, polynomial) : order; - } - - return polynomial; -} - -function uncenter(k, a, x, y) { - const z = Array(k); - let i, j, v, c; - - // initialize to zero - for (i = 0; i < k; ++i) z[i] = 0; - - // polynomial expansion - for (i = k - 1; i >= 0; --i) { - v = a[i]; - c = 1; - z[i] += v; - for (j = 1; j <= i; ++j) { - c *= (i + 1 - j) / j; // binomial coefficent - z[i-j] += v * Math.pow(x, j) * c; - } - } - - // bias term - z[0] += y; - - return z; -} - -// Given an array for a two-dimensional matrix and the polynomial order, -// solve A * x = b using Gaussian elimination. -function gaussianElimination(matrix) { - const n = matrix.length - 1, - coef = []; - - let i, j, k, r, t; - - for (i = 0; i < n; ++i) { - r = i; // max row - for (j = i + 1; j < n; ++j) { - if (Math.abs(matrix[i][j]) > Math.abs(matrix[i][r])) { - r = j; - } - } - - for (k = i; k < n + 1; ++k) { - t = matrix[k][i]; - matrix[k][i] = matrix[k][r]; - matrix[k][r] = t; - } - - for (j = i + 1; j < n; ++j) { - for (k = n; k >= i; k--) { - matrix[k][j] -= (matrix[k][i] * matrix[i][j]) / matrix[i][i]; - } - } - } - - for (j = n - 1; j >= 0; --j) { - t = 0; - for (k = j + 1; k < n; ++k) { - t += matrix[k][j] * coef[k]; - } - coef[j] = (matrix[n][j] - t) / matrix[j][j]; - } - - return coef; -} \ No newline at end of file diff --git a/src/polynomial.ts b/src/polynomial.ts new file mode 100644 index 0000000..d26cf1d --- /dev/null +++ b/src/polynomial.ts @@ -0,0 +1,218 @@ +// Adapted from regression-js by Tom Alexander +// Source: https://github.com/Tom-Alexander/regression-js/blob/master/src/regression.js#L246 +// License: https://github.com/Tom-Alexander/regression-js/blob/master/LICENSE +// ...with ideas from vega-statistics by Jeffrey Heer +// Source: https://github.com/vega/vega/blob/f21cb8792b4e0cbe2b1a3fd44b0f5db370dbaadb/packages/vega-statistics/src/regression/poly.js +// License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE + + +import { determination } from "./utils/determination"; +import { interpose } from "./utils/interpose"; +import { points, visitPoints } from "./utils/points"; +import linear from "./linear"; +import quad from "./quadratic"; +import { PredictFunction, Accessor, DataPoint, Domain } from "./types"; + + +type PolynomialOutputRoot = [DataPoint, DataPoint] + +export type PolynomialOutput = PolynomialOutputRoot & { + coefficients: number[]; + predict: PredictFunction; + rSquared: number; +} + +type PolynomialRegressionRoot = (data: DataPoint[]) => PolynomialOutput; + +export interface PolynomialRegression extends PolynomialRegressionRoot { + (data: DataPoint[]): PolynomialOutput; + + domain(): Domain; + + domain(domain?: Domain): PolynomialRegression; + + x(): Accessor; + + x(x: Accessor): PolynomialRegression; + + y(): Accessor; + + y(y: Accessor): PolynomialRegression; + + order(): number; + + order(order: number): PolynomialRegression; +} + + +export default function polynomial(): PolynomialRegression { + let x: Accessor = d => d[0], + y: Accessor = d => d[1], + order = 3, + domain: Domain; + + const polynomialRegression = function polynomialRegression(data: DataPoint[]): PolynomialOutput { + // Shortcut for lower-order polynomials: + if (order === 1) { + const o = linear().x(x).y(y).domain(domain)(data); + const result = [ + o[0], + o[1], + ] as PolynomialOutput; + result.coefficients = [o.b, o.a]; + result.predict = o.predict; + result.rSquared = o.rSquared; + return result; + } + if (order === 2) { + const o = quad().x(x).y(y).domain(domain)(data); + const result = [ + o[0], + o[1], + ] as PolynomialOutput; + result.coefficients = [o.c, o.b, o.a]; + result.predict = o.predict; + result.rSquared = o.rSquared; + return result; + } + + const [xv, yv, ux, uy] = points(data, x, y); + const n = xv.length; + const k = order + 1; + const lhs: number[] = []; + const rhs: Float64Array[] = []; + + let Y = 0, + n0 = 0, + xmin = domain ? +domain[0] : Infinity, + xmax = domain ? +domain[1] : -Infinity; + + visitPoints(data, x, y, (dx, dy) => { + n0++; + Y += (dy - Y) / n0; + if (!domain) { + if (dx < xmin) xmin = dx; + if (dx > xmax) xmax = dx; + } + }); + + // Build normal equations + for (let i = 0; i < k; i++) { + // LHS + let v = 0; + for (let l = 0; l < n; l++) { + v += Math.pow(xv[l], i) * yv[l]; + } + lhs.push(v); + + // RHS + const c = new Float64Array(k); + for (let j = 0; j < k; j++) { + let v2 = 0; + for (let l = 0; l < n; l++) { + v2 += Math.pow(xv[l], i + j); + } + c[j] = v2; + } + rhs.push(c); + } + rhs.push(new Float64Array(lhs)); + + const coef = gaussianElimination(rhs); + const fn = (xx: number) => { + let shifted = xx - ux; + let val = uy + coef[0]; + for (let i = 1; i < k; i++) { + val += coef[i] * Math.pow(shifted, i); + } + return val; + }; + + const out = interpose(xmin, xmax, fn); + out.coefficients = uncenter(k, coef, -ux, uy); + out.predict = fn; + out.rSquared = determination(data, x, y, Y, fn); + + return out; + } as PolynomialRegression; + + polynomialRegression.domain = function (arr?: [number, number]) { + if (!arguments.length) return domain; + domain = arr; + return polynomialRegression; + } as PolynomialRegression["domain"]; + + polynomialRegression.x = function (fn?: Accessor) { + if (!arguments.length) return x; + x = fn!; + return polynomialRegression; + } as PolynomialRegression["x"]; + + polynomialRegression.y = function (fn?: Accessor) { + if (!arguments.length) return y; + y = fn!; + return polynomialRegression; + } as PolynomialRegression["y"]; + + polynomialRegression.order = function (n?: number) { + if (!arguments.length) return order; + order = n!; + return polynomialRegression; + } as PolynomialRegression["order"]; + + return polynomialRegression; +} + +function uncenter(k: number, a: number[], x: number, y: number): number[] { + const z = new Array(k).fill(0); + for (let i = k - 1; i >= 0; --i) { + let v = a[i]; + z[i] += v; + let c = 1; + for (let j = 1; j <= i; ++j) { + c *= (i + 1 - j) / j; // binomial coefficient + z[i - j] += v * Math.pow(x, j) * c; + } + } + // bias term + z[0] += y; + return z; +} + +// Solve A * x = b using Gaussian elimination +function gaussianElimination(matrix: Float64Array[]): number[] { + const n = matrix.length - 1; + const coef = new Array(n); + + for (let i = 0; i < n; i++) { + let r = i; + // find pivot row + for (let j = i + 1; j < n; j++) { + if (Math.abs(matrix[i][j]) > Math.abs(matrix[i][r])) { + r = j; + } + } + // swap columns + for (let k = i; k < n + 1; k++) { + const t = matrix[k][i]; + matrix[k][i] = matrix[k][r]; + matrix[k][r] = t; + } + // reduce + for (let j = i + 1; j < n; j++) { + for (let k = n; k >= i; k--) { + matrix[k][j] -= (matrix[k][i] * matrix[i][j]) / matrix[i][i]; + } + } + } + + for (let j = n - 1; j >= 0; j--) { + let t = 0; + for (let k = j + 1; k < n; k++) { + t += matrix[k][j] * coef[k]; + } + coef[j] = (matrix[n][j] - t) / matrix[j][j]; + } + + return coef; +} diff --git a/src/power.js b/src/power.js deleted file mode 100644 index 589efed..0000000 --- a/src/power.js +++ /dev/null @@ -1,63 +0,0 @@ -import { determination } from "./utils/determination"; -import { interpose } from "./utils/interpose"; -import { ols } from "./utils/ols"; -import { visitPoints } from "./utils/points"; - -export default function() { - let x = d => d[0], - y = d => d[1], - domain; - - function power(data){ - let n = 0, - X = 0, - Y = 0, - XY = 0, - X2 = 0, - YS = 0, - xmin = domain ? +domain[0] : Infinity, - xmax = domain ? +domain[1] : -Infinity; - - visitPoints(data, x, y, (dx, dy) => { - const lx = Math.log(dx), - ly = Math.log(dy); - ++n; - X += (lx - X) / n; - Y += (ly - Y) / n; - XY += (lx * ly - XY) / n; - X2 += (lx * lx - X2) / n; - YS += (dy - YS) / n; - - if (!domain){ - if (dx < xmin) xmin = dx; - if (dx > xmax) xmax = dx; - } - }); - - let [a, b] = ols(X, Y, XY, X2); - a = Math.exp(a); - const fn = x => a * Math.pow(x, b), - out = interpose(xmin, xmax, fn); - - out.a = a; - out.b = b; - out.predict = fn; - out.rSquared = determination(data, x, y, YS, fn); - - return out; - } - - power.domain = function(arr){ - return arguments.length ? (domain = arr, power) : domain; - } - - power.x = function(fn){ - return arguments.length ? (x = fn, power) : x; - } - - power.y = function(fn){ - return arguments.length ? (y = fn, power) : y; - } - - return power; -} \ No newline at end of file diff --git a/src/power.ts b/src/power.ts new file mode 100644 index 0000000..7fd8aa6 --- /dev/null +++ b/src/power.ts @@ -0,0 +1,93 @@ +import { determination } from "./utils/determination"; +import { interpose } from "./utils/interpose"; +import { ols } from "./utils/ols"; +import { visitPoints } from "./utils/points"; +import { PredictFunction, DataPoint, Accessor, Domain } from "./types"; + +type PowerOutputRoot = [DataPoint, DataPoint]; + +interface PowerOutput extends PowerOutputRoot { + a: number; + b: number; + predict: PredictFunction; + rSquared: number; +} + +type PowerRegressionRoot = (data: DataPoint[]) => PowerOutput; +interface PowerRegression extends PowerRegressionRoot{ + (data: DataPoint[]): PowerOutput; + domain(): Domain; + domain(domain?: Domain): PowerRegression; + + x(): Accessor; + x(x: Accessor): PowerRegression; + + y(): Accessor; + y(y: Accessor): PowerRegression; +} + +export default function power(): PowerRegression { + let x: Accessor = d => d[0], + y: Accessor = d => d[1], + domain: Domain; + + const powerRegression =function powerRegression(data: DataPoint[]): PowerOutput { + let n = 0, + X = 0, + Y = 0, + XY = 0, + X2 = 0, + YS = 0, + xmin = domain ? +domain[0] : Infinity, + xmax = domain ? +domain[1] : -Infinity; + + visitPoints(data, x, y, (dx, dy) => { + const lx = Math.log(dx), + ly = Math.log(dy); + ++n; + X += (lx - X) / n; + Y += (ly - Y) / n; + XY += (lx * ly - XY) / n; + X2 += (lx * lx - X2) / n; + YS += (dy - YS) / n; + + if (!domain) { + if (dx < xmin) xmin = dx; + if (dx > xmax) xmax = dx; + } + }); + + let [a, b] = ols(X, Y, XY, X2); + a = Math.exp(a); + + const fn = (xx: number) => a * Math.pow(xx, b); + const out = interpose(xmin, xmax, fn) as PowerOutput; + + out.a = a; + out.b = b; + out.predict = fn; + out.rSquared = determination(data, x, y, YS, fn); + + return out; + } as PowerRegression; + + powerRegression.domain = function(arr?: Domain) { + if (!arguments.length) return domain; + domain = arr; + return powerRegression; + } as PowerRegression["domain"]; + + powerRegression.x = function(fn?: Accessor) { + if (!arguments.length) return x; + x = fn!; + return powerRegression; + } as PowerRegression["x"]; + + powerRegression.y = function(fn?: Accessor) { + if (!arguments.length) return y; + y = fn!; + return powerRegression; + } as PowerRegression["y"]; + + return powerRegression; +} diff --git a/src/quadratic.js b/src/quadratic.js deleted file mode 100644 index 34109f1..0000000 --- a/src/quadratic.js +++ /dev/null @@ -1,80 +0,0 @@ -import { determination } from "./utils/determination"; -import { interpose } from "./utils/interpose"; -import { points, visitPoints } from "./utils/points"; - -export default function(){ - let x = d => d[0], - y = d => d[1], - domain; - - function quadratic(data){ - const [xv, yv, ux, uy] = points(data, x, y), - n = xv.length; - - let X2 = 0, - X3 = 0, - X4 = 0, - XY = 0, - X2Y = 0, - i, dx, dy, x2; - - for (i = 0; i < n;) { - dx = xv[i]; - dy = yv[i++]; - x2 = dx * dx; - X2 += (x2 - X2) / i; - X3 += (x2 * dx - X3) / i; - X4 += (x2 * x2 - X4) / i; - XY += (dx * dy - XY) / i; - X2Y += (x2 * dy - X2Y) / i; - } - - let Y = 0, - n0 = 0, - xmin = domain ? +domain[0] : Infinity, - xmax = domain ? +domain[1] : -Infinity; - - visitPoints(data, x, y, (dx, dy) => { - n0++; - Y += (dy - Y) / n0; - if (!domain){ - if (dx < xmin) xmin = dx; - if (dx > xmax) xmax = dx; - } - }); - - const X2X2 = X4 - (X2 * X2), - d = (X2 * X2X2 - X3 * X3), - a = (X2Y * X2 - XY * X3) / d, - b = (XY * X2X2 - X2Y * X3) / d, - c = -a * X2, - fn = x => { - x = x - ux; - return a * x * x + b * x + c + uy; - }; - - const out = interpose(xmin, xmax, fn); - - out.a = a; - out.b = b - 2 * a * ux; - out.c = c - b * ux + a * ux * ux + uy; - out.predict = fn; - out.rSquared = determination(data, x, y, Y, fn); - - return out; - } - - quadratic.domain = function(arr){ - return arguments.length ? (domain = arr, quadratic) : domain; - } - - quadratic.x = function(fn){ - return arguments.length ? (x = fn, quadratic) : x; - } - - quadratic.y = function(fn){ - return arguments.length ? (y = fn, quadratic) : y; - } - - return quadratic; -} \ No newline at end of file diff --git a/src/quadratic.ts b/src/quadratic.ts new file mode 100644 index 0000000..e89f745 --- /dev/null +++ b/src/quadratic.ts @@ -0,0 +1,115 @@ +import { determination } from "./utils/determination"; +import { interpose } from "./utils/interpose"; +import { points, visitPoints } from "./utils/points"; +import { Accessor, DataPoint, PredictFunction, Domain } from "./types"; + +type QuadraticOutputRoot = [DataPoint, DataPoint]; + +interface QuadraticOutput extends QuadraticOutputRoot { + a: number; + b: number; + c: number; + predict: PredictFunction; + rSquared: number; +} + +type QuadraticRegressionRoot = (data: DataPoint[]) => QuadraticOutput; + +interface QuadraticRegression extends QuadraticRegressionRoot { + (data: DataPoint[]): QuadraticOutput; + + domain(): Domain; + + domain(domain?: Domain): QuadraticRegression; + + x(): Accessor; + + x(x: Accessor): QuadraticRegression; + + y(): Accessor; + + y(y: Accessor): QuadraticRegression; +} + + +export default function quadratic(): QuadraticRegression { + let x: Accessor = d => d[0], + y: Accessor = d => d[1], + domain: Domain; + + const quadraticRegression = function quadraticRegression(data: DataPoint[]): QuadraticOutput { + const [xv, yv, ux, uy] = points(data, x, y); + const n = xv.length; + + let X2 = 0, + X3 = 0, + X4 = 0, + XY = 0, + X2Y = 0, + i, dx, dy, x2; + + for (i = 0; i < n;) { + dx = xv[i]; + dy = yv[i++]; + x2 = dx * dx; + X2 += (x2 - X2) / i; + X3 += ((x2 * dx) - X3) / i; + X4 += ((x2 * x2) - X4) / i; + XY += ((dx * dy) - XY) / i; + X2Y += ((x2 * dy) - X2Y) / i; + } + + let Y = 0, + n0 = 0, + xmin = domain ? +domain[0] : Infinity, + xmax = domain ? +domain[1] : -Infinity; + + visitPoints(data, x, y, (dx2, dy2) => { + n0++; + Y += (dy2 - Y) / n0; + if (!domain) { + if (dx2 < xmin) xmin = dx2; + if (dx2 > xmax) xmax = dx2; + } + }); + + const X2X2 = X4 - (X2 * X2); + const d = (X2 * X2X2 - X3 * X3); + const a = (X2Y * X2 - XY * X3) / d; + const b = (XY * X2X2 - X2Y * X3) / d; + const c = -a * X2; + const fn = (xx: number) => { + const shifted = xx - ux; + return a * shifted * shifted + b * shifted + c + uy; + }; + + const out = interpose(xmin, xmax, fn) as QuadraticOutput; + out.a = a; + out.b = b - 2 * a * ux; + out.c = c - b * ux + a * ux * ux + uy; + out.predict = fn; + out.rSquared = determination(data, x, y, Y, fn); + + return out; + } as QuadraticRegression; + + quadraticRegression.domain = function (arr?: Domain) { + if (!arguments.length) return domain; + domain = arr; + return quadraticRegression; + } as QuadraticRegression["domain"]; + + quadraticRegression.x = function (fn?: Accessor) { + if (!arguments.length) return x; + x = fn!; + return quadraticRegression; + } as QuadraticRegression["x"]; + + quadraticRegression.y = function (fn?: Accessor) { + if (!arguments.length) return y; + y = fn!; + return quadraticRegression; + } as QuadraticRegression["y"]; + + return quadraticRegression; +} diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000..9053b40 --- /dev/null +++ b/src/types.ts @@ -0,0 +1,5 @@ + +export type DataPoint = [number, number]; +export type Accessor = (d: DataPoint, i?: number, data?: DataPoint[]) => number; +export type PredictFunction = (x: number) => number; +export type Domain = [number, number] | undefined; diff --git a/src/utils/determination.js b/src/utils/determination.js deleted file mode 100644 index 117eaea..0000000 --- a/src/utils/determination.js +++ /dev/null @@ -1,18 +0,0 @@ -import { visitPoints } from "./points"; - -// Given a dataset, x- and y-accessors, the mean center of the y values, and a predict function, -// return the coefficient of determination, or R squared. -export function determination(data, x, y, uY, predict){ - let SSE = 0, - SST = 0; - - visitPoints(data, x, y, (dx, dy) => { - const sse = dy - predict(dx), - sst = dy - uY; - - SSE += sse * sse; - SST += sst * sst; - }); - - return 1 - SSE / SST; -} \ No newline at end of file diff --git a/src/utils/determination.ts b/src/utils/determination.ts new file mode 100644 index 0000000..e443b7d --- /dev/null +++ b/src/utils/determination.ts @@ -0,0 +1,26 @@ +import { visitPoints } from "./points"; +import { Accessor, DataPoint, PredictFunction } from "../types"; + +/** + * Given a dataset, x- and y-accessors, the mean center of the y-values (uY), + * and a prediction function, return the coefficient of determination, R^2. + */ +export function determination( + data: DataPoint[], + x: Accessor, + y: Accessor, + uY: number, + predict: PredictFunction +): number { + let SSE = 0, // Sum of Squared Errors + SST = 0; // Total Sum of Squares + + visitPoints(data, x, y, (dx, dy) => { + const sse = dy - predict(dx); + const sst = dy - uY; + SSE += sse * sse; + SST += sst * sst; + }); + + return 1 - SSE / SST; +} diff --git a/src/utils/geometry.js b/src/utils/geometry.js deleted file mode 100644 index 29b9134..0000000 --- a/src/utils/geometry.js +++ /dev/null @@ -1,9 +0,0 @@ -// Returns the angle of a line in degrees. -export function angle(line){ - return Math.atan2(line[1][1] - line[0][1], line[1][0] - line[0][0]) * 180 / Math.PI; -} - -// Returns the midpoint of a line. -export function midpoint(line){ - return [(line[0][0] + line[1][0]) / 2, (line[0][1] + line[1][1]) / 2]; -} \ No newline at end of file diff --git a/src/utils/geometry.ts b/src/utils/geometry.ts new file mode 100644 index 0000000..e5b75dd --- /dev/null +++ b/src/utils/geometry.ts @@ -0,0 +1,21 @@ +import { DataPoint } from "../types"; + +/** + * Returns the angle of a line in degrees. + */ +export function angle(line: [DataPoint, DataPoint]): number { + return ( + Math.atan2(line[1][1] - line[0][1], line[1][0] - line[0][0]) * + (180 / Math.PI) + ); +} + +/** + * Returns the midpoint of a line. + */ +export function midpoint(line: [DataPoint, DataPoint]): DataPoint { + return [ + (line[0][0] + line[1][0]) / 2, + (line[0][1] + line[1][1]) / 2 + ]; +} diff --git a/src/utils/interpose.js b/src/utils/interpose.js deleted file mode 100644 index 61802c8..0000000 --- a/src/utils/interpose.js +++ /dev/null @@ -1,40 +0,0 @@ -import { angle, midpoint } from "./geometry"; - -// Given a start point, an end point, and a prediciton function, -// returns a smooth line. -export function interpose(xmin, xmax, predict){ - const l = Math.log(xmax - xmin) * Math.LOG10E + 1 | 0; - const precision = 1 * Math.pow(10, -l / 2 - 1), maxIter = 1e4; - let points = [px(xmin), px(xmax)], iter = 0; - - while (find(points) && iter < maxIter); - - return points; - - function px(x){ - return [x, predict(x)]; - } - - function find(points){ - iter++; - const n = points.length; - let found = false; - - for (let i = 0; i < n - 1; i++){ - const p0 = points[i], - p1 = points[i + 1], - m = midpoint([p0, p1]), - mp = px(m[0]), - a0 = angle([p0, m]), - a1 = angle([p0, mp]), - a = Math.abs(a0 - a1); - - if (a > precision){ - points.splice(i + 1, 0, mp); - found = true; - } - } - - return found; - } -} \ No newline at end of file diff --git a/src/utils/interpose.ts b/src/utils/interpose.ts new file mode 100644 index 0000000..41fa987 --- /dev/null +++ b/src/utils/interpose.ts @@ -0,0 +1,49 @@ +import { angle, midpoint } from "./geometry"; +import { PredictFunction, DataPoint } from "../types"; + +/** + * Given a start point (xmin), an end point (xmax), + * and a prediction function, returns a smooth line. + */ +export function interpose( + xmin: number, + xmax: number, + predict: PredictFunction +): [DataPoint, DataPoint] { + const l = (Math.log(xmax - xmin) * Math.LOG10E + 1) | 0; + const precision = Math.pow(10, -l / 2 - 1); + const maxIter = 1e4; + let points: [DataPoint, DataPoint] = [px(xmin), px(xmax)]; + let iter = 0; + + while (find(points) && iter < maxIter) ; + + return points; + + function px(x: number): DataPoint { + return [x, predict(x)]; + } + + function find(points: DataPoint[]): boolean { + iter++; + const n = points.length; + let found = false; + + for (let i = 0; i < n - 1; i++) { + const p0 = points[i]; + const p1 = points[i + 1]; + const m = midpoint([p0, p1]); + const mp = px(m[0]); + const a0 = angle([p0, m]); + const a1 = angle([p0, mp]); + const a = Math.abs(a0 - a1); + + if (a > precision) { + points.splice(i + 1, 0, mp); + found = true; + } + } + + return found; + } +} diff --git a/src/utils/median.js b/src/utils/median.ts similarity index 52% rename from src/utils/median.js rename to src/utils/median.ts index d040c87..f823d9a 100644 --- a/src/utils/median.js +++ b/src/utils/median.ts @@ -1,6 +1,8 @@ -// Returns the medium value of an array of numbers. -export function median(arr){ +/** + * Returns the median value of an array of numbers. + */ +export function median(arr: Float64Array): number { arr.sort((a, b) => a - b); var i = arr.length / 2; return i % 1 === 0 ? (arr[i - 1] + arr[i]) / 2 : arr[Math.floor(i)]; -} \ No newline at end of file +} diff --git a/src/utils/ols.js b/src/utils/ols.js deleted file mode 100644 index f621548..0000000 --- a/src/utils/ols.js +++ /dev/null @@ -1,10 +0,0 @@ -// Ordinary Least Squares from vega-statistics by Jeffrey Heer -// License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE -// Source: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/packages/vega-statistics/src/regression/ols.js -export function ols(uX, uY, uXY, uX2) { - const delta = uX2 - uX * uX, - slope = Math.abs(delta) < 1e-24 ? 0 : (uXY - uX * uY) / delta, - intercept = uY - slope * uX; - - return [intercept, slope]; -} \ No newline at end of file diff --git a/src/utils/ols.ts b/src/utils/ols.ts new file mode 100644 index 0000000..8c43c41 --- /dev/null +++ b/src/utils/ols.ts @@ -0,0 +1,18 @@ +/** + * Ordinary Least Squares from vega-statistics by Jeffrey Heer + * License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE + * Source: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/packages/vega-statistics/src/regression/ols.js + */ + +export function ols( + uX: number, + uY: number, + uXY: number, + uX2: number +): [number, number] { + const delta = uX2 - uX * uX, + slope = Math.abs(delta) < 1e-24 ? 0 : (uXY - uX * uY) / delta, + intercept = uY - slope * uX; + + return [intercept, slope]; +} diff --git a/src/utils/points.js b/src/utils/points.ts similarity index 50% rename from src/utils/points.js rename to src/utils/points.ts index 5e1a5c8..c197337 100644 --- a/src/utils/points.js +++ b/src/utils/points.ts @@ -1,20 +1,31 @@ -// Adapted from vega-statistics by Jeffrey Heer -// License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE -// Source: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/packages/vega-statistics/src/regression/points.js -export function points(data, x, y, sort) { +import { Accessor, DataPoint } from "../types"; + +/** + * Adapted from vega-statistics by Jeffrey Heer + * License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE + * Source: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/packages/vega-statistics/src/regression/points.js + */ +export function points( + data: DataPoint[], + x: Accessor, + y: Accessor, + sort?: boolean +): [Float64Array, Float64Array, number, number] { data = data.filter((d, i) => { let u = x(d, i), v = y(d, i); return u != null && isFinite(u) && v != null && isFinite(v); }); - + + if (sort) { data.sort((a, b) => x(a) - x(b)); } - + + const n = data.length, - X = new Float64Array(n), - Y = new Float64Array(n); - + X = new Float64Array(n), + Y = new Float64Array(n); + // extract values, calculate means let ux = 0, uy = 0, xv, yv, d; for (let i = 0; i < n; ) { @@ -25,25 +36,30 @@ export function points(data, x, y, sort) { ux += (xv - ux) / i; uy += (yv - uy) / i; } - + // mean center the data for (let i = 0; i < n; ++i) { X[i] -= ux; Y[i] -= uy; } - + return [X, Y, ux, uy]; } - -export function visitPoints(data, x, y, cb){ +/** + * Iterates over valid data points, invoking a callback for each. + */ +export function visitPoints( + data: DataPoint[], + x: Accessor, + y: Accessor, + cb: (dx: number, dy: number, index: number) => void +): void { let iterations = 0; - - for (let i = 0, n = data.length; i < n; i++) { - const d = data[i], - dx = +x(d, i, data), - dy = +y(d, i, data); - + for (let i = 0; i < data.length; i++) { + const d = data[i]; + const dx = +x(d, i, data); + const dy = +y(d, i, data); if (dx != null && isFinite(dx) && dy != null && isFinite(dy)) { cb(dx, dy, iterations++); } diff --git a/test/loess-test.js b/test/loess-test.js index 0f163f3..13c965c 100644 --- a/test/loess-test.js +++ b/test/loess-test.js @@ -27,4 +27,4 @@ tape("loess(data) calculates the LOESS regression", function(test) { test.deepEqual(r, output); test.end(); -}); \ No newline at end of file +}); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..2ac344c --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "ES5", + "module": "ESNext", + "declaration": true, + "declarationDir": "./dist/types", + "outDir": "./dist", + "allowJs": true, + "strict": true + }, + "include": [ + "index.ts", + "src/**/*.ts" + ], + "exclude": [ + "node_modules", + "dist", + "**/*.test.js" + ] +} From be843f93e3b1c4168c30e5a0fb2b1bf5f87f8133 Mon Sep 17 00:00:00 2001 From: Kirill Baldin Date: Wed, 15 Jan 2025 17:08:13 +0400 Subject: [PATCH 02/10] Refactor types and update build artifacts. Changed "Accessor" type to allow flexible input data. Introduced a root type for "PolynomialRegression" for better clarity. Added TypeScript declaration files to the package distribution for enhanced developer support. Updated build script to include all TypeScript definitions. --- dist/d3-regression.cjs.js | 1 + dist/d3-regression.esm.js | 1 + dist/d3-regression.js | 1 + dist/d3-regression.min.js | 1 + dist/src/polynomial.d.ts | 3 ++- dist/src/types.d.ts | 2 +- package.json | 2 +- src/types.ts | 2 +- 8 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 dist/d3-regression.min.js diff --git a/dist/d3-regression.cjs.js b/dist/d3-regression.cjs.js index 01b59fe..67d6795 100644 --- a/dist/d3-regression.cjs.js +++ b/dist/d3-regression.cjs.js @@ -470,6 +470,7 @@ function quadratic() { return quadraticRegression; } +// Adapted from regression-js by Tom Alexander function polynomial() { var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, order = 3, domain; var polynomialRegression = function polynomialRegression(data) { diff --git a/dist/d3-regression.esm.js b/dist/d3-regression.esm.js index cb631e0..db4f3aa 100644 --- a/dist/d3-regression.esm.js +++ b/dist/d3-regression.esm.js @@ -466,6 +466,7 @@ function quadratic() { return quadraticRegression; } +// Adapted from regression-js by Tom Alexander function polynomial() { var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, order = 3, domain; var polynomialRegression = function polynomialRegression(data) { diff --git a/dist/d3-regression.js b/dist/d3-regression.js index 600764d..f7a618d 100644 --- a/dist/d3-regression.js +++ b/dist/d3-regression.js @@ -472,6 +472,7 @@ return quadraticRegression; } + // Adapted from regression-js by Tom Alexander function polynomial() { var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, order = 3, domain; var polynomialRegression = function polynomialRegression(data) { diff --git a/dist/d3-regression.min.js b/dist/d3-regression.min.js new file mode 100644 index 0000000..cbb1875 --- /dev/null +++ b/dist/d3-regression.min.js @@ -0,0 +1 @@ +!function(n,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports):"function"==typeof define&&define.amd?define(["exports"],r):(n=n||self,r(n.d3={}))}(this,function(n){"use strict";function r(n,r,t,e){n=n.filter(function(n,e){var u=r(n,e),o=t(n,e);return null!=u&&isFinite(u)&&null!=o&&isFinite(o)}),e&&n.sort(function(n,t){return r(n)-r(t)});for(var u,o,a,i=n.length,f=new Float64Array(i),c=new Float64Array(i),h=0,v=0,l=0;li&&(n.splice(a+1,0,l),t=!0)}return t}(f)&&c<1e4;);return f}function i(n,r,t,e){var u=e-n*n,o=Math.abs(u)<1e-24?0:(t-n*r)/u;return[r-o*n,o]}function f(){var n,r=function(n){return n[0]},u=function(n){return n[1]},o=function(o){var f=0,c=0,h=0,v=0,l=0,g=0,s=n?+n[0]:1/0,d=n?+n[1]:-1/0;t(o,r,u,function(r,t){var e=Math.log(t),u=r*t;++f,c+=(t-c)/f,v+=(u-v)/f,g+=(r*u-g)/f,h+=(t*e-h)/f,l+=(u*e-l)/f,n||(rd&&(d=r))});var p=i(v/c,h/c,l/c,g/c),M=p[0],y=p[1];M=Math.exp(M);var b=function(n){return M*Math.exp(y*n)},w=a(s,d,b);return w.a=M,w.b=y,w.predict=b,w.rSquared=e(o,r,u,c,b),w};return o.domain=function(r){return arguments.length?(n=r,o):n},o.x=function(n){return arguments.length?(r=n,o):r},o.y=function(n){return arguments.length?(u=n,o):u},o}function c(){var n,r=function(n){return n[0]},u=function(n){return n[1]},o=function(o){var a=0,f=0,c=0,h=0,v=0,l=n?+n[0]:1/0,g=n?+n[1]:-1/0;t(o,r,u,function(r,t){++a,f+=(r-f)/a,c+=(t-c)/a,h+=(r*t-h)/a,v+=(r*r-v)/a,n||(rg&&(g=r))});var s=i(f,c,h,v),d=s[0],p=s[1],M=function(n){return p*n+d},y=[[l,M(l)],[g,M(g)]];return y.a=p,y.b=d,y.predict=M,y.rSquared=e(o,r,u,c,M),y};return o.domain=function(r){return arguments.length?(n=r,o):n},o.x=function(n){return arguments.length?(r=n,o):r},o.y=function(n){return arguments.length?(u=n,o):u},o}function h(n){n.sort(function(n,r){return n-r});var r=n.length/2;return r%1==0?(n[r-1]+n[r])/2:n[Math.floor(r)]}function v(){var n=function(n){return n[0]},t=function(n){return n[1]},e=.3,u=function(u){for(var o=r(u,n,t,!0),a=o[0],f=o[1],c=o[2],v=o[3],d=a.length,p=Math.max(2,~~(e*d)),M=new Float64Array(d),y=new Float64Array(d),b=new Float64Array(d).fill(1),w=-1;++w<=x;){for(var F=[0,p-1],q=0;qa[L]-S?A:L,E=0,j=0,k=0,O=0,_=0,G=1/Math.abs(a[P]-S||1),I=A;I<=L;++I){var Q=a[I],z=f[I],B=l(Math.abs(S-Q)*G)*b[I],C=Q*B;E+=B,j+=C,k+=z*B,O+=z*C,_+=Q*C}var D=i(j/E,k/E,O/E,_/E),H=D[0],J=D[1];M[q]=H+J*S,y[q]=Math.abs(f[q]-M[q]),g(a,q+1,F)}if(w===x)break;var K=h(y);if(Math.abs(K)=1?m:(B=1-N*N)*B}return s(a,M,c,v)};return u.bandwidth=function(n){return arguments.length?(e=n,u):e},u.x=function(r){return arguments.length?(n=r,u):n},u.y=function(n){return arguments.length?(t=n,u):t},u}function l(n){return(n=1-n*n*n)*n*n}function g(n,r,t){var e=n[r],u=t[0],o=t[1]+1;if(!(o>=n.length))for(;r>u&&n[o]-e<=e-n[u];)t[0]=++u,t[1]=o,++o}function s(n,r,t,e){for(var u,o=n.length,a=[],i=0,f=0,c=[];id&&(d=r))});var M=i(h,v,l,g),y=M[0],b=M[1],w=function(n){return b*Math.log(n)/p+y},x=a(s,d,w);return x.a=b,x.b=y,x.predict=w,x.rSquared=e(f,r,u,v,w),x};return f.domain=function(r){return arguments.length?(n=r,f):n},f.x=function(n){return arguments.length?(r=n,f):r},f.y=function(n){return arguments.length?(u=n,f):u},f.base=function(n){return arguments.length?(o=n,f):o},f}function p(){var n,u=function(n){return n[0]},o=function(n){return n[1]},i=function(i){var f,c,h,v,l=r(i,u,o),g=l[0],s=l[1],d=l[2],p=l[3],M=g.length,y=0,b=0,w=0,x=0,m=0;for(f=0;fA&&(A=r))});var L=w-y*y,P=y*L-b*b,E=(m*y-x*b)/P,j=(x*L-m*b)/P,k=-E*y,O=function(n){var r=n-d;return E*r*r+j*r+k+p},_=a(S,A,O);return _.a=E,_.b=j-2*E*d,_.c=k-j*d+E*d*d+p,_.predict=O,_.rSquared=e(i,u,o,F,O),_};return i.domain=function(r){return arguments.length?(n=r,i):n},i.x=function(n){return arguments.length?(u=n,i):u},i.y=function(n){return arguments.length?(o=n,i):o},i}function M(){var n,u=function(n){return n[0]},o=function(n){return n[1]},i=3,f=function(f){if(1===i){var h=c().x(u).y(o).domain(n)(f),v=[h[0],h[1]];return v.coefficients=[h.b,h.a],v.predict=h.predict,v.rSquared=h.rSquared,v}if(2===i){var h=p().x(u).y(o).domain(n)(f),v=[h[0],h[1]];return v.coefficients=[h.c,h.b,h.a],v.predict=h.predict,v.rSquared=h.rSquared,v}var l=r(f,u,o),g=l[0],s=l[1],d=l[2],M=l[3],w=g.length,x=i+1,m=[],F=[],q=0,S=0,A=n?+n[0]:1/0,L=n?+n[1]:-1/0;t(f,u,o,function(r,t){S++,q+=(t-q)/S,n||(rL&&(L=r))});for(var P=0;P=0;--o){var a=r[o];u[o]+=a;for(var i=1,f=1;f<=o;++f)i*=(o+1-f)/f,u[o-f]+=a*Math.pow(t,f)*i}return u[0]+=e,u}function b(n){for(var r=n.length-1,t=new Array(r),e=0;eMath.abs(n[e][u])&&(u=o);for(var a=e;a=e;a--)n[a][o]-=n[a][e]*n[e][o]/n[e][e]}for(var o=r-1;o>=0;o--){for(var i=0,a=o+1;ad&&(d=r))});var p=i(c,h,v,l),M=p[0],y=p[1];M=Math.exp(M);var b=function(n){return M*Math.pow(n,y)},w=a(s,d,b);return w.a=M,w.b=y,w.predict=b,w.rSquared=e(o,r,u,g,b),w};return o.domain=function(r){return arguments.length?(n=r,o):n},o.x=function(n){return arguments.length?(r=n,o):r},o.y=function(n){return arguments.length?(u=n,o):u},o}var x=2,m=1e-12;n.regressionExp=f,n.regressionLinear=c,n.regressionLoess=v,n.regressionLog=d,n.regressionPoly=M,n.regressionPow=w,n.regressionQuad=p,Object.defineProperty(n,"__esModule",{value:!0})}); \ No newline at end of file diff --git a/dist/src/polynomial.d.ts b/dist/src/polynomial.d.ts index f9c4706..e348d20 100644 --- a/dist/src/polynomial.d.ts +++ b/dist/src/polynomial.d.ts @@ -5,7 +5,8 @@ export type PolynomialOutput = PolynomialOutputRoot & { predict: PredictFunction; rSquared: number; }; -interface PolynomialRegression { +type PolynomialRegressionRoot = (data: DataPoint[]) => PolynomialOutput; +export interface PolynomialRegression extends PolynomialRegressionRoot { (data: DataPoint[]): PolynomialOutput; domain(): Domain; domain(domain?: Domain): PolynomialRegression; diff --git a/dist/src/types.d.ts b/dist/src/types.d.ts index 9da5237..319ab30 100644 --- a/dist/src/types.d.ts +++ b/dist/src/types.d.ts @@ -1,4 +1,4 @@ export type DataPoint = [number, number]; -export type Accessor = (d: DataPoint, i?: number, data?: DataPoint[]) => number; +export type Accessor = (d: any, i?: number, data?: DataPoint[]) => number; export type PredictFunction = (x: number) => number; export type Domain = [number, number] | undefined; diff --git a/package.json b/package.json index 6d281cc..babb340 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "pretest": "rm -rf dist && mkdir dist && rollup -c --banner \"$(preamble)\"", "test": "tape 'test/**/*-test.js'", "prepublishOnly": "npm run test && uglifyjs dist/d3-regression.js -c -m -o dist/d3-regression.min.js", - "postpublish": "zip -j dist/d3-regression.zip -- LICENSE README.md dist/d3-regression.js dist/d3-regression.min.js dist/d3-regression.cjs.js dist/d3-regression.esm.js" + "postpublish": "zip -j dist/d3-regression.zip -- LICENSE README.md dist/d3-regression.js dist/d3-regression.min.js dist/d3-regression.cjs.js dist/d3-regression.esm.js dist/index.d.ts dist/src/*.d.ts" }, "repository": { "type": "git", diff --git a/src/types.ts b/src/types.ts index 9053b40..fa32d29 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,5 +1,5 @@ export type DataPoint = [number, number]; -export type Accessor = (d: DataPoint, i?: number, data?: DataPoint[]) => number; +export type Accessor = (d: any, i?: number, data?: DataPoint[]) => number; export type PredictFunction = (x: number) => number; export type Domain = [number, number] | undefined; From c8526bd7aa7adc4c1f769092f2283151d75c928c Mon Sep 17 00:00:00 2001 From: Kirill Baldin Date: Wed, 15 Jan 2025 17:52:45 +0400 Subject: [PATCH 03/10] Enhance type support with generics for functional utilities --- dist/d3-regression.cjs.js | 20 +++---- dist/d3-regression.esm.js | 20 +++---- dist/d3-regression.js | 20 +++---- dist/d3-regression.min.js | 2 +- dist/src/exponential.d.ts | 16 +++--- dist/src/linear.d.ts | 16 +++--- dist/src/loess.d.ts | 16 +++--- dist/src/logarithmic.d.ts | 18 +++--- dist/src/polynomial.d.ts | 23 ++++---- dist/src/power.d.ts | 22 ++++--- dist/src/quadratic.d.ts | 22 ++++--- dist/src/types.d.ts | 2 +- dist/src/utils/determination.d.ts | 4 +- dist/src/utils/points.d.ts | 6 +- src/exponential.ts | 34 ++++++----- src/linear.ts | 60 ++++++++++--------- src/loess.ts | 52 ++++++++--------- src/logarithmic.ts | 41 +++++++------ src/polynomial.ts | 95 +++++++++++++------------------ src/power.ts | 47 ++++++++------- src/quadratic.ts | 77 ++++++++++++------------- src/types.ts | 3 +- src/utils/determination.ts | 8 +-- src/utils/points.ts | 20 +++---- 24 files changed, 288 insertions(+), 356 deletions(-) diff --git a/dist/d3-regression.cjs.js b/dist/d3-regression.cjs.js index 67d6795..d9e67e1 100644 --- a/dist/d3-regression.cjs.js +++ b/dist/d3-regression.cjs.js @@ -130,7 +130,7 @@ function ols(uX, uY, uXY, uX2) { } function exponential() { - var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, domain; + var y = function (d) { return d[1]; }, x = function (d) { return d[0]; }, domain; var exponentialRegression = function (data) { var n = 0, Y = 0, YL = 0, XY = 0, XYL = 0, X2Y = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; visitPoints(data, x, y, function (dx, dy) { @@ -242,9 +242,9 @@ function median(arr) { // Adapted from science.js by Jason Davies var maxiters = 2, epsilon = 1e-12; function loess() { - var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, bandwidth = .3; + var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, bandwidth = 0.3; var loessRegression = function loessRegression(data) { - var _a = points(data, x, y, true), xv = _a[0], yv = _a[1], ux = _a[2], uy = _a[3]; + var _a = points(data, function (dd) { return x(dd); }, function (dd) { return y(dd); }, true), xv = _a[0], yv = _a[1], ux = _a[2], uy = _a[3]; var n = xv.length; var bw = Math.max(2, ~~(bandwidth * n)); // # of nearest neighbors var yhat = new Float64Array(n); @@ -353,7 +353,7 @@ function output(xv, yhat, ux, uy) { function logarithmic() { var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, base = Math.E, domain; - var logarithmicRegression = function logarithmicRegression(data) { + var logarithmicRegression = function (data) { var n = 0, X = 0, Y = 0, XY = 0, X2 = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity, lb = Math.log(base); visitPoints(data, x, y, function (dx, dy) { var lx = Math.log(dx) / lb; @@ -408,7 +408,7 @@ function logarithmic() { function quadratic() { var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, domain; var quadraticRegression = function quadraticRegression(data) { - var _a = points(data, x, y), xv = _a[0], yv = _a[1], ux = _a[2], uy = _a[3]; + var _a = points(data, function (dd) { return x(dd); }, function (dd) { return y(dd); }), xv = _a[0], yv = _a[1], ux = _a[2], uy = _a[3]; var n = xv.length; var X2 = 0, X3 = 0, X4 = 0, XY = 0, X2Y = 0, i, dx, dy, x2; for (i = 0; i < n;) { @@ -477,10 +477,7 @@ function polynomial() { // Shortcut for lower-order polynomials: if (order === 1) { var o = linear().x(x).y(y).domain(domain)(data); - var result = [ - o[0], - o[1], - ]; + var result = [o[0], o[1]]; result.coefficients = [o.b, o.a]; result.predict = o.predict; result.rSquared = o.rSquared; @@ -488,10 +485,7 @@ function polynomial() { } if (order === 2) { var o = quadratic().x(x).y(y).domain(domain)(data); - var result = [ - o[0], - o[1], - ]; + var result = [o[0], o[1]]; result.coefficients = [o.c, o.b, o.a]; result.predict = o.predict; result.rSquared = o.rSquared; diff --git a/dist/d3-regression.esm.js b/dist/d3-regression.esm.js index db4f3aa..46034c0 100644 --- a/dist/d3-regression.esm.js +++ b/dist/d3-regression.esm.js @@ -126,7 +126,7 @@ function ols(uX, uY, uXY, uX2) { } function exponential() { - var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, domain; + var y = function (d) { return d[1]; }, x = function (d) { return d[0]; }, domain; var exponentialRegression = function (data) { var n = 0, Y = 0, YL = 0, XY = 0, XYL = 0, X2Y = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; visitPoints(data, x, y, function (dx, dy) { @@ -238,9 +238,9 @@ function median(arr) { // Adapted from science.js by Jason Davies var maxiters = 2, epsilon = 1e-12; function loess() { - var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, bandwidth = .3; + var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, bandwidth = 0.3; var loessRegression = function loessRegression(data) { - var _a = points(data, x, y, true), xv = _a[0], yv = _a[1], ux = _a[2], uy = _a[3]; + var _a = points(data, function (dd) { return x(dd); }, function (dd) { return y(dd); }, true), xv = _a[0], yv = _a[1], ux = _a[2], uy = _a[3]; var n = xv.length; var bw = Math.max(2, ~~(bandwidth * n)); // # of nearest neighbors var yhat = new Float64Array(n); @@ -349,7 +349,7 @@ function output(xv, yhat, ux, uy) { function logarithmic() { var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, base = Math.E, domain; - var logarithmicRegression = function logarithmicRegression(data) { + var logarithmicRegression = function (data) { var n = 0, X = 0, Y = 0, XY = 0, X2 = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity, lb = Math.log(base); visitPoints(data, x, y, function (dx, dy) { var lx = Math.log(dx) / lb; @@ -404,7 +404,7 @@ function logarithmic() { function quadratic() { var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, domain; var quadraticRegression = function quadraticRegression(data) { - var _a = points(data, x, y), xv = _a[0], yv = _a[1], ux = _a[2], uy = _a[3]; + var _a = points(data, function (dd) { return x(dd); }, function (dd) { return y(dd); }), xv = _a[0], yv = _a[1], ux = _a[2], uy = _a[3]; var n = xv.length; var X2 = 0, X3 = 0, X4 = 0, XY = 0, X2Y = 0, i, dx, dy, x2; for (i = 0; i < n;) { @@ -473,10 +473,7 @@ function polynomial() { // Shortcut for lower-order polynomials: if (order === 1) { var o = linear().x(x).y(y).domain(domain)(data); - var result = [ - o[0], - o[1], - ]; + var result = [o[0], o[1]]; result.coefficients = [o.b, o.a]; result.predict = o.predict; result.rSquared = o.rSquared; @@ -484,10 +481,7 @@ function polynomial() { } if (order === 2) { var o = quadratic().x(x).y(y).domain(domain)(data); - var result = [ - o[0], - o[1], - ]; + var result = [o[0], o[1]]; result.coefficients = [o.c, o.b, o.a]; result.predict = o.predict; result.rSquared = o.rSquared; diff --git a/dist/d3-regression.js b/dist/d3-regression.js index f7a618d..2bc9b8e 100644 --- a/dist/d3-regression.js +++ b/dist/d3-regression.js @@ -132,7 +132,7 @@ } function exponential() { - var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, domain; + var y = function (d) { return d[1]; }, x = function (d) { return d[0]; }, domain; var exponentialRegression = function (data) { var n = 0, Y = 0, YL = 0, XY = 0, XYL = 0, X2Y = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; visitPoints(data, x, y, function (dx, dy) { @@ -244,9 +244,9 @@ // Adapted from science.js by Jason Davies var maxiters = 2, epsilon = 1e-12; function loess() { - var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, bandwidth = .3; + var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, bandwidth = 0.3; var loessRegression = function loessRegression(data) { - var _a = points(data, x, y, true), xv = _a[0], yv = _a[1], ux = _a[2], uy = _a[3]; + var _a = points(data, function (dd) { return x(dd); }, function (dd) { return y(dd); }, true), xv = _a[0], yv = _a[1], ux = _a[2], uy = _a[3]; var n = xv.length; var bw = Math.max(2, ~~(bandwidth * n)); // # of nearest neighbors var yhat = new Float64Array(n); @@ -355,7 +355,7 @@ function logarithmic() { var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, base = Math.E, domain; - var logarithmicRegression = function logarithmicRegression(data) { + var logarithmicRegression = function (data) { var n = 0, X = 0, Y = 0, XY = 0, X2 = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity, lb = Math.log(base); visitPoints(data, x, y, function (dx, dy) { var lx = Math.log(dx) / lb; @@ -410,7 +410,7 @@ function quadratic() { var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, domain; var quadraticRegression = function quadraticRegression(data) { - var _a = points(data, x, y), xv = _a[0], yv = _a[1], ux = _a[2], uy = _a[3]; + var _a = points(data, function (dd) { return x(dd); }, function (dd) { return y(dd); }), xv = _a[0], yv = _a[1], ux = _a[2], uy = _a[3]; var n = xv.length; var X2 = 0, X3 = 0, X4 = 0, XY = 0, X2Y = 0, i, dx, dy, x2; for (i = 0; i < n;) { @@ -479,10 +479,7 @@ // Shortcut for lower-order polynomials: if (order === 1) { var o = linear().x(x).y(y).domain(domain)(data); - var result = [ - o[0], - o[1], - ]; + var result = [o[0], o[1]]; result.coefficients = [o.b, o.a]; result.predict = o.predict; result.rSquared = o.rSquared; @@ -490,10 +487,7 @@ } if (order === 2) { var o = quadratic().x(x).y(y).domain(domain)(data); - var result = [ - o[0], - o[1], - ]; + var result = [o[0], o[1]]; result.coefficients = [o.c, o.b, o.a]; result.predict = o.predict; result.rSquared = o.rSquared; diff --git a/dist/d3-regression.min.js b/dist/d3-regression.min.js index cbb1875..681f40f 100644 --- a/dist/d3-regression.min.js +++ b/dist/d3-regression.min.js @@ -1 +1 @@ -!function(n,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports):"function"==typeof define&&define.amd?define(["exports"],r):(n=n||self,r(n.d3={}))}(this,function(n){"use strict";function r(n,r,t,e){n=n.filter(function(n,e){var u=r(n,e),o=t(n,e);return null!=u&&isFinite(u)&&null!=o&&isFinite(o)}),e&&n.sort(function(n,t){return r(n)-r(t)});for(var u,o,a,i=n.length,f=new Float64Array(i),c=new Float64Array(i),h=0,v=0,l=0;li&&(n.splice(a+1,0,l),t=!0)}return t}(f)&&c<1e4;);return f}function i(n,r,t,e){var u=e-n*n,o=Math.abs(u)<1e-24?0:(t-n*r)/u;return[r-o*n,o]}function f(){var n,r=function(n){return n[0]},u=function(n){return n[1]},o=function(o){var f=0,c=0,h=0,v=0,l=0,g=0,s=n?+n[0]:1/0,d=n?+n[1]:-1/0;t(o,r,u,function(r,t){var e=Math.log(t),u=r*t;++f,c+=(t-c)/f,v+=(u-v)/f,g+=(r*u-g)/f,h+=(t*e-h)/f,l+=(u*e-l)/f,n||(rd&&(d=r))});var p=i(v/c,h/c,l/c,g/c),M=p[0],y=p[1];M=Math.exp(M);var b=function(n){return M*Math.exp(y*n)},w=a(s,d,b);return w.a=M,w.b=y,w.predict=b,w.rSquared=e(o,r,u,c,b),w};return o.domain=function(r){return arguments.length?(n=r,o):n},o.x=function(n){return arguments.length?(r=n,o):r},o.y=function(n){return arguments.length?(u=n,o):u},o}function c(){var n,r=function(n){return n[0]},u=function(n){return n[1]},o=function(o){var a=0,f=0,c=0,h=0,v=0,l=n?+n[0]:1/0,g=n?+n[1]:-1/0;t(o,r,u,function(r,t){++a,f+=(r-f)/a,c+=(t-c)/a,h+=(r*t-h)/a,v+=(r*r-v)/a,n||(rg&&(g=r))});var s=i(f,c,h,v),d=s[0],p=s[1],M=function(n){return p*n+d},y=[[l,M(l)],[g,M(g)]];return y.a=p,y.b=d,y.predict=M,y.rSquared=e(o,r,u,c,M),y};return o.domain=function(r){return arguments.length?(n=r,o):n},o.x=function(n){return arguments.length?(r=n,o):r},o.y=function(n){return arguments.length?(u=n,o):u},o}function h(n){n.sort(function(n,r){return n-r});var r=n.length/2;return r%1==0?(n[r-1]+n[r])/2:n[Math.floor(r)]}function v(){var n=function(n){return n[0]},t=function(n){return n[1]},e=.3,u=function(u){for(var o=r(u,n,t,!0),a=o[0],f=o[1],c=o[2],v=o[3],d=a.length,p=Math.max(2,~~(e*d)),M=new Float64Array(d),y=new Float64Array(d),b=new Float64Array(d).fill(1),w=-1;++w<=x;){for(var F=[0,p-1],q=0;qa[L]-S?A:L,E=0,j=0,k=0,O=0,_=0,G=1/Math.abs(a[P]-S||1),I=A;I<=L;++I){var Q=a[I],z=f[I],B=l(Math.abs(S-Q)*G)*b[I],C=Q*B;E+=B,j+=C,k+=z*B,O+=z*C,_+=Q*C}var D=i(j/E,k/E,O/E,_/E),H=D[0],J=D[1];M[q]=H+J*S,y[q]=Math.abs(f[q]-M[q]),g(a,q+1,F)}if(w===x)break;var K=h(y);if(Math.abs(K)=1?m:(B=1-N*N)*B}return s(a,M,c,v)};return u.bandwidth=function(n){return arguments.length?(e=n,u):e},u.x=function(r){return arguments.length?(n=r,u):n},u.y=function(n){return arguments.length?(t=n,u):t},u}function l(n){return(n=1-n*n*n)*n*n}function g(n,r,t){var e=n[r],u=t[0],o=t[1]+1;if(!(o>=n.length))for(;r>u&&n[o]-e<=e-n[u];)t[0]=++u,t[1]=o,++o}function s(n,r,t,e){for(var u,o=n.length,a=[],i=0,f=0,c=[];id&&(d=r))});var M=i(h,v,l,g),y=M[0],b=M[1],w=function(n){return b*Math.log(n)/p+y},x=a(s,d,w);return x.a=b,x.b=y,x.predict=w,x.rSquared=e(f,r,u,v,w),x};return f.domain=function(r){return arguments.length?(n=r,f):n},f.x=function(n){return arguments.length?(r=n,f):r},f.y=function(n){return arguments.length?(u=n,f):u},f.base=function(n){return arguments.length?(o=n,f):o},f}function p(){var n,u=function(n){return n[0]},o=function(n){return n[1]},i=function(i){var f,c,h,v,l=r(i,u,o),g=l[0],s=l[1],d=l[2],p=l[3],M=g.length,y=0,b=0,w=0,x=0,m=0;for(f=0;fA&&(A=r))});var L=w-y*y,P=y*L-b*b,E=(m*y-x*b)/P,j=(x*L-m*b)/P,k=-E*y,O=function(n){var r=n-d;return E*r*r+j*r+k+p},_=a(S,A,O);return _.a=E,_.b=j-2*E*d,_.c=k-j*d+E*d*d+p,_.predict=O,_.rSquared=e(i,u,o,F,O),_};return i.domain=function(r){return arguments.length?(n=r,i):n},i.x=function(n){return arguments.length?(u=n,i):u},i.y=function(n){return arguments.length?(o=n,i):o},i}function M(){var n,u=function(n){return n[0]},o=function(n){return n[1]},i=3,f=function(f){if(1===i){var h=c().x(u).y(o).domain(n)(f),v=[h[0],h[1]];return v.coefficients=[h.b,h.a],v.predict=h.predict,v.rSquared=h.rSquared,v}if(2===i){var h=p().x(u).y(o).domain(n)(f),v=[h[0],h[1]];return v.coefficients=[h.c,h.b,h.a],v.predict=h.predict,v.rSquared=h.rSquared,v}var l=r(f,u,o),g=l[0],s=l[1],d=l[2],M=l[3],w=g.length,x=i+1,m=[],F=[],q=0,S=0,A=n?+n[0]:1/0,L=n?+n[1]:-1/0;t(f,u,o,function(r,t){S++,q+=(t-q)/S,n||(rL&&(L=r))});for(var P=0;P=0;--o){var a=r[o];u[o]+=a;for(var i=1,f=1;f<=o;++f)i*=(o+1-f)/f,u[o-f]+=a*Math.pow(t,f)*i}return u[0]+=e,u}function b(n){for(var r=n.length-1,t=new Array(r),e=0;eMath.abs(n[e][u])&&(u=o);for(var a=e;a=e;a--)n[a][o]-=n[a][e]*n[e][o]/n[e][e]}for(var o=r-1;o>=0;o--){for(var i=0,a=o+1;ad&&(d=r))});var p=i(c,h,v,l),M=p[0],y=p[1];M=Math.exp(M);var b=function(n){return M*Math.pow(n,y)},w=a(s,d,b);return w.a=M,w.b=y,w.predict=b,w.rSquared=e(o,r,u,g,b),w};return o.domain=function(r){return arguments.length?(n=r,o):n},o.x=function(n){return arguments.length?(r=n,o):r},o.y=function(n){return arguments.length?(u=n,o):u},o}var x=2,m=1e-12;n.regressionExp=f,n.regressionLinear=c,n.regressionLoess=v,n.regressionLog=d,n.regressionPoly=M,n.regressionPow=w,n.regressionQuad=p,Object.defineProperty(n,"__esModule",{value:!0})}); \ No newline at end of file +!function(n,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports):"function"==typeof define&&define.amd?define(["exports"],r):(n=n||self,r(n.d3={}))}(this,function(n){"use strict";function r(n,r,t,e){n=n.filter(function(n,e){var u=r(n,e),o=t(n,e);return null!=u&&isFinite(u)&&null!=o&&isFinite(o)}),e&&n.sort(function(n,t){return r(n)-r(t)});for(var u,o,a,i=n.length,f=new Float64Array(i),c=new Float64Array(i),h=0,v=0,l=0;li&&(n.splice(a+1,0,l),t=!0)}return t}(f)&&c<1e4;);return f}function i(n,r,t,e){var u=e-n*n,o=Math.abs(u)<1e-24?0:(t-n*r)/u;return[r-o*n,o]}function f(){var n,r=function(n){return n[1]},u=function(n){return n[0]},o=function(o){var f=0,c=0,h=0,v=0,l=0,g=0,s=n?+n[0]:1/0,d=n?+n[1]:-1/0;t(o,u,r,function(r,t){var e=Math.log(t),u=r*t;++f,c+=(t-c)/f,v+=(u-v)/f,g+=(r*u-g)/f,h+=(t*e-h)/f,l+=(u*e-l)/f,n||(rd&&(d=r))});var p=i(v/c,h/c,l/c,g/c),M=p[0],y=p[1];M=Math.exp(M);var b=function(n){return M*Math.exp(y*n)},w=a(s,d,b);return w.a=M,w.b=y,w.predict=b,w.rSquared=e(o,u,r,c,b),w};return o.domain=function(r){return arguments.length?(n=r,o):n},o.x=function(n){return arguments.length?(u=n,o):u},o.y=function(n){return arguments.length?(r=n,o):r},o}function c(){var n,r=function(n){return n[0]},u=function(n){return n[1]},o=function(o){var a=0,f=0,c=0,h=0,v=0,l=n?+n[0]:1/0,g=n?+n[1]:-1/0;t(o,r,u,function(r,t){++a,f+=(r-f)/a,c+=(t-c)/a,h+=(r*t-h)/a,v+=(r*r-v)/a,n||(rg&&(g=r))});var s=i(f,c,h,v),d=s[0],p=s[1],M=function(n){return p*n+d},y=[[l,M(l)],[g,M(g)]];return y.a=p,y.b=d,y.predict=M,y.rSquared=e(o,r,u,c,M),y};return o.domain=function(r){return arguments.length?(n=r,o):n},o.x=function(n){return arguments.length?(r=n,o):r},o.y=function(n){return arguments.length?(u=n,o):u},o}function h(n){n.sort(function(n,r){return n-r});var r=n.length/2;return r%1==0?(n[r-1]+n[r])/2:n[Math.floor(r)]}function v(){var n=function(n){return n[0]},t=function(n){return n[1]},e=.3,u=function(u){for(var o=r(u,function(r){return n(r)},function(n){return t(n)},!0),a=o[0],f=o[1],c=o[2],v=o[3],d=a.length,p=Math.max(2,~~(e*d)),M=new Float64Array(d),y=new Float64Array(d),b=new Float64Array(d).fill(1),w=-1;++w<=x;){for(var F=[0,p-1],q=0;qa[L]-S?A:L,E=0,j=0,k=0,O=0,_=0,G=1/Math.abs(a[P]-S||1),I=A;I<=L;++I){var Q=a[I],z=f[I],B=l(Math.abs(S-Q)*G)*b[I],C=Q*B;E+=B,j+=C,k+=z*B,O+=z*C,_+=Q*C}var D=i(j/E,k/E,O/E,_/E),H=D[0],J=D[1];M[q]=H+J*S,y[q]=Math.abs(f[q]-M[q]),g(a,q+1,F)}if(w===x)break;var K=h(y);if(Math.abs(K)=1?m:(B=1-N*N)*B}return s(a,M,c,v)};return u.bandwidth=function(n){return arguments.length?(e=n,u):e},u.x=function(r){return arguments.length?(n=r,u):n},u.y=function(n){return arguments.length?(t=n,u):t},u}function l(n){return(n=1-n*n*n)*n*n}function g(n,r,t){var e=n[r],u=t[0],o=t[1]+1;if(!(o>=n.length))for(;r>u&&n[o]-e<=e-n[u];)t[0]=++u,t[1]=o,++o}function s(n,r,t,e){for(var u,o=n.length,a=[],i=0,f=0,c=[];id&&(d=r))});var M=i(h,v,l,g),y=M[0],b=M[1],w=function(n){return b*Math.log(n)/p+y},x=a(s,d,w);return x.a=b,x.b=y,x.predict=w,x.rSquared=e(f,r,u,v,w),x};return f.domain=function(r){return arguments.length?(n=r,f):n},f.x=function(n){return arguments.length?(r=n,f):r},f.y=function(n){return arguments.length?(u=n,f):u},f.base=function(n){return arguments.length?(o=n,f):o},f}function p(){var n,u=function(n){return n[0]},o=function(n){return n[1]},i=function(i){var f,c,h,v,l=r(i,function(n){return u(n)},function(n){return o(n)}),g=l[0],s=l[1],d=l[2],p=l[3],M=g.length,y=0,b=0,w=0,x=0,m=0;for(f=0;fA&&(A=r))});var L=w-y*y,P=y*L-b*b,E=(m*y-x*b)/P,j=(x*L-m*b)/P,k=-E*y,O=function(n){var r=n-d;return E*r*r+j*r+k+p},_=a(S,A,O);return _.a=E,_.b=j-2*E*d,_.c=k-j*d+E*d*d+p,_.predict=O,_.rSquared=e(i,u,o,F,O),_};return i.domain=function(r){return arguments.length?(n=r,i):n},i.x=function(n){return arguments.length?(u=n,i):u},i.y=function(n){return arguments.length?(o=n,i):o},i}function M(){var n,u=function(n){return n[0]},o=function(n){return n[1]},i=3,f=function(f){if(1===i){var h=c().x(u).y(o).domain(n)(f),v=[h[0],h[1]];return v.coefficients=[h.b,h.a],v.predict=h.predict,v.rSquared=h.rSquared,v}if(2===i){var h=p().x(u).y(o).domain(n)(f),v=[h[0],h[1]];return v.coefficients=[h.c,h.b,h.a],v.predict=h.predict,v.rSquared=h.rSquared,v}var l=r(f,u,o),g=l[0],s=l[1],d=l[2],M=l[3],w=g.length,x=i+1,m=[],F=[],q=0,S=0,A=n?+n[0]:1/0,L=n?+n[1]:-1/0;t(f,u,o,function(r,t){S++,q+=(t-q)/S,n||(rL&&(L=r))});for(var P=0;P=0;--o){var a=r[o];u[o]+=a;for(var i=1,f=1;f<=o;++f)i*=(o+1-f)/f,u[o-f]+=a*Math.pow(t,f)*i}return u[0]+=e,u}function b(n){for(var r=n.length-1,t=new Array(r),e=0;eMath.abs(n[e][u])&&(u=o);for(var a=e;a=e;a--)n[a][o]-=n[a][e]*n[e][o]/n[e][e]}for(var o=r-1;o>=0;o--){for(var i=0,a=o+1;ad&&(d=r))});var p=i(c,h,v,l),M=p[0],y=p[1];M=Math.exp(M);var b=function(n){return M*Math.pow(n,y)},w=a(s,d,b);return w.a=M,w.b=y,w.predict=b,w.rSquared=e(o,r,u,g,b),w};return o.domain=function(r){return arguments.length?(n=r,o):n},o.x=function(n){return arguments.length?(r=n,o):r},o.y=function(n){return arguments.length?(u=n,o):u},o}var x=2,m=1e-12;n.regressionExp=f,n.regressionLinear=c,n.regressionLoess=v,n.regressionLog=d,n.regressionPoly=M,n.regressionPow=w,n.regressionQuad=p,Object.defineProperty(n,"__esModule",{value:!0})}); \ No newline at end of file diff --git a/dist/src/exponential.d.ts b/dist/src/exponential.d.ts index 2de7c09..8ff11b9 100644 --- a/dist/src/exponential.d.ts +++ b/dist/src/exponential.d.ts @@ -5,15 +5,13 @@ export type ExponentialOutput = [DataPoint, DataPoint] & { predict: PredictFunction; rSquared: number; }; -type ExponentialRegressionRoot = (data: DataPoint[]) => ExponentialOutput; -export interface ExponentialRegression extends ExponentialRegressionRoot { - (data: DataPoint[]): ExponentialOutput; +export interface ExponentialRegression { + (data: T[]): ExponentialOutput; domain(): Domain; domain(arr: Domain): this; - x(): Accessor; - x(fn: Accessor): this; - y(): Accessor; - y(fn: Accessor): this; + x(): Accessor; + x(fn: Accessor): this; + y(): Accessor; + y(fn: Accessor): this; } -export default function exponential(): ExponentialRegression; -export {}; +export default function exponential(): ExponentialRegression; diff --git a/dist/src/linear.d.ts b/dist/src/linear.d.ts index 80e1e2d..7857536 100644 --- a/dist/src/linear.d.ts +++ b/dist/src/linear.d.ts @@ -5,15 +5,13 @@ export type LinearOutput = [DataPoint, DataPoint] & { predict: PredictFunction; rSquared: number; }; -type LinearRegressionRoot = (data: DataPoint[]) => LinearOutput; -export interface LinearRegression extends LinearRegressionRoot { - (data: DataPoint[]): LinearOutput; +export interface LinearRegression { + (data: T[]): LinearOutput; domain(): Domain; domain(arr: Domain): this; - x(): Accessor; - x(fn: Accessor): this; - y(): Accessor; - y(fn: Accessor): this; + x(): Accessor; + x(fn: Accessor): this; + y(): Accessor; + y(fn: Accessor): this; } -export default function linear(): LinearRegression; -export {}; +export default function linear(): LinearRegression; diff --git a/dist/src/loess.d.ts b/dist/src/loess.d.ts index fff1774..ec2f0e6 100644 --- a/dist/src/loess.d.ts +++ b/dist/src/loess.d.ts @@ -1,13 +1,11 @@ import { Accessor, DataPoint } from "./types"; -type LoessRegressionRoot = (data: DataPoint[]) => Array; -export interface LoessRegression extends LoessRegressionRoot { - (data: DataPoint[]): Array; +export interface LoessRegression { + (data: T[]): DataPoint[]; bandwidth(): number; bandwidth(bw: number): this; - x(): Accessor; - x(fn: Accessor): this; - y(): Accessor; - y(fn: Accessor): this; + x(): Accessor; + x(fn: Accessor): this; + y(): Accessor; + y(fn: Accessor): this; } -export default function loess(): LoessRegression; -export {}; +export default function loess(): LoessRegression; diff --git a/dist/src/logarithmic.d.ts b/dist/src/logarithmic.d.ts index bb0e2b5..1420628 100644 --- a/dist/src/logarithmic.d.ts +++ b/dist/src/logarithmic.d.ts @@ -1,22 +1,20 @@ import { PredictFunction, DataPoint, Accessor, Domain } from "./types"; -type OutputRoot = [DataPoint, DataPoint]; -type LogarithmicOutput = OutputRoot & { +type LogarithmicOutput = [DataPoint, DataPoint] & { a: number; b: number; predict: PredictFunction; rSquared: number; }; -type LogarithmicRegressionRoot = (data: DataPoint[]) => LogarithmicOutput; -export interface LogarithmicRegression extends LogarithmicRegressionRoot { - (data: DataPoint[]): LogarithmicOutput; +export interface LogarithmicRegression { + (data: T[]): LogarithmicOutput; domain(): Domain; domain(arr: Domain): this; - x(): Accessor; - x(fn: Accessor): this; - y(): Accessor; - y(fn: Accessor): this; + x(): Accessor; + x(fn: Accessor): this; + y(): Accessor; + y(fn: Accessor): this; base(): number; base(b: number): this; } -export default function logarithmic(): LogarithmicRegression; +export default function logarithmic(): LogarithmicRegression; export {}; diff --git a/dist/src/polynomial.d.ts b/dist/src/polynomial.d.ts index e348d20..b32400a 100644 --- a/dist/src/polynomial.d.ts +++ b/dist/src/polynomial.d.ts @@ -1,21 +1,18 @@ import { PredictFunction, Accessor, DataPoint, Domain } from "./types"; -type PolynomialOutputRoot = [DataPoint, DataPoint]; -export type PolynomialOutput = PolynomialOutputRoot & { +export type PolynomialOutput = [DataPoint, DataPoint] & { coefficients: number[]; predict: PredictFunction; rSquared: number; }; -type PolynomialRegressionRoot = (data: DataPoint[]) => PolynomialOutput; -export interface PolynomialRegression extends PolynomialRegressionRoot { - (data: DataPoint[]): PolynomialOutput; +export interface PolynomialRegression { + (data: T[]): PolynomialOutput; domain(): Domain; - domain(domain?: Domain): PolynomialRegression; - x(): Accessor; - x(x: Accessor): PolynomialRegression; - y(): Accessor; - y(y: Accessor): PolynomialRegression; + domain(domain?: Domain): this; + x(): Accessor; + x(x: Accessor): this; + y(): Accessor; + y(y: Accessor): this; order(): number; - order(order: number): PolynomialRegression; + order(order: number): this; } -export default function polynomial(): PolynomialRegression; -export {}; +export default function polynomial(): PolynomialRegression; diff --git a/dist/src/power.d.ts b/dist/src/power.d.ts index 2950a94..c6b8f9a 100644 --- a/dist/src/power.d.ts +++ b/dist/src/power.d.ts @@ -1,20 +1,18 @@ import { PredictFunction, DataPoint, Accessor, Domain } from "./types"; -type PowerOutputRoot = [DataPoint, DataPoint]; -interface PowerOutput extends PowerOutputRoot { +export type PowerOutput = [DataPoint, DataPoint] & { a: number; b: number; predict: PredictFunction; rSquared: number; -} -type PowerRegressionRoot = (data: DataPoint[]) => PowerOutput; -interface PowerRegression extends PowerRegressionRoot { - (data: DataPoint[]): PowerOutput; +}; +interface PowerRegression { + (data: T[]): PowerOutput; domain(): Domain; - domain(domain?: Domain): PowerRegression; - x(): Accessor; - x(x: Accessor): PowerRegression; - y(): Accessor; - y(y: Accessor): PowerRegression; + domain(domain?: Domain): this; + x(): Accessor; + x(x: Accessor): this; + y(): Accessor; + y(y: Accessor): this; } -export default function power(): PowerRegression; +export default function power(): PowerRegression; export {}; diff --git a/dist/src/quadratic.d.ts b/dist/src/quadratic.d.ts index 4dc566e..15c6567 100644 --- a/dist/src/quadratic.d.ts +++ b/dist/src/quadratic.d.ts @@ -1,21 +1,19 @@ import { Accessor, DataPoint, PredictFunction, Domain } from "./types"; -type QuadraticOutputRoot = [DataPoint, DataPoint]; -interface QuadraticOutput extends QuadraticOutputRoot { +export type QuadraticOutput = [DataPoint, DataPoint] & { a: number; b: number; c: number; predict: PredictFunction; rSquared: number; -} -type QuadraticRegressionRoot = (data: DataPoint[]) => QuadraticOutput; -interface QuadraticRegression extends QuadraticRegressionRoot { - (data: DataPoint[]): QuadraticOutput; +}; +interface QuadraticRegression { + (data: T[]): QuadraticOutput; domain(): Domain; - domain(domain?: Domain): QuadraticRegression; - x(): Accessor; - x(x: Accessor): QuadraticRegression; - y(): Accessor; - y(y: Accessor): QuadraticRegression; + domain(domain?: Domain): this; + x(): Accessor; + x(x: Accessor): this; + y(): Accessor; + y(y: Accessor): this; } -export default function quadratic(): QuadraticRegression; +export default function quadratic(): QuadraticRegression; export {}; diff --git a/dist/src/types.d.ts b/dist/src/types.d.ts index 319ab30..f31848d 100644 --- a/dist/src/types.d.ts +++ b/dist/src/types.d.ts @@ -1,4 +1,4 @@ export type DataPoint = [number, number]; -export type Accessor = (d: any, i?: number, data?: DataPoint[]) => number; +export type Accessor = (d: T, i?: number, data?: T[]) => number; export type PredictFunction = (x: number) => number; export type Domain = [number, number] | undefined; diff --git a/dist/src/utils/determination.d.ts b/dist/src/utils/determination.d.ts index 01aebbb..69bbed2 100644 --- a/dist/src/utils/determination.d.ts +++ b/dist/src/utils/determination.d.ts @@ -1,6 +1,6 @@ -import { Accessor, DataPoint, PredictFunction } from "../types"; +import { Accessor, PredictFunction } from "../types"; /** * Given a dataset, x- and y-accessors, the mean center of the y-values (uY), * and a prediction function, return the coefficient of determination, R^2. */ -export declare function determination(data: DataPoint[], x: Accessor, y: Accessor, uY: number, predict: PredictFunction): number; +export declare function determination(data: T[], x: Accessor, y: Accessor, uY: number, predict: PredictFunction): number; diff --git a/dist/src/utils/points.d.ts b/dist/src/utils/points.d.ts index e88a526..f471c45 100644 --- a/dist/src/utils/points.d.ts +++ b/dist/src/utils/points.d.ts @@ -1,11 +1,11 @@ -import { Accessor, DataPoint } from "../types"; +import { Accessor } from "../types"; /** * Adapted from vega-statistics by Jeffrey Heer * License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE * Source: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/packages/vega-statistics/src/regression/points.js */ -export declare function points(data: DataPoint[], x: Accessor, y: Accessor, sort?: boolean): [Float64Array, Float64Array, number, number]; +export declare function points(data: T[], x: Accessor, y: Accessor, sort?: boolean): [Float64Array, Float64Array, number, number]; /** * Iterates over valid data points, invoking a callback for each. */ -export declare function visitPoints(data: DataPoint[], x: Accessor, y: Accessor, cb: (dx: number, dy: number, index: number) => void): void; +export declare function visitPoints(data: T[], x: Accessor, y: Accessor, cb: (dx: number, dy: number, index: number) => void): void; diff --git a/src/exponential.ts b/src/exponential.ts index 9b6ecc7..dc1f310 100644 --- a/src/exponential.ts +++ b/src/exponential.ts @@ -12,27 +12,25 @@ export type ExponentialOutput = [DataPoint, DataPoint] & { rSquared: number; } -type ExponentialRegressionRoot = (data: DataPoint[]) => ExponentialOutput - -export interface ExponentialRegression extends ExponentialRegressionRoot { - (data: DataPoint[]): ExponentialOutput; +export interface ExponentialRegression { + (data: T[]): ExponentialOutput; domain(): Domain; domain(arr: Domain): this; - x(): Accessor; - x(fn: Accessor): this; + x(): Accessor; + x(fn: Accessor): this; - y(): Accessor; - y(fn: Accessor): this; + y(): Accessor; + y(fn: Accessor): this; } -export default function exponential(): ExponentialRegression { - let x: Accessor = d => d[0], - y: Accessor = d => d[1], +export default function exponential(): ExponentialRegression { + let y: Accessor = (d: T) => (d as DataPoint)[1], + x: Accessor = (d: T) => (d as DataPoint)[0], domain: Domain; - const exponentialRegression = function (data: DataPoint[]): ExponentialOutput { + const exponentialRegression = function (data: T[]): ExponentialOutput { let n = 0, Y = 0, YL = 0, @@ -70,25 +68,25 @@ export default function exponential(): ExponentialRegression { out.rSquared = determination(data, x, y, Y, fn); return out; - } as ExponentialRegression; + } as ExponentialRegression; exponentialRegression.domain = function (arr) { if (!arguments.length) return domain; domain = arr; return exponentialRegression; - } as ExponentialRegression["domain"]; + } as ExponentialRegression['domain']; - exponentialRegression.x = function (fn?: Accessor) { + exponentialRegression.x = function (fn?: Accessor) { if (!arguments.length) return x; x = fn!; return exponentialRegression; - } as ExponentialRegression["x"]; + } as ExponentialRegression['x']; - exponentialRegression.y = function (fn?: Accessor) { + exponentialRegression.y = function (fn?: Accessor) { if (!arguments.length) return y; y = fn!; return exponentialRegression; - } as ExponentialRegression["y"]; + } as ExponentialRegression['y']; return exponentialRegression; } diff --git a/src/linear.ts b/src/linear.ts index 693b0b2..d9c8e21 100644 --- a/src/linear.ts +++ b/src/linear.ts @@ -3,35 +3,33 @@ import { ols } from "./utils/ols"; import { visitPoints } from "./utils/points"; import { PredictFunction, Accessor, DataPoint, Domain } from "./types"; - -export type LinearOutput = [DataPoint, DataPoint] & { +export type LinearOutput = [DataPoint, DataPoint] & { a: number; // slope b: number; // intercept predict: PredictFunction rSquared: number; -} -type LinearRegressionRoot = (data: DataPoint[]) => LinearOutput +}; -export interface LinearRegression extends LinearRegressionRoot { - (data: DataPoint[]): LinearOutput; - +export interface LinearRegression { + (data: T[]): LinearOutput; + domain(): Domain; domain(arr: Domain): this; - - x(): Accessor; - x(fn: Accessor): this; - - y(): Accessor; - y(fn: Accessor): this; + + x(): Accessor; + x(fn: Accessor): this; + + y(): Accessor; + y(fn: Accessor): this; } -export default function linear():LinearRegression { - let x: Accessor = (d) => d[0], - y: Accessor = (d) => d[1], - domain: Domain; - - const linearRegression = function (data: DataPoint[]): LinearOutput { +export default function linear(): LinearRegression { + let x: Accessor = (d: T) => (d as DataPoint)[0], + y: Accessor = (d: T) => (d as DataPoint)[1], + domain: Domain; + + const linearRegression = function (data: T[]): LinearOutput { let n = 0, X = 0, // sum of x Y = 0, // sum of y @@ -46,16 +44,16 @@ export default function linear():LinearRegression { Y += (dy - Y) / n; XY += (dx * dy - XY) / n; X2 += (dx * dx - X2) / n; - + if (!domain) { if (dx < xmin) xmin = dx; if (dx > xmax) xmax = dx; } }); - + const [intercept, slope] = ols(X, Y, XY, X2); const fn = (xx: number) => slope * xx + intercept; - + const out = [[xmin, fn(xmin)], [xmax, fn(xmax)]] as LinearOutput; out.a = slope; out.b = intercept; @@ -63,25 +61,25 @@ export default function linear():LinearRegression { out.rSquared = determination(data, x, y, Y, fn); return out; - } as LinearRegression + } as LinearRegression linearRegression.domain = function (arr) { if (!arguments.length) return domain; domain = arr; return linearRegression; - } as LinearRegression["domain"]; - - linearRegression.x = function (fn?: Accessor) { + } as LinearRegression['domain']; + + linearRegression.x = function (fn?: Accessor) { if (!arguments.length) return x; x = fn!; return linearRegression; - } as LinearRegression["x"]; - - linearRegression.y = function (fn?: Accessor) { + } as LinearRegression['x']; + + linearRegression.y = function (fn?: Accessor) { if (!arguments.length) return y; y = fn!; return linearRegression; - } as LinearRegression["y"]; - + } as LinearRegression['y']; + return linearRegression; } diff --git a/src/loess.ts b/src/loess.ts index 0f39549..5b9ee5d 100644 --- a/src/loess.ts +++ b/src/loess.ts @@ -13,32 +13,26 @@ import { Accessor, DataPoint } from "./types"; const maxiters = 2, epsilon = 1e-12; -type LoessRegressionRoot = (data: DataPoint[]) => Array; +export interface LoessRegression { + (data: T[]): DataPoint[]; -export interface LoessRegression extends LoessRegressionRoot { - (data: DataPoint[]): Array; - bandwidth(): number; - bandwidth(bw: number): this; - - x(): Accessor; - - x(fn: Accessor): this; - - y(): Accessor; - - y(fn: Accessor): this; + + x(): Accessor; + x(fn: Accessor): this; + + y(): Accessor; + y(fn: Accessor): this; } +export default function loess(): LoessRegression { + let x: Accessor = (d: T) => (d as DataPoint)[0], + y: Accessor = (d: T) => (d as DataPoint)[1], + bandwidth = 0.3; -export default function loess(): LoessRegression { - let x: Accessor = d => d[0], - y: Accessor = d => d[1], - bandwidth = .3; - - const loessRegression = function loessRegression(data: DataPoint[]): Array { - const [xv, yv, ux, uy] = points(data, x, y, true); + const loessRegression = function loessRegression(data: T[]): Array { + const [xv, yv, ux, uy] = points(data, (dd) => x(dd), (dd) => y(dd), true); const n = xv.length; const bw = Math.max(2, ~~(bandwidth * n)); // # of nearest neighbors const yhat = new Float64Array(n); @@ -93,26 +87,26 @@ export default function loess(): LoessRegression { } return output(xv, yhat, ux, uy); - } as LoessRegression + } as LoessRegression loessRegression.bandwidth = function (bw?: number) { if (!arguments.length) return bandwidth; bandwidth = bw!; return loessRegression; - } as LoessRegression["bandwidth"]; - - loessRegression.x = function (fn?: Accessor) { + } as LoessRegression['bandwidth']; + + loessRegression.x = function (fn?: Accessor) { if (!arguments.length) return x; x = fn!; return loessRegression; - } as LoessRegression["x"]; - - loessRegression.y = function (fn?: Accessor) { + } as LoessRegression['x']; + + loessRegression.y = function (fn?: Accessor) { if (!arguments.length) return y; y = fn!; return loessRegression; - } as LoessRegression["y"]; - + } as LoessRegression['y']; + return loessRegression; } diff --git a/src/logarithmic.ts b/src/logarithmic.ts index db356f6..f135217 100644 --- a/src/logarithmic.ts +++ b/src/logarithmic.ts @@ -5,38 +5,37 @@ import { visitPoints } from "./utils/points"; import { PredictFunction, DataPoint, Accessor, Domain } from "./types"; -type OutputRoot = [DataPoint, DataPoint] -type LogarithmicOutput = OutputRoot & { +type LogarithmicOutput = [DataPoint, DataPoint] & { a: number; // slope b: number; // intercept predict: PredictFunction rSquared: number; -} -type LogarithmicRegressionRoot = (data: DataPoint[]) => LogarithmicOutput +}; + -export interface LogarithmicRegression extends LogarithmicRegressionRoot { - (data: DataPoint[]): LogarithmicOutput; +export interface LogarithmicRegression { + (data: T[]): LogarithmicOutput; domain(): Domain; domain(arr: Domain): this; - x(): Accessor; - x(fn: Accessor): this; + x(): Accessor; + x(fn: Accessor): this; - y(): Accessor; - y(fn: Accessor): this; + y(): Accessor; + y(fn: Accessor): this; base(): number; base(b: number): this; } -export default function logarithmic(): LogarithmicRegression { - let x: Accessor = d => d[0], - y: Accessor = d => d[1], +export default function logarithmic(): LogarithmicRegression { + let x: Accessor = (d: T) => (d as DataPoint)[0], + y: Accessor = (d: T) => (d as DataPoint)[1], base: number = Math.E, domain: Domain; - const logarithmicRegression = function logarithmicRegression(data: DataPoint[]): LogarithmicOutput { + const logarithmicRegression = function (data: T[]): LogarithmicOutput { let n = 0, X = 0, Y = 0, @@ -70,31 +69,31 @@ export default function logarithmic(): LogarithmicRegression { out.rSquared = determination(data, x, y, Y, fn); return out; - } as LogarithmicRegression; + } as LogarithmicRegression; logarithmicRegression.domain = function (arr?: [number, number]) { if (!arguments.length) return domain; domain = arr; return logarithmicRegression; - } as LogarithmicRegression["domain"]; + } as LogarithmicRegression['domain']; - logarithmicRegression.x = function (fn?: Accessor) { + logarithmicRegression.x = function (fn?: Accessor) { if (!arguments.length) return x; x = fn!; return logarithmicRegression; - } as LogarithmicRegression["x"]; + } as LogarithmicRegression['x']; - logarithmicRegression.y = function (fn?: Accessor) { + logarithmicRegression.y = function (fn?: Accessor) { if (!arguments.length) return y; y = fn!; return logarithmicRegression; - } as LogarithmicRegression["y"]; + } as LogarithmicRegression['y']; logarithmicRegression.base = function (b?: number) { if (!arguments.length) return base; base = b!; return logarithmicRegression; - } as LogarithmicRegression["base"]; + } as LogarithmicRegression['base']; return logarithmicRegression; } diff --git a/src/polynomial.ts b/src/polynomial.ts index d26cf1d..fb3fc6c 100644 --- a/src/polynomial.ts +++ b/src/polynomial.ts @@ -13,63 +13,48 @@ import linear from "./linear"; import quad from "./quadratic"; import { PredictFunction, Accessor, DataPoint, Domain } from "./types"; - -type PolynomialOutputRoot = [DataPoint, DataPoint] - -export type PolynomialOutput = PolynomialOutputRoot & { +export type PolynomialOutput = [DataPoint, DataPoint] & { coefficients: number[]; predict: PredictFunction; rSquared: number; -} +}; -type PolynomialRegressionRoot = (data: DataPoint[]) => PolynomialOutput; -export interface PolynomialRegression extends PolynomialRegressionRoot { - (data: DataPoint[]): PolynomialOutput; - +export interface PolynomialRegression { + (data: T[]): PolynomialOutput; + domain(): Domain; - - domain(domain?: Domain): PolynomialRegression; - - x(): Accessor; - - x(x: Accessor): PolynomialRegression; - - y(): Accessor; - - y(y: Accessor): PolynomialRegression; - + domain(domain?: Domain): this; + + x(): Accessor; + x(x: Accessor): this; + + y(): Accessor; + y(y: Accessor): this; + order(): number; - - order(order: number): PolynomialRegression; + order(order: number): this; } +export default function polynomial(): PolynomialRegression { + let x: Accessor = (d: T) => (d as DataPoint)[0], + y: Accessor = (d: T) => (d as DataPoint)[1], + order = 3, + domain: Domain; -export default function polynomial(): PolynomialRegression { - let x: Accessor = d => d[0], - y: Accessor = d => d[1], - order = 3, - domain: Domain; - - const polynomialRegression = function polynomialRegression(data: DataPoint[]): PolynomialOutput { + const polynomialRegression = function polynomialRegression(data: T[]): PolynomialOutput { // Shortcut for lower-order polynomials: if (order === 1) { - const o = linear().x(x).y(y).domain(domain)(data); - const result = [ - o[0], - o[1], - ] as PolynomialOutput; + const o = linear().x(x).y(y).domain(domain)(data); + const result = [o[0], o[1]] as PolynomialOutput; result.coefficients = [o.b, o.a]; result.predict = o.predict; result.rSquared = o.rSquared; return result; } if (order === 2) { - const o = quad().x(x).y(y).domain(domain)(data); - const result = [ - o[0], - o[1], - ] as PolynomialOutput; + const o = quad().x(x).y(y).domain(domain)(data); + const result = [o[0], o[1]] as PolynomialOutput; result.coefficients = [o.c, o.b, o.a]; result.predict = o.predict; result.rSquared = o.rSquared; @@ -81,7 +66,7 @@ export default function polynomial(): PolynomialRegression { const k = order + 1; const lhs: number[] = []; const rhs: Float64Array[] = []; - + let Y = 0, n0 = 0, xmin = domain ? +domain[0] : Infinity, @@ -95,7 +80,7 @@ export default function polynomial(): PolynomialRegression { if (dx > xmax) xmax = dx; } }); - + // Build normal equations for (let i = 0; i < k; i++) { // LHS @@ -104,7 +89,7 @@ export default function polynomial(): PolynomialRegression { v += Math.pow(xv[l], i) * yv[l]; } lhs.push(v); - + // RHS const c = new Float64Array(k); for (let j = 0; j < k; j++) { @@ -117,7 +102,7 @@ export default function polynomial(): PolynomialRegression { rhs.push(c); } rhs.push(new Float64Array(lhs)); - + const coef = gaussianElimination(rhs); const fn = (xx: number) => { let shifted = xx - ux; @@ -134,32 +119,32 @@ export default function polynomial(): PolynomialRegression { out.rSquared = determination(data, x, y, Y, fn); return out; - } as PolynomialRegression; + } as PolynomialRegression; polynomialRegression.domain = function (arr?: [number, number]) { if (!arguments.length) return domain; domain = arr; return polynomialRegression; - } as PolynomialRegression["domain"]; - - polynomialRegression.x = function (fn?: Accessor) { + } as PolynomialRegression['domain']; + + polynomialRegression.x = function (fn?: Accessor) { if (!arguments.length) return x; x = fn!; return polynomialRegression; - } as PolynomialRegression["x"]; - - polynomialRegression.y = function (fn?: Accessor) { + } as PolynomialRegression['x']; + + polynomialRegression.y = function (fn?: Accessor) { if (!arguments.length) return y; y = fn!; return polynomialRegression; - } as PolynomialRegression["y"]; - + } as PolynomialRegression['y']; + polynomialRegression.order = function (n?: number) { if (!arguments.length) return order; order = n!; return polynomialRegression; - } as PolynomialRegression["order"]; - + } as PolynomialRegression['order']; + return polynomialRegression; } @@ -183,7 +168,7 @@ function uncenter(k: number, a: number[], x: number, y: number): number[] { function gaussianElimination(matrix: Float64Array[]): number[] { const n = matrix.length - 1; const coef = new Array(n); - + for (let i = 0; i < n; i++) { let r = i; // find pivot row diff --git a/src/power.ts b/src/power.ts index 7fd8aa6..54a140e 100644 --- a/src/power.ts +++ b/src/power.ts @@ -4,34 +4,33 @@ import { ols } from "./utils/ols"; import { visitPoints } from "./utils/points"; import { PredictFunction, DataPoint, Accessor, Domain } from "./types"; -type PowerOutputRoot = [DataPoint, DataPoint]; - -interface PowerOutput extends PowerOutputRoot { +export type PowerOutput = [DataPoint, DataPoint] & { a: number; b: number; predict: PredictFunction; rSquared: number; } -type PowerRegressionRoot = (data: DataPoint[]) => PowerOutput; -interface PowerRegression extends PowerRegressionRoot{ - (data: DataPoint[]): PowerOutput; + +interface PowerRegression { + (data: T[]): PowerOutput; + domain(): Domain; - domain(domain?: Domain): PowerRegression; - - x(): Accessor; - x(x: Accessor): PowerRegression; - - y(): Accessor; - y(y: Accessor): PowerRegression; + domain(domain?: Domain): this; + + x(): Accessor; + x(x: Accessor): this; + + y(): Accessor; + y(y: Accessor): this; } -export default function power(): PowerRegression { - let x: Accessor = d => d[0], - y: Accessor = d => d[1], +export default function power(): PowerRegression { + let x: Accessor = (d: T) => (d as DataPoint)[0], + y: Accessor = (d: T) => (d as DataPoint)[1], domain: Domain; - - const powerRegression =function powerRegression(data: DataPoint[]): PowerOutput { + + const powerRegression = function powerRegression(data: T[]): PowerOutput { let n = 0, X = 0, Y = 0, @@ -69,25 +68,25 @@ export default function power(): PowerRegression { out.rSquared = determination(data, x, y, YS, fn); return out; - } as PowerRegression; + } as PowerRegression; powerRegression.domain = function(arr?: Domain) { if (!arguments.length) return domain; domain = arr; return powerRegression; - } as PowerRegression["domain"]; + } as PowerRegression['domain']; - powerRegression.x = function(fn?: Accessor) { + powerRegression.x = function(fn?: Accessor) { if (!arguments.length) return x; x = fn!; return powerRegression; - } as PowerRegression["x"]; + } as PowerRegression['x']; - powerRegression.y = function(fn?: Accessor) { + powerRegression.y = function(fn?: Accessor) { if (!arguments.length) return y; y = fn!; return powerRegression; - } as PowerRegression["y"]; + } as PowerRegression['y']; return powerRegression; } diff --git a/src/quadratic.ts b/src/quadratic.ts index e89f745..3f91ffa 100644 --- a/src/quadratic.ts +++ b/src/quadratic.ts @@ -3,9 +3,7 @@ import { interpose } from "./utils/interpose"; import { points, visitPoints } from "./utils/points"; import { Accessor, DataPoint, PredictFunction, Domain } from "./types"; -type QuadraticOutputRoot = [DataPoint, DataPoint]; - -interface QuadraticOutput extends QuadraticOutputRoot { +export type QuadraticOutput = [DataPoint, DataPoint] & { a: number; b: number; c: number; @@ -13,41 +11,36 @@ interface QuadraticOutput extends QuadraticOutputRoot { rSquared: number; } -type QuadraticRegressionRoot = (data: DataPoint[]) => QuadraticOutput; -interface QuadraticRegression extends QuadraticRegressionRoot { - (data: DataPoint[]): QuadraticOutput; - +interface QuadraticRegression { + (data: T[]): QuadraticOutput; + domain(): Domain; - - domain(domain?: Domain): QuadraticRegression; - - x(): Accessor; - - x(x: Accessor): QuadraticRegression; - - y(): Accessor; - - y(y: Accessor): QuadraticRegression; + domain(domain?: Domain): this; + + x(): Accessor; + x(x: Accessor): this; + + y(): Accessor; + y(y: Accessor): this; } +export default function quadratic(): QuadraticRegression { + let x: Accessor = (d: T) => (d as DataPoint)[0], + y: Accessor = (d: T) => (d as DataPoint)[1], + domain: Domain; -export default function quadratic(): QuadraticRegression { - let x: Accessor = d => d[0], - y: Accessor = d => d[1], - domain: Domain; - - const quadraticRegression = function quadraticRegression(data: DataPoint[]): QuadraticOutput { - const [xv, yv, ux, uy] = points(data, x, y); + const quadraticRegression = function quadraticRegression(data: T[]): QuadraticOutput { + const [xv, yv, ux, uy] = points(data, (dd) => x(dd), (dd) => y(dd)); const n = xv.length; - + let X2 = 0, - X3 = 0, - X4 = 0, - XY = 0, - X2Y = 0, - i, dx, dy, x2; - + X3 = 0, + X4 = 0, + XY = 0, + X2Y = 0, + i, dx, dy, x2; + for (i = 0; i < n;) { dx = xv[i]; dy = yv[i++]; @@ -72,7 +65,7 @@ export default function quadratic(): QuadraticRegression { if (dx2 > xmax) xmax = dx2; } }); - + const X2X2 = X4 - (X2 * X2); const d = (X2 * X2X2 - X3 * X3); const a = (X2Y * X2 - XY * X3) / d; @@ -82,7 +75,7 @@ export default function quadratic(): QuadraticRegression { const shifted = xx - ux; return a * shifted * shifted + b * shifted + c + uy; }; - + const out = interpose(xmin, xmax, fn) as QuadraticOutput; out.a = a; out.b = b - 2 * a * ux; @@ -91,25 +84,25 @@ export default function quadratic(): QuadraticRegression { out.rSquared = determination(data, x, y, Y, fn); return out; - } as QuadraticRegression; + } as QuadraticRegression; quadraticRegression.domain = function (arr?: Domain) { if (!arguments.length) return domain; domain = arr; return quadraticRegression; - } as QuadraticRegression["domain"]; - - quadraticRegression.x = function (fn?: Accessor) { + } as QuadraticRegression['domain']; + + quadraticRegression.x = function (fn?: Accessor) { if (!arguments.length) return x; x = fn!; return quadraticRegression; - } as QuadraticRegression["x"]; - - quadraticRegression.y = function (fn?: Accessor) { + } as QuadraticRegression['x']; + + quadraticRegression.y = function (fn?: Accessor) { if (!arguments.length) return y; y = fn!; return quadraticRegression; - } as QuadraticRegression["y"]; - + } as QuadraticRegression['y']; + return quadraticRegression; } diff --git a/src/types.ts b/src/types.ts index fa32d29..f31848d 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,5 +1,4 @@ - export type DataPoint = [number, number]; -export type Accessor = (d: any, i?: number, data?: DataPoint[]) => number; +export type Accessor = (d: T, i?: number, data?: T[]) => number; export type PredictFunction = (x: number) => number; export type Domain = [number, number] | undefined; diff --git a/src/utils/determination.ts b/src/utils/determination.ts index e443b7d..1c23e79 100644 --- a/src/utils/determination.ts +++ b/src/utils/determination.ts @@ -5,10 +5,10 @@ import { Accessor, DataPoint, PredictFunction } from "../types"; * Given a dataset, x- and y-accessors, the mean center of the y-values (uY), * and a prediction function, return the coefficient of determination, R^2. */ -export function determination( - data: DataPoint[], - x: Accessor, - y: Accessor, +export function determination( + data: T[], + x: Accessor, + y: Accessor, uY: number, predict: PredictFunction ): number { diff --git a/src/utils/points.ts b/src/utils/points.ts index c197337..944377e 100644 --- a/src/utils/points.ts +++ b/src/utils/points.ts @@ -1,14 +1,14 @@ -import { Accessor, DataPoint } from "../types"; +import { Accessor } from "../types"; /** * Adapted from vega-statistics by Jeffrey Heer * License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE * Source: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/packages/vega-statistics/src/regression/points.js */ -export function points( - data: DataPoint[], - x: Accessor, - y: Accessor, +export function points( + data: T[], + x: Accessor, + y: Accessor, sort?: boolean ): [Float64Array, Float64Array, number, number] { data = data.filter((d, i) => { @@ -28,7 +28,7 @@ export function points( // extract values, calculate means let ux = 0, uy = 0, xv, yv, d; - for (let i = 0; i < n; ) { + for (let i = 0; i < n;) { d = data[i]; X[i] = xv = +x(d, i, data); Y[i] = yv = +y(d, i, data); @@ -49,10 +49,10 @@ export function points( /** * Iterates over valid data points, invoking a callback for each. */ -export function visitPoints( - data: DataPoint[], - x: Accessor, - y: Accessor, +export function visitPoints( + data: T[], + x: Accessor, + y: Accessor, cb: (dx: number, dy: number, index: number) => void ): void { let iterations = 0; From 6299477a46f3d7840560ef8eaed1d986e2098b37 Mon Sep 17 00:00:00 2001 From: Kirill Baldin Date: Wed, 15 Jan 2025 18:43:32 +0400 Subject: [PATCH 04/10] Add sigmoidal regression support --- dist/d3-regression.cjs.js | 94 +++++++++++++++++++++++++++ dist/d3-regression.esm.js | 95 ++++++++++++++++++++++++++- dist/d3-regression.js | 94 +++++++++++++++++++++++++++ dist/d3-regression.min.js | 2 +- dist/index.d.ts | 1 + dist/src/sigmoidal.d.ts | 24 +++++++ index.ts | 3 +- src/sigmoidal.ts | 133 ++++++++++++++++++++++++++++++++++++++ 8 files changed, 443 insertions(+), 3 deletions(-) create mode 100644 dist/src/sigmoidal.d.ts create mode 100644 src/sigmoidal.ts diff --git a/dist/d3-regression.cjs.js b/dist/d3-regression.cjs.js index d9e67e1..ea9f596 100644 --- a/dist/d3-regression.cjs.js +++ b/dist/d3-regression.cjs.js @@ -668,6 +668,99 @@ function power() { return powerRegression; } +function sigmoidal() { + var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, domain, maxIter = 2000, alpha = 1e-4; // learning rate + function sigmoidalRegression(data) { + var n = 0, Xmin = domain ? +domain[0] : Infinity, Xmax = domain ? +domain[1] : -Infinity, Ymin = Infinity, Ymax = -Infinity, sumY = 0; + // Gather data & track min/max for domain if not preset + visitPoints(data, x, y, function (dx, dy) { + n++; + sumY += dy; + if (!domain) { + if (dx < Xmin) + Xmin = dx; + if (dx > Xmax) + Xmax = dx; + } + if (dy < Ymin) + Ymin = dy; + if (dy > Ymax) + Ymax = dy; + }); + if (!domain && (Xmin === Infinity || Xmax === -Infinity)) { + Xmin = 0; + Xmax = 1; + } + // Initialize parameters + var A = Ymax - Ymin; // amplitude + var B = 1; // logistic slope + var C = Ymin; // baseline offset + var M = (Xmin + Xmax) / 2; // midpoint + // Predict function + function f(xx) { + return C + A / (1 + Math.exp(-B * (xx - M))); + } + var _loop_1 = function (iter) { + var dA = 0, dB = 0, dC = 0, dM = 0; + visitPoints(data, x, y, function (dx, dy) { + var yhat = f(dx); + var err = dy - yhat; + var ex = Math.exp(-B * (dx - M)); + var g = 1 / (1 + ex); // logistic + // partial derivatives + var df_dA = g; + var df_dC = 1; + var df_dB = A * g * (1 - g) * (dx - M); + // Note the negative sign for M: + var df_dM = -A * B * g * (1 - g); + var factor = -2 * err; + dA += factor * df_dA; + dB += factor * df_dB; + dC += factor * df_dC; + dM += factor * df_dM; + }); + A -= alpha * (dA / n); + B -= alpha * (dB / n); + C -= alpha * (dC / n); + M -= alpha * (dM / n); + }; + // Gradient Descent + for (var iter = 0; iter < maxIter; iter++) { + _loop_1(); + } + var predict = function (xx) { return C + A / (1 + Math.exp(-B * (xx - M))); }; + var out = interpose(Xmin, Xmax, predict); + out.A = A; + out.B = B; + out.C = C; + out.M = M; + out.predict = predict; + // R^2 + var meanY = sumY / n; + out.rSquared = determination(data, x, y, meanY, predict); + return out; + } + sigmoidalRegression.domain = function (arr) { + if (!arguments.length) + return domain; + domain = arr; + return sigmoidalRegression; + }; + sigmoidalRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return sigmoidalRegression; + }; + sigmoidalRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return sigmoidalRegression; + }; + return sigmoidalRegression; +} + exports.regressionExp = exponential; exports.regressionLinear = linear; exports.regressionLoess = loess; @@ -675,3 +768,4 @@ exports.regressionLog = logarithmic; exports.regressionPoly = polynomial; exports.regressionPow = power; exports.regressionQuad = quadratic; +exports.regressionSigmoidal = sigmoidal; diff --git a/dist/d3-regression.esm.js b/dist/d3-regression.esm.js index 46034c0..f4d98e6 100644 --- a/dist/d3-regression.esm.js +++ b/dist/d3-regression.esm.js @@ -664,4 +664,97 @@ function power() { return powerRegression; } -export { exponential as regressionExp, linear as regressionLinear, loess as regressionLoess, logarithmic as regressionLog, polynomial as regressionPoly, power as regressionPow, quadratic as regressionQuad }; +function sigmoidal() { + var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, domain, maxIter = 2000, alpha = 1e-4; // learning rate + function sigmoidalRegression(data) { + var n = 0, Xmin = domain ? +domain[0] : Infinity, Xmax = domain ? +domain[1] : -Infinity, Ymin = Infinity, Ymax = -Infinity, sumY = 0; + // Gather data & track min/max for domain if not preset + visitPoints(data, x, y, function (dx, dy) { + n++; + sumY += dy; + if (!domain) { + if (dx < Xmin) + Xmin = dx; + if (dx > Xmax) + Xmax = dx; + } + if (dy < Ymin) + Ymin = dy; + if (dy > Ymax) + Ymax = dy; + }); + if (!domain && (Xmin === Infinity || Xmax === -Infinity)) { + Xmin = 0; + Xmax = 1; + } + // Initialize parameters + var A = Ymax - Ymin; // amplitude + var B = 1; // logistic slope + var C = Ymin; // baseline offset + var M = (Xmin + Xmax) / 2; // midpoint + // Predict function + function f(xx) { + return C + A / (1 + Math.exp(-B * (xx - M))); + } + var _loop_1 = function (iter) { + var dA = 0, dB = 0, dC = 0, dM = 0; + visitPoints(data, x, y, function (dx, dy) { + var yhat = f(dx); + var err = dy - yhat; + var ex = Math.exp(-B * (dx - M)); + var g = 1 / (1 + ex); // logistic + // partial derivatives + var df_dA = g; + var df_dC = 1; + var df_dB = A * g * (1 - g) * (dx - M); + // Note the negative sign for M: + var df_dM = -A * B * g * (1 - g); + var factor = -2 * err; + dA += factor * df_dA; + dB += factor * df_dB; + dC += factor * df_dC; + dM += factor * df_dM; + }); + A -= alpha * (dA / n); + B -= alpha * (dB / n); + C -= alpha * (dC / n); + M -= alpha * (dM / n); + }; + // Gradient Descent + for (var iter = 0; iter < maxIter; iter++) { + _loop_1(); + } + var predict = function (xx) { return C + A / (1 + Math.exp(-B * (xx - M))); }; + var out = interpose(Xmin, Xmax, predict); + out.A = A; + out.B = B; + out.C = C; + out.M = M; + out.predict = predict; + // R^2 + var meanY = sumY / n; + out.rSquared = determination(data, x, y, meanY, predict); + return out; + } + sigmoidalRegression.domain = function (arr) { + if (!arguments.length) + return domain; + domain = arr; + return sigmoidalRegression; + }; + sigmoidalRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return sigmoidalRegression; + }; + sigmoidalRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return sigmoidalRegression; + }; + return sigmoidalRegression; +} + +export { exponential as regressionExp, linear as regressionLinear, loess as regressionLoess, logarithmic as regressionLog, polynomial as regressionPoly, power as regressionPow, quadratic as regressionQuad, sigmoidal as regressionSigmoidal }; diff --git a/dist/d3-regression.js b/dist/d3-regression.js index 2bc9b8e..f6b0111 100644 --- a/dist/d3-regression.js +++ b/dist/d3-regression.js @@ -670,6 +670,99 @@ return powerRegression; } + function sigmoidal() { + var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, domain, maxIter = 2000, alpha = 1e-4; // learning rate + function sigmoidalRegression(data) { + var n = 0, Xmin = domain ? +domain[0] : Infinity, Xmax = domain ? +domain[1] : -Infinity, Ymin = Infinity, Ymax = -Infinity, sumY = 0; + // Gather data & track min/max for domain if not preset + visitPoints(data, x, y, function (dx, dy) { + n++; + sumY += dy; + if (!domain) { + if (dx < Xmin) + Xmin = dx; + if (dx > Xmax) + Xmax = dx; + } + if (dy < Ymin) + Ymin = dy; + if (dy > Ymax) + Ymax = dy; + }); + if (!domain && (Xmin === Infinity || Xmax === -Infinity)) { + Xmin = 0; + Xmax = 1; + } + // Initialize parameters + var A = Ymax - Ymin; // amplitude + var B = 1; // logistic slope + var C = Ymin; // baseline offset + var M = (Xmin + Xmax) / 2; // midpoint + // Predict function + function f(xx) { + return C + A / (1 + Math.exp(-B * (xx - M))); + } + var _loop_1 = function (iter) { + var dA = 0, dB = 0, dC = 0, dM = 0; + visitPoints(data, x, y, function (dx, dy) { + var yhat = f(dx); + var err = dy - yhat; + var ex = Math.exp(-B * (dx - M)); + var g = 1 / (1 + ex); // logistic + // partial derivatives + var df_dA = g; + var df_dC = 1; + var df_dB = A * g * (1 - g) * (dx - M); + // Note the negative sign for M: + var df_dM = -A * B * g * (1 - g); + var factor = -2 * err; + dA += factor * df_dA; + dB += factor * df_dB; + dC += factor * df_dC; + dM += factor * df_dM; + }); + A -= alpha * (dA / n); + B -= alpha * (dB / n); + C -= alpha * (dC / n); + M -= alpha * (dM / n); + }; + // Gradient Descent + for (var iter = 0; iter < maxIter; iter++) { + _loop_1(); + } + var predict = function (xx) { return C + A / (1 + Math.exp(-B * (xx - M))); }; + var out = interpose(Xmin, Xmax, predict); + out.A = A; + out.B = B; + out.C = C; + out.M = M; + out.predict = predict; + // R^2 + var meanY = sumY / n; + out.rSquared = determination(data, x, y, meanY, predict); + return out; + } + sigmoidalRegression.domain = function (arr) { + if (!arguments.length) + return domain; + domain = arr; + return sigmoidalRegression; + }; + sigmoidalRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return sigmoidalRegression; + }; + sigmoidalRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return sigmoidalRegression; + }; + return sigmoidalRegression; + } + exports.regressionExp = exponential; exports.regressionLinear = linear; exports.regressionLoess = loess; @@ -677,6 +770,7 @@ exports.regressionPoly = polynomial; exports.regressionPow = power; exports.regressionQuad = quadratic; + exports.regressionSigmoidal = sigmoidal; Object.defineProperty(exports, '__esModule', { value: true }); diff --git a/dist/d3-regression.min.js b/dist/d3-regression.min.js index 681f40f..1227620 100644 --- a/dist/d3-regression.min.js +++ b/dist/d3-regression.min.js @@ -1 +1 @@ -!function(n,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports):"function"==typeof define&&define.amd?define(["exports"],r):(n=n||self,r(n.d3={}))}(this,function(n){"use strict";function r(n,r,t,e){n=n.filter(function(n,e){var u=r(n,e),o=t(n,e);return null!=u&&isFinite(u)&&null!=o&&isFinite(o)}),e&&n.sort(function(n,t){return r(n)-r(t)});for(var u,o,a,i=n.length,f=new Float64Array(i),c=new Float64Array(i),h=0,v=0,l=0;li&&(n.splice(a+1,0,l),t=!0)}return t}(f)&&c<1e4;);return f}function i(n,r,t,e){var u=e-n*n,o=Math.abs(u)<1e-24?0:(t-n*r)/u;return[r-o*n,o]}function f(){var n,r=function(n){return n[1]},u=function(n){return n[0]},o=function(o){var f=0,c=0,h=0,v=0,l=0,g=0,s=n?+n[0]:1/0,d=n?+n[1]:-1/0;t(o,u,r,function(r,t){var e=Math.log(t),u=r*t;++f,c+=(t-c)/f,v+=(u-v)/f,g+=(r*u-g)/f,h+=(t*e-h)/f,l+=(u*e-l)/f,n||(rd&&(d=r))});var p=i(v/c,h/c,l/c,g/c),M=p[0],y=p[1];M=Math.exp(M);var b=function(n){return M*Math.exp(y*n)},w=a(s,d,b);return w.a=M,w.b=y,w.predict=b,w.rSquared=e(o,u,r,c,b),w};return o.domain=function(r){return arguments.length?(n=r,o):n},o.x=function(n){return arguments.length?(u=n,o):u},o.y=function(n){return arguments.length?(r=n,o):r},o}function c(){var n,r=function(n){return n[0]},u=function(n){return n[1]},o=function(o){var a=0,f=0,c=0,h=0,v=0,l=n?+n[0]:1/0,g=n?+n[1]:-1/0;t(o,r,u,function(r,t){++a,f+=(r-f)/a,c+=(t-c)/a,h+=(r*t-h)/a,v+=(r*r-v)/a,n||(rg&&(g=r))});var s=i(f,c,h,v),d=s[0],p=s[1],M=function(n){return p*n+d},y=[[l,M(l)],[g,M(g)]];return y.a=p,y.b=d,y.predict=M,y.rSquared=e(o,r,u,c,M),y};return o.domain=function(r){return arguments.length?(n=r,o):n},o.x=function(n){return arguments.length?(r=n,o):r},o.y=function(n){return arguments.length?(u=n,o):u},o}function h(n){n.sort(function(n,r){return n-r});var r=n.length/2;return r%1==0?(n[r-1]+n[r])/2:n[Math.floor(r)]}function v(){var n=function(n){return n[0]},t=function(n){return n[1]},e=.3,u=function(u){for(var o=r(u,function(r){return n(r)},function(n){return t(n)},!0),a=o[0],f=o[1],c=o[2],v=o[3],d=a.length,p=Math.max(2,~~(e*d)),M=new Float64Array(d),y=new Float64Array(d),b=new Float64Array(d).fill(1),w=-1;++w<=x;){for(var F=[0,p-1],q=0;qa[L]-S?A:L,E=0,j=0,k=0,O=0,_=0,G=1/Math.abs(a[P]-S||1),I=A;I<=L;++I){var Q=a[I],z=f[I],B=l(Math.abs(S-Q)*G)*b[I],C=Q*B;E+=B,j+=C,k+=z*B,O+=z*C,_+=Q*C}var D=i(j/E,k/E,O/E,_/E),H=D[0],J=D[1];M[q]=H+J*S,y[q]=Math.abs(f[q]-M[q]),g(a,q+1,F)}if(w===x)break;var K=h(y);if(Math.abs(K)=1?m:(B=1-N*N)*B}return s(a,M,c,v)};return u.bandwidth=function(n){return arguments.length?(e=n,u):e},u.x=function(r){return arguments.length?(n=r,u):n},u.y=function(n){return arguments.length?(t=n,u):t},u}function l(n){return(n=1-n*n*n)*n*n}function g(n,r,t){var e=n[r],u=t[0],o=t[1]+1;if(!(o>=n.length))for(;r>u&&n[o]-e<=e-n[u];)t[0]=++u,t[1]=o,++o}function s(n,r,t,e){for(var u,o=n.length,a=[],i=0,f=0,c=[];id&&(d=r))});var M=i(h,v,l,g),y=M[0],b=M[1],w=function(n){return b*Math.log(n)/p+y},x=a(s,d,w);return x.a=b,x.b=y,x.predict=w,x.rSquared=e(f,r,u,v,w),x};return f.domain=function(r){return arguments.length?(n=r,f):n},f.x=function(n){return arguments.length?(r=n,f):r},f.y=function(n){return arguments.length?(u=n,f):u},f.base=function(n){return arguments.length?(o=n,f):o},f}function p(){var n,u=function(n){return n[0]},o=function(n){return n[1]},i=function(i){var f,c,h,v,l=r(i,function(n){return u(n)},function(n){return o(n)}),g=l[0],s=l[1],d=l[2],p=l[3],M=g.length,y=0,b=0,w=0,x=0,m=0;for(f=0;fA&&(A=r))});var L=w-y*y,P=y*L-b*b,E=(m*y-x*b)/P,j=(x*L-m*b)/P,k=-E*y,O=function(n){var r=n-d;return E*r*r+j*r+k+p},_=a(S,A,O);return _.a=E,_.b=j-2*E*d,_.c=k-j*d+E*d*d+p,_.predict=O,_.rSquared=e(i,u,o,F,O),_};return i.domain=function(r){return arguments.length?(n=r,i):n},i.x=function(n){return arguments.length?(u=n,i):u},i.y=function(n){return arguments.length?(o=n,i):o},i}function M(){var n,u=function(n){return n[0]},o=function(n){return n[1]},i=3,f=function(f){if(1===i){var h=c().x(u).y(o).domain(n)(f),v=[h[0],h[1]];return v.coefficients=[h.b,h.a],v.predict=h.predict,v.rSquared=h.rSquared,v}if(2===i){var h=p().x(u).y(o).domain(n)(f),v=[h[0],h[1]];return v.coefficients=[h.c,h.b,h.a],v.predict=h.predict,v.rSquared=h.rSquared,v}var l=r(f,u,o),g=l[0],s=l[1],d=l[2],M=l[3],w=g.length,x=i+1,m=[],F=[],q=0,S=0,A=n?+n[0]:1/0,L=n?+n[1]:-1/0;t(f,u,o,function(r,t){S++,q+=(t-q)/S,n||(rL&&(L=r))});for(var P=0;P=0;--o){var a=r[o];u[o]+=a;for(var i=1,f=1;f<=o;++f)i*=(o+1-f)/f,u[o-f]+=a*Math.pow(t,f)*i}return u[0]+=e,u}function b(n){for(var r=n.length-1,t=new Array(r),e=0;eMath.abs(n[e][u])&&(u=o);for(var a=e;a=e;a--)n[a][o]-=n[a][e]*n[e][o]/n[e][e]}for(var o=r-1;o>=0;o--){for(var i=0,a=o+1;ad&&(d=r))});var p=i(c,h,v,l),M=p[0],y=p[1];M=Math.exp(M);var b=function(n){return M*Math.pow(n,y)},w=a(s,d,b);return w.a=M,w.b=y,w.predict=b,w.rSquared=e(o,r,u,g,b),w};return o.domain=function(r){return arguments.length?(n=r,o):n},o.x=function(n){return arguments.length?(r=n,o):r},o.y=function(n){return arguments.length?(u=n,o):u},o}var x=2,m=1e-12;n.regressionExp=f,n.regressionLinear=c,n.regressionLoess=v,n.regressionLog=d,n.regressionPoly=M,n.regressionPow=w,n.regressionQuad=p,Object.defineProperty(n,"__esModule",{value:!0})}); \ No newline at end of file +!function(n,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports):"function"==typeof define&&define.amd?define(["exports"],r):(n=n||self,r(n.d3={}))}(this,function(n){"use strict";function r(n,r,t,e){n=n.filter(function(n,e){var u=r(n,e),o=t(n,e);return null!=u&&isFinite(u)&&null!=o&&isFinite(o)}),e&&n.sort(function(n,t){return r(n)-r(t)});for(var u,o,a,i=n.length,f=new Float64Array(i),c=new Float64Array(i),v=0,h=0,l=0;li&&(n.splice(a+1,0,l),t=!0)}return t}(f)&&c<1e4;);return f}function i(n,r,t,e){var u=e-n*n,o=Math.abs(u)<1e-24?0:(t-n*r)/u;return[r-o*n,o]}function f(){var n,r=function(n){return n[1]},u=function(n){return n[0]},o=function(o){var f=0,c=0,v=0,h=0,l=0,g=0,s=n?+n[0]:1/0,d=n?+n[1]:-1/0;t(o,u,r,function(r,t){var e=Math.log(t),u=r*t;++f,c+=(t-c)/f,h+=(u-h)/f,g+=(r*u-g)/f,v+=(t*e-v)/f,l+=(u*e-l)/f,n||(rd&&(d=r))});var p=i(h/c,v/c,l/c,g/c),M=p[0],y=p[1];M=Math.exp(M);var b=function(n){return M*Math.exp(y*n)},x=a(s,d,b);return x.a=M,x.b=y,x.predict=b,x.rSquared=e(o,u,r,c,b),x};return o.domain=function(r){return arguments.length?(n=r,o):n},o.x=function(n){return arguments.length?(u=n,o):u},o.y=function(n){return arguments.length?(r=n,o):r},o}function c(){var n,r=function(n){return n[0]},u=function(n){return n[1]},o=function(o){var a=0,f=0,c=0,v=0,h=0,l=n?+n[0]:1/0,g=n?+n[1]:-1/0;t(o,r,u,function(r,t){++a,f+=(r-f)/a,c+=(t-c)/a,v+=(r*t-v)/a,h+=(r*r-h)/a,n||(rg&&(g=r))});var s=i(f,c,v,h),d=s[0],p=s[1],M=function(n){return p*n+d},y=[[l,M(l)],[g,M(g)]];return y.a=p,y.b=d,y.predict=M,y.rSquared=e(o,r,u,c,M),y};return o.domain=function(r){return arguments.length?(n=r,o):n},o.x=function(n){return arguments.length?(r=n,o):r},o.y=function(n){return arguments.length?(u=n,o):u},o}function v(n){n.sort(function(n,r){return n-r});var r=n.length/2;return r%1==0?(n[r-1]+n[r])/2:n[Math.floor(r)]}function h(){var n=function(n){return n[0]},t=function(n){return n[1]},e=.3,u=function(u){for(var o=r(u,function(r){return n(r)},function(n){return t(n)},!0),a=o[0],f=o[1],c=o[2],h=o[3],d=a.length,p=Math.max(2,~~(e*d)),M=new Float64Array(d),y=new Float64Array(d),b=new Float64Array(d).fill(1),x=-1;++x<=m;){for(var w=[0,p-1],q=0;qa[L]-F?A:L,E=0,j=0,k=0,O=0,_=0,B=1/Math.abs(a[P]-F||1),C=A;C<=L;++C){var G=a[C],I=f[C],Q=l(Math.abs(F-G)*B)*b[C],z=G*Q;E+=Q,j+=z,k+=I*Q,O+=I*z,_+=G*z}var D=i(j/E,k/E,O/E,_/E),H=D[0],J=D[1];M[q]=H+J*F,y[q]=Math.abs(f[q]-M[q]),g(a,q+1,w)}if(x===m)break;var K=v(y);if(Math.abs(K)=1?S:(Q=1-N*N)*Q}return s(a,M,c,h)};return u.bandwidth=function(n){return arguments.length?(e=n,u):e},u.x=function(r){return arguments.length?(n=r,u):n},u.y=function(n){return arguments.length?(t=n,u):t},u}function l(n){return(n=1-n*n*n)*n*n}function g(n,r,t){var e=n[r],u=t[0],o=t[1]+1;if(!(o>=n.length))for(;r>u&&n[o]-e<=e-n[u];)t[0]=++u,t[1]=o,++o}function s(n,r,t,e){for(var u,o=n.length,a=[],i=0,f=0,c=[];id&&(d=r))});var M=i(v,h,l,g),y=M[0],b=M[1],x=function(n){return b*Math.log(n)/p+y},w=a(s,d,x);return w.a=b,w.b=y,w.predict=x,w.rSquared=e(f,r,u,h,x),w};return f.domain=function(r){return arguments.length?(n=r,f):n},f.x=function(n){return arguments.length?(r=n,f):r},f.y=function(n){return arguments.length?(u=n,f):u},f.base=function(n){return arguments.length?(o=n,f):o},f}function p(){var n,u=function(n){return n[0]},o=function(n){return n[1]},i=function(i){var f,c,v,h,l=r(i,function(n){return u(n)},function(n){return o(n)}),g=l[0],s=l[1],d=l[2],p=l[3],M=g.length,y=0,b=0,x=0,w=0,m=0;for(f=0;fA&&(A=r))});var L=x-y*y,P=y*L-b*b,E=(m*y-w*b)/P,j=(w*L-m*b)/P,k=-E*y,O=function(n){var r=n-d;return E*r*r+j*r+k+p},_=a(F,A,O);return _.a=E,_.b=j-2*E*d,_.c=k-j*d+E*d*d+p,_.predict=O,_.rSquared=e(i,u,o,S,O),_};return i.domain=function(r){return arguments.length?(n=r,i):n},i.x=function(n){return arguments.length?(u=n,i):u},i.y=function(n){return arguments.length?(o=n,i):o},i}function M(){var n,u=function(n){return n[0]},o=function(n){return n[1]},i=3,f=function(f){if(1===i){var v=c().x(u).y(o).domain(n)(f),h=[v[0],v[1]];return h.coefficients=[v.b,v.a],h.predict=v.predict,h.rSquared=v.rSquared,h}if(2===i){var v=p().x(u).y(o).domain(n)(f),h=[v[0],v[1]];return h.coefficients=[v.c,v.b,v.a],h.predict=v.predict,h.rSquared=v.rSquared,h}var l=r(f,u,o),g=l[0],s=l[1],d=l[2],M=l[3],x=g.length,w=i+1,m=[],S=[],q=0,F=0,A=n?+n[0]:1/0,L=n?+n[1]:-1/0;t(f,u,o,function(r,t){F++,q+=(t-q)/F,n||(rL&&(L=r))});for(var P=0;P=0;--o){var a=r[o];u[o]+=a;for(var i=1,f=1;f<=o;++f)i*=(o+1-f)/f,u[o-f]+=a*Math.pow(t,f)*i}return u[0]+=e,u}function b(n){for(var r=n.length-1,t=new Array(r),e=0;eMath.abs(n[e][u])&&(u=o);for(var a=e;a=e;a--)n[a][o]-=n[a][e]*n[e][o]/n[e][e]}for(var o=r-1;o>=0;o--){for(var i=0,a=o+1;ad&&(d=r))});var p=i(c,v,h,l),M=p[0],y=p[1];M=Math.exp(M);var b=function(n){return M*Math.pow(n,y)},x=a(s,d,b);return x.a=M,x.b=y,x.predict=b,x.rSquared=e(o,r,u,g,b),x};return o.domain=function(r){return arguments.length?(n=r,o):n},o.x=function(n){return arguments.length?(r=n,o):r},o.y=function(n){return arguments.length?(u=n,o):u},o}function w(){function n(n){function c(n){return y+p/(1+Math.exp(-M*(n-b)))}var v=0,h=r?+r[0]:1/0,l=r?+r[1]:-1/0,g=1/0,s=-1/0,d=0;t(n,u,o,function(n,t){v++,d+=t,r||(nl&&(l=n)),ts&&(s=t)}),r||h!==1/0&&l!==-1/0||(h=0,l=1);for(var p=s-g,M=1,y=g,b=(h+l)/2,x=0;x { + (data: T[]): SigmoidalOutput; + domain(): Domain; + domain(domain: Domain): this; + x(): Accessor; + x(fn: Accessor): this; + y(): Accessor; + y(fn: Accessor): this; +} +export default function sigmoidal(): SigmoidalRegression; diff --git a/index.ts b/index.ts index 3159d4e..d90ba6e 100644 --- a/index.ts +++ b/index.ts @@ -4,4 +4,5 @@ export {default as regressionLoess} from "./src/loess"; export {default as regressionLog} from "./src/logarithmic"; export {default as regressionPoly} from "./src/polynomial"; export {default as regressionPow} from "./src/power"; -export {default as regressionQuad} from "./src/quadratic"; \ No newline at end of file +export {default as regressionQuad} from "./src/quadratic"; +export {default as regressionSigmoidal} from "./src/sigmoidal"; diff --git a/src/sigmoidal.ts b/src/sigmoidal.ts new file mode 100644 index 0000000..a38ec50 --- /dev/null +++ b/src/sigmoidal.ts @@ -0,0 +1,133 @@ +import { determination } from "./utils/determination"; +import { interpose } from "./utils/interpose"; +import { visitPoints } from "./utils/points"; +import { PredictFunction, Domain, DataPoint, Accessor } from "./types"; + +/** + * Sigmoidal (logistic) regression of the form: + * f(x) = C + A / (1 + exp(-B * (x - M))) + * where A, B, C, M are parameters found via gradient descent. + */ +export type SigmoidalOutput = [DataPoint, DataPoint] & { + A: number; + B: number; + C: number; + M: number; + predict: PredictFunction; + rSquared: number; +}; + +export interface SigmoidalRegression { + (data: T[]): SigmoidalOutput; + domain(): Domain; + domain(domain: Domain): this; + x(): Accessor; + x(fn: Accessor): this; + y(): Accessor; + y(fn: Accessor): this; +} + +export default function sigmoidal(): SigmoidalRegression { + let x: Accessor = (d: T) => (d as DataPoint)[0], + y: Accessor = (d: T) => (d as DataPoint)[1], + domain: Domain, + maxIter = 2000, + alpha = 1e-4; // learning rate + + function sigmoidalRegression(data: T[]): SigmoidalOutput { + let n = 0, + Xmin = domain ? +domain[0] : Infinity, + Xmax = domain ? +domain[1] : -Infinity, + Ymin = Infinity, + Ymax = -Infinity, + sumY = 0; + + // Gather data & track min/max for domain if not preset + visitPoints(data, x, y, (dx, dy) => { + n++; + sumY += dy; + if (!domain) { + if (dx < Xmin) Xmin = dx; + if (dx > Xmax) Xmax = dx; + } + if (dy < Ymin) Ymin = dy; + if (dy > Ymax) Ymax = dy; + }); + + if (!domain && (Xmin === Infinity || Xmax === -Infinity)) { + Xmin = 0; + Xmax = 1; + } + + // Initialize parameters + let A = Ymax - Ymin; // amplitude + let B = 1; // logistic slope + let C = Ymin; // baseline offset + let M = (Xmin + Xmax) / 2; // midpoint + + // Predict function + function f(xx: number) { + return C + A / (1 + Math.exp(-B * (xx - M))); + } + + // Gradient Descent + for (let iter = 0; iter < maxIter; iter++) { + let dA = 0, dB = 0, dC = 0, dM = 0; + visitPoints(data, x, y, (dx, dy) => { + const yhat = f(dx); + const err = dy - yhat; + const ex = Math.exp(-B * (dx - M)); + const g = 1 / (1 + ex); // logistic + // partial derivatives + const df_dA = g; + const df_dC = 1; + const df_dB = A * g * (1 - g) * (dx - M); + // Note the negative sign for M: + const df_dM = -A * B * g * (1 - g); + + const factor = -2 * err; + dA += factor * df_dA; + dB += factor * df_dB; + dC += factor * df_dC; + dM += factor * df_dM; + }); + A -= alpha * (dA / n); + B -= alpha * (dB / n); + C -= alpha * (dC / n); + M -= alpha * (dM / n); + } + + const predict = (xx: number) => C + A / (1 + Math.exp(-B * (xx - M))); + const out = interpose(Xmin, Xmax, predict) as SigmoidalOutput; + out.A = A; + out.B = B; + out.C = C; + out.M = M; + out.predict = predict; + + // R^2 + const meanY = sumY / n; + out.rSquared = determination(data, x, y, meanY, predict); + return out; + } + + sigmoidalRegression.domain = function(arr?: Domain): any { + if (!arguments.length) return domain; + domain = arr; + return sigmoidalRegression; + }; + + sigmoidalRegression.x = function(fn?: Accessor): any { + if (!arguments.length) return x; + x = fn!; + return sigmoidalRegression; + }; + + sigmoidalRegression.y = function(fn?: Accessor): any { + if (!arguments.length) return y; + y = fn!; + return sigmoidalRegression; + }; + + return sigmoidalRegression; +} \ No newline at end of file From 639611b703f61d27c67472fc9928bc1524ef33e8 Mon Sep 17 00:00:00 2001 From: gka Date: Sat, 20 Sep 2025 13:34:19 +0200 Subject: [PATCH 05/10] ts: change target to es2015 --- tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tsconfig.json b/tsconfig.json index 2ac344c..467dd28 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "ES5", + "target": "es2015", "module": "ESNext", "declaration": true, "declarationDir": "./dist/types", From 7d06b32a0c900127790ecb8e1e3f0e8f9cbb25fe Mon Sep 17 00:00:00 2001 From: gka Date: Sat, 20 Sep 2025 13:34:32 +0200 Subject: [PATCH 06/10] add @gka namespace chore: add pnpm lock file chore: build --- dist/d3-regression.cjs.js | 1459 +++++++------- dist/d3-regression.esm.js | 1459 +++++++------- dist/d3-regression.js | 1465 +++++++------- dist/d3-regression.min.js | 1 - dist/index.d.ts | 16 +- dist/src/exponential.d.ts | 34 +- dist/src/linear.d.ts | 34 +- dist/src/loess.d.ts | 22 +- dist/src/logarithmic.d.ts | 40 +- dist/src/polynomial.d.ts | 36 +- dist/src/power.d.ts | 36 +- dist/src/quadratic.d.ts | 38 +- dist/src/sigmoidal.d.ts | 48 +- dist/src/types.d.ts | 8 +- dist/src/utils/determination.d.ts | 12 +- dist/src/utils/geometry.d.ts | 18 +- dist/src/utils/interpose.d.ts | 12 +- dist/src/utils/median.d.ts | 8 +- dist/src/utils/ols.d.ts | 12 +- dist/src/utils/points.d.ts | 22 +- package.json | 4 +- pnpm-lock.yaml | 3028 +++++++++++++++++++++++++++++ src/polynomial.ts | 22 +- 23 files changed, 5426 insertions(+), 2408 deletions(-) delete mode 100644 dist/d3-regression.min.js create mode 100644 pnpm-lock.yaml diff --git a/dist/d3-regression.cjs.js b/dist/d3-regression.cjs.js index ea9f596..b78907d 100644 --- a/dist/d3-regression.cjs.js +++ b/dist/d3-regression.cjs.js @@ -1,764 +1,761 @@ -// https://github.com/HarryStevens/d3-regression#readme Version 1.3.10. Copyright 2025 Harry Stevens. +// https://github.com/HarryStevens/d3-regression#readme Version 1.3.10-pr48. Copyright 2025 Harry Stevens. 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); -/** - * Adapted from vega-statistics by Jeffrey Heer - * License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE - * Source: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/packages/vega-statistics/src/regression/points.js - */ -function points(data, x, y, sort) { - data = data.filter(function (d, i) { - var u = x(d, i), v = y(d, i); - return u != null && isFinite(u) && v != null && isFinite(v); - }); - if (sort) { - data.sort(function (a, b) { return x(a) - x(b); }); - } - var n = data.length, X = new Float64Array(n), Y = new Float64Array(n); - // extract values, calculate means - var ux = 0, uy = 0, xv, yv, d; - for (var i = 0; i < n;) { - d = data[i]; - X[i] = xv = +x(d, i, data); - Y[i] = yv = +y(d, i, data); - ++i; - ux += (xv - ux) / i; - uy += (yv - uy) / i; - } - // mean center the data - for (var i = 0; i < n; ++i) { - X[i] -= ux; - Y[i] -= uy; - } - return [X, Y, ux, uy]; -} -/** - * Iterates over valid data points, invoking a callback for each. - */ -function visitPoints(data, x, y, cb) { - var iterations = 0; - for (var i = 0; i < data.length; i++) { - var d = data[i]; - var dx = +x(d, i, data); - var dy = +y(d, i, data); - if (dx != null && isFinite(dx) && dy != null && isFinite(dy)) { - cb(dx, dy, iterations++); - } - } +/** + * Adapted from vega-statistics by Jeffrey Heer + * License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE + * Source: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/packages/vega-statistics/src/regression/points.js + */ +function points(data, x, y, sort) { + data = data.filter((d, i) => { + let u = x(d, i), v = y(d, i); + return u != null && isFinite(u) && v != null && isFinite(v); + }); + if (sort) { + data.sort((a, b) => x(a) - x(b)); + } + const n = data.length, X = new Float64Array(n), Y = new Float64Array(n); + // extract values, calculate means + let ux = 0, uy = 0, xv, yv, d; + for (let i = 0; i < n;) { + d = data[i]; + X[i] = xv = +x(d, i, data); + Y[i] = yv = +y(d, i, data); + ++i; + ux += (xv - ux) / i; + uy += (yv - uy) / i; + } + // mean center the data + for (let i = 0; i < n; ++i) { + X[i] -= ux; + Y[i] -= uy; + } + return [X, Y, ux, uy]; +} +/** + * Iterates over valid data points, invoking a callback for each. + */ +function visitPoints(data, x, y, cb) { + let iterations = 0; + for (let i = 0; i < data.length; i++) { + const d = data[i]; + const dx = +x(d, i, data); + const dy = +y(d, i, data); + if (dx != null && isFinite(dx) && dy != null && isFinite(dy)) { + cb(dx, dy, iterations++); + } + } } -/** - * Given a dataset, x- and y-accessors, the mean center of the y-values (uY), - * and a prediction function, return the coefficient of determination, R^2. - */ -function determination(data, x, y, uY, predict) { - var SSE = 0, // Sum of Squared Errors - SST = 0; // Total Sum of Squares - visitPoints(data, x, y, function (dx, dy) { - var sse = dy - predict(dx); - var sst = dy - uY; - SSE += sse * sse; - SST += sst * sst; - }); - return 1 - SSE / SST; +/** + * Given a dataset, x- and y-accessors, the mean center of the y-values (uY), + * and a prediction function, return the coefficient of determination, R^2. + */ +function determination(data, x, y, uY, predict) { + let SSE = 0, // Sum of Squared Errors + SST = 0; // Total Sum of Squares + visitPoints(data, x, y, (dx, dy) => { + const sse = dy - predict(dx); + const sst = dy - uY; + SSE += sse * sse; + SST += sst * sst; + }); + return 1 - SSE / SST; } -/** - * Returns the angle of a line in degrees. - */ -function angle(line) { - return (Math.atan2(line[1][1] - line[0][1], line[1][0] - line[0][0]) * - (180 / Math.PI)); -} -/** - * Returns the midpoint of a line. - */ -function midpoint(line) { - return [ - (line[0][0] + line[1][0]) / 2, - (line[0][1] + line[1][1]) / 2 - ]; +/** + * Returns the angle of a line in degrees. + */ +function angle(line) { + return (Math.atan2(line[1][1] - line[0][1], line[1][0] - line[0][0]) * + (180 / Math.PI)); +} +/** + * Returns the midpoint of a line. + */ +function midpoint(line) { + return [ + (line[0][0] + line[1][0]) / 2, + (line[0][1] + line[1][1]) / 2 + ]; } -/** - * Given a start point (xmin), an end point (xmax), - * and a prediction function, returns a smooth line. - */ -function interpose(xmin, xmax, predict) { - var l = (Math.log(xmax - xmin) * Math.LOG10E + 1) | 0; - var precision = Math.pow(10, -l / 2 - 1); - var maxIter = 1e4; - var points = [px(xmin), px(xmax)]; - var iter = 0; - while (find(points) && iter < maxIter) - ; - return points; - function px(x) { - return [x, predict(x)]; - } - function find(points) { - iter++; - var n = points.length; - var found = false; - for (var i = 0; i < n - 1; i++) { - var p0 = points[i]; - var p1 = points[i + 1]; - var m = midpoint([p0, p1]); - var mp = px(m[0]); - var a0 = angle([p0, m]); - var a1 = angle([p0, mp]); - var a = Math.abs(a0 - a1); - if (a > precision) { - points.splice(i + 1, 0, mp); - found = true; - } - } - return found; - } +/** + * Given a start point (xmin), an end point (xmax), + * and a prediction function, returns a smooth line. + */ +function interpose(xmin, xmax, predict) { + const l = (Math.log(xmax - xmin) * Math.LOG10E + 1) | 0; + const precision = Math.pow(10, -l / 2 - 1); + const maxIter = 1e4; + let points = [px(xmin), px(xmax)]; + let iter = 0; + while (find(points) && iter < maxIter) + ; + return points; + function px(x) { + return [x, predict(x)]; + } + function find(points) { + iter++; + const n = points.length; + let found = false; + for (let i = 0; i < n - 1; i++) { + const p0 = points[i]; + const p1 = points[i + 1]; + const m = midpoint([p0, p1]); + const mp = px(m[0]); + const a0 = angle([p0, m]); + const a1 = angle([p0, mp]); + const a = Math.abs(a0 - a1); + if (a > precision) { + points.splice(i + 1, 0, mp); + found = true; + } + } + return found; + } } -/** - * Ordinary Least Squares from vega-statistics by Jeffrey Heer - * License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE - * Source: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/packages/vega-statistics/src/regression/ols.js - */ -function ols(uX, uY, uXY, uX2) { - var delta = uX2 - uX * uX, slope = Math.abs(delta) < 1e-24 ? 0 : (uXY - uX * uY) / delta, intercept = uY - slope * uX; - return [intercept, slope]; +/** + * Ordinary Least Squares from vega-statistics by Jeffrey Heer + * License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE + * Source: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/packages/vega-statistics/src/regression/ols.js + */ +function ols(uX, uY, uXY, uX2) { + const delta = uX2 - uX * uX, slope = Math.abs(delta) < 1e-24 ? 0 : (uXY - uX * uY) / delta, intercept = uY - slope * uX; + return [intercept, slope]; } -function exponential() { - var y = function (d) { return d[1]; }, x = function (d) { return d[0]; }, domain; - var exponentialRegression = function (data) { - var n = 0, Y = 0, YL = 0, XY = 0, XYL = 0, X2Y = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; - visitPoints(data, x, y, function (dx, dy) { - var ly = Math.log(dy), xy = dx * dy; - ++n; - Y += (dy - Y) / n; - XY += (xy - XY) / n; - X2Y += (dx * xy - X2Y) / n; - YL += (dy * ly - YL) / n; - XYL += (xy * ly - XYL) / n; - if (!domain) { - if (dx < xmin) - xmin = dx; - if (dx > xmax) - xmax = dx; - } - }); - var _a = ols(XY / Y, YL / Y, XYL / Y, X2Y / Y), a = _a[0], b = _a[1]; - a = Math.exp(a); - var fn = function (xx) { return a * Math.exp(b * xx); }; - var out = interpose(xmin, xmax, fn); - out.a = a; - out.b = b; - out.predict = fn; - out.rSquared = determination(data, x, y, Y, fn); - return out; - }; - exponentialRegression.domain = function (arr) { - if (!arguments.length) - return domain; - domain = arr; - return exponentialRegression; - }; - exponentialRegression.x = function (fn) { - if (!arguments.length) - return x; - x = fn; - return exponentialRegression; - }; - exponentialRegression.y = function (fn) { - if (!arguments.length) - return y; - y = fn; - return exponentialRegression; - }; - return exponentialRegression; +function exponential() { + let y = (d) => d[1], x = (d) => d[0], domain; + const exponentialRegression = function (data) { + let n = 0, Y = 0, YL = 0, XY = 0, XYL = 0, X2Y = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; + visitPoints(data, x, y, (dx, dy) => { + const ly = Math.log(dy), xy = dx * dy; + ++n; + Y += (dy - Y) / n; + XY += (xy - XY) / n; + X2Y += (dx * xy - X2Y) / n; + YL += (dy * ly - YL) / n; + XYL += (xy * ly - XYL) / n; + if (!domain) { + if (dx < xmin) + xmin = dx; + if (dx > xmax) + xmax = dx; + } + }); + let [a, b] = ols(XY / Y, YL / Y, XYL / Y, X2Y / Y); + a = Math.exp(a); + const fn = (xx) => a * Math.exp(b * xx); + const out = interpose(xmin, xmax, fn); + out.a = a; + out.b = b; + out.predict = fn; + out.rSquared = determination(data, x, y, Y, fn); + return out; + }; + exponentialRegression.domain = function (arr) { + if (!arguments.length) + return domain; + domain = arr; + return exponentialRegression; + }; + exponentialRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return exponentialRegression; + }; + exponentialRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return exponentialRegression; + }; + return exponentialRegression; } -function linear() { - var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, domain; - var linearRegression = function (data) { - var n = 0, X = 0, // sum of x - Y = 0, // sum of y - XY = 0, // sum of x*y - X2 = 0, // sum of x*x - xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; - visitPoints(data, x, y, function (dx, dy) { - ++n; - X += (dx - X) / n; - Y += (dy - Y) / n; - XY += (dx * dy - XY) / n; - X2 += (dx * dx - X2) / n; - if (!domain) { - if (dx < xmin) - xmin = dx; - if (dx > xmax) - xmax = dx; - } - }); - var _a = ols(X, Y, XY, X2), intercept = _a[0], slope = _a[1]; - var fn = function (xx) { return slope * xx + intercept; }; - var out = [[xmin, fn(xmin)], [xmax, fn(xmax)]]; - out.a = slope; - out.b = intercept; - out.predict = fn; - out.rSquared = determination(data, x, y, Y, fn); - return out; - }; - linearRegression.domain = function (arr) { - if (!arguments.length) - return domain; - domain = arr; - return linearRegression; - }; - linearRegression.x = function (fn) { - if (!arguments.length) - return x; - x = fn; - return linearRegression; - }; - linearRegression.y = function (fn) { - if (!arguments.length) - return y; - y = fn; - return linearRegression; - }; - return linearRegression; +function linear() { + let x = (d) => d[0], y = (d) => d[1], domain; + const linearRegression = function (data) { + let n = 0, X = 0, // sum of x + Y = 0, // sum of y + XY = 0, // sum of x*y + X2 = 0, // sum of x*x + xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; + visitPoints(data, x, y, (dx, dy) => { + ++n; + X += (dx - X) / n; + Y += (dy - Y) / n; + XY += (dx * dy - XY) / n; + X2 += (dx * dx - X2) / n; + if (!domain) { + if (dx < xmin) + xmin = dx; + if (dx > xmax) + xmax = dx; + } + }); + const [intercept, slope] = ols(X, Y, XY, X2); + const fn = (xx) => slope * xx + intercept; + const out = [[xmin, fn(xmin)], [xmax, fn(xmax)]]; + out.a = slope; + out.b = intercept; + out.predict = fn; + out.rSquared = determination(data, x, y, Y, fn); + return out; + }; + linearRegression.domain = function (arr) { + if (!arguments.length) + return domain; + domain = arr; + return linearRegression; + }; + linearRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return linearRegression; + }; + linearRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return linearRegression; + }; + return linearRegression; } -/** - * Returns the median value of an array of numbers. - */ -function median(arr) { - arr.sort(function (a, b) { return a - b; }); - var i = arr.length / 2; - return i % 1 === 0 ? (arr[i - 1] + arr[i]) / 2 : arr[Math.floor(i)]; +/** + * Returns the median value of an array of numbers. + */ +function median(arr) { + arr.sort((a, b) => a - b); + var i = arr.length / 2; + return i % 1 === 0 ? (arr[i - 1] + arr[i]) / 2 : arr[Math.floor(i)]; } -// Adapted from science.js by Jason Davies -var maxiters = 2, epsilon = 1e-12; -function loess() { - var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, bandwidth = 0.3; - var loessRegression = function loessRegression(data) { - var _a = points(data, function (dd) { return x(dd); }, function (dd) { return y(dd); }, true), xv = _a[0], yv = _a[1], ux = _a[2], uy = _a[3]; - var n = xv.length; - var bw = Math.max(2, ~~(bandwidth * n)); // # of nearest neighbors - var yhat = new Float64Array(n); - var residuals = new Float64Array(n); - var robustWeights = new Float64Array(n).fill(1); - for (var iter = -1; ++iter <= maxiters;) { - var interval = [0, bw - 1]; - for (var i = 0; i < n; ++i) { - var dx = xv[i]; - var i0 = interval[0]; - var i1 = interval[1]; - var edge = (dx - xv[i0]) > (xv[i1] - dx) ? i0 : i1; - var W = 0, X = 0, Y = 0, XY = 0, X2 = 0; - var denom = 1 / Math.abs(xv[edge] - dx || 1); - for (var k = i0; k <= i1; ++k) { - var xk = xv[k]; - var yk = yv[k]; - var w = tricube(Math.abs(dx - xk) * denom) * robustWeights[k]; - var xkw = xk * w; - W += w; - X += xkw; - Y += yk * w; - XY += yk * xkw; - X2 += xk * xkw; - } - // Linear regression fit - var _b = ols(X / W, Y / W, XY / W, X2 / W), a = _b[0], b = _b[1]; - yhat[i] = a + b * dx; - residuals[i] = Math.abs(yv[i] - yhat[i]); - updateInterval(xv, i + 1, interval); - } - if (iter === maxiters) { - break; - } - var medianResidual = median(residuals); - if (Math.abs(medianResidual) < epsilon) - break; - for (var i = 0, arg = void 0, w = void 0; i < n; ++i) { - arg = residuals[i] / (6 * medianResidual); - // Default to epsilon (rather than zero) for large deviations - // Keeping weights tiny but non-zero prevents singularites - robustWeights[i] = (arg >= 1) ? epsilon : ((w = 1 - arg * arg) * w); - } - } - return output(xv, yhat, ux, uy); - }; - loessRegression.bandwidth = function (bw) { - if (!arguments.length) - return bandwidth; - bandwidth = bw; - return loessRegression; - }; - loessRegression.x = function (fn) { - if (!arguments.length) - return x; - x = fn; - return loessRegression; - }; - loessRegression.y = function (fn) { - if (!arguments.length) - return y; - y = fn; - return loessRegression; - }; - return loessRegression; -} -// Weighting kernel for local regression -function tricube(x) { - return (x = 1 - x * x * x) * x * x; -} -// Advance sliding window interval of nearest neighbors -function updateInterval(xv, i, interval) { - var val = xv[i], left = interval[0], right = interval[1] + 1; - if (right >= xv.length) - return; - // Step right if distance to new right edge is <= distance to old left edge - // Step when distance is equal to ensure movement over duplicate x values - while (i > left && (xv[right] - val) <= (val - xv[left])) { - interval[0] = ++left; - interval[1] = right; - ++right; - } -} -// Generate smoothed output points -// Average points with repeated x values -function output(xv, yhat, ux, uy) { - var n = xv.length, out = []; - var i = 0, cnt = 0, prev = [], v; - for (; i < n; ++i) { - v = xv[i] + ux; - if (prev[0] === v) { - // Average output values via online update - prev[1] += (yhat[i] - prev[1]) / (++cnt); - } - else { - // Add new output point - cnt = 0; - prev[1] += uy; - prev = [v, yhat[i]]; - out.push(prev); - } - } - prev[1] += uy; - return out; +// Adapted from science.js by Jason Davies +const maxiters = 2, epsilon = 1e-12; +function loess() { + let x = (d) => d[0], y = (d) => d[1], bandwidth = 0.3; + const loessRegression = function loessRegression(data) { + const [xv, yv, ux, uy] = points(data, (dd) => x(dd), (dd) => y(dd), true); + const n = xv.length; + const bw = Math.max(2, ~~(bandwidth * n)); // # of nearest neighbors + const yhat = new Float64Array(n); + const residuals = new Float64Array(n); + const robustWeights = new Float64Array(n).fill(1); + for (let iter = -1; ++iter <= maxiters;) { + const interval = [0, bw - 1]; + for (let i = 0; i < n; ++i) { + const dx = xv[i]; + const i0 = interval[0]; + const i1 = interval[1]; + const edge = (dx - xv[i0]) > (xv[i1] - dx) ? i0 : i1; + let W = 0, X = 0, Y = 0, XY = 0, X2 = 0; + const denom = 1 / Math.abs(xv[edge] - dx || 1); + for (let k = i0; k <= i1; ++k) { + const xk = xv[k]; + const yk = yv[k]; + const w = tricube(Math.abs(dx - xk) * denom) * robustWeights[k]; + const xkw = xk * w; + W += w; + X += xkw; + Y += yk * w; + XY += yk * xkw; + X2 += xk * xkw; + } + // Linear regression fit + const [a, b] = ols(X / W, Y / W, XY / W, X2 / W); + yhat[i] = a + b * dx; + residuals[i] = Math.abs(yv[i] - yhat[i]); + updateInterval(xv, i + 1, interval); + } + if (iter === maxiters) { + break; + } + const medianResidual = median(residuals); + if (Math.abs(medianResidual) < epsilon) + break; + for (let i = 0, arg, w; i < n; ++i) { + arg = residuals[i] / (6 * medianResidual); + // Default to epsilon (rather than zero) for large deviations + // Keeping weights tiny but non-zero prevents singularites + robustWeights[i] = (arg >= 1) ? epsilon : ((w = 1 - arg * arg) * w); + } + } + return output(xv, yhat, ux, uy); + }; + loessRegression.bandwidth = function (bw) { + if (!arguments.length) + return bandwidth; + bandwidth = bw; + return loessRegression; + }; + loessRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return loessRegression; + }; + loessRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return loessRegression; + }; + return loessRegression; +} +// Weighting kernel for local regression +function tricube(x) { + return (x = 1 - x * x * x) * x * x; +} +// Advance sliding window interval of nearest neighbors +function updateInterval(xv, i, interval) { + let val = xv[i], left = interval[0], right = interval[1] + 1; + if (right >= xv.length) + return; + // Step right if distance to new right edge is <= distance to old left edge + // Step when distance is equal to ensure movement over duplicate x values + while (i > left && (xv[right] - val) <= (val - xv[left])) { + interval[0] = ++left; + interval[1] = right; + ++right; + } +} +// Generate smoothed output points +// Average points with repeated x values +function output(xv, yhat, ux, uy) { + const n = xv.length, out = []; + let i = 0, cnt = 0, prev = [], v; + for (; i < n; ++i) { + v = xv[i] + ux; + if (prev[0] === v) { + // Average output values via online update + prev[1] += (yhat[i] - prev[1]) / (++cnt); + } + else { + // Add new output point + cnt = 0; + prev[1] += uy; + prev = [v, yhat[i]]; + out.push(prev); + } + } + prev[1] += uy; + return out; } -function logarithmic() { - var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, base = Math.E, domain; - var logarithmicRegression = function (data) { - var n = 0, X = 0, Y = 0, XY = 0, X2 = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity, lb = Math.log(base); - visitPoints(data, x, y, function (dx, dy) { - var lx = Math.log(dx) / lb; - ++n; - X += (lx - X) / n; - Y += (dy - Y) / n; - XY += (lx * dy - XY) / n; - X2 += (lx * lx - X2) / n; - if (!domain) { - if (dx < xmin) - xmin = dx; - if (dx > xmax) - xmax = dx; - } - }); - var _a = ols(X, Y, XY, X2), intercept = _a[0], slope = _a[1]; - var fn = function (xx) { return slope * Math.log(xx) / lb + intercept; }; - var out = interpose(xmin, xmax, fn); - out.a = slope; - out.b = intercept; - out.predict = fn; - out.rSquared = determination(data, x, y, Y, fn); - return out; - }; - logarithmicRegression.domain = function (arr) { - if (!arguments.length) - return domain; - domain = arr; - return logarithmicRegression; - }; - logarithmicRegression.x = function (fn) { - if (!arguments.length) - return x; - x = fn; - return logarithmicRegression; - }; - logarithmicRegression.y = function (fn) { - if (!arguments.length) - return y; - y = fn; - return logarithmicRegression; - }; - logarithmicRegression.base = function (b) { - if (!arguments.length) - return base; - base = b; - return logarithmicRegression; - }; - return logarithmicRegression; +function logarithmic() { + let x = (d) => d[0], y = (d) => d[1], base = Math.E, domain; + const logarithmicRegression = function (data) { + let n = 0, X = 0, Y = 0, XY = 0, X2 = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity, lb = Math.log(base); + visitPoints(data, x, y, (dx, dy) => { + const lx = Math.log(dx) / lb; + ++n; + X += (lx - X) / n; + Y += (dy - Y) / n; + XY += (lx * dy - XY) / n; + X2 += (lx * lx - X2) / n; + if (!domain) { + if (dx < xmin) + xmin = dx; + if (dx > xmax) + xmax = dx; + } + }); + const [intercept, slope] = ols(X, Y, XY, X2); + const fn = (xx) => slope * Math.log(xx) / lb + intercept; + const out = interpose(xmin, xmax, fn); + out.a = slope; + out.b = intercept; + out.predict = fn; + out.rSquared = determination(data, x, y, Y, fn); + return out; + }; + logarithmicRegression.domain = function (arr) { + if (!arguments.length) + return domain; + domain = arr; + return logarithmicRegression; + }; + logarithmicRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return logarithmicRegression; + }; + logarithmicRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return logarithmicRegression; + }; + logarithmicRegression.base = function (b) { + if (!arguments.length) + return base; + base = b; + return logarithmicRegression; + }; + return logarithmicRegression; } -function quadratic() { - var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, domain; - var quadraticRegression = function quadraticRegression(data) { - var _a = points(data, function (dd) { return x(dd); }, function (dd) { return y(dd); }), xv = _a[0], yv = _a[1], ux = _a[2], uy = _a[3]; - var n = xv.length; - var X2 = 0, X3 = 0, X4 = 0, XY = 0, X2Y = 0, i, dx, dy, x2; - for (i = 0; i < n;) { - dx = xv[i]; - dy = yv[i++]; - x2 = dx * dx; - X2 += (x2 - X2) / i; - X3 += ((x2 * dx) - X3) / i; - X4 += ((x2 * x2) - X4) / i; - XY += ((dx * dy) - XY) / i; - X2Y += ((x2 * dy) - X2Y) / i; - } - var Y = 0, n0 = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; - visitPoints(data, x, y, function (dx2, dy2) { - n0++; - Y += (dy2 - Y) / n0; - if (!domain) { - if (dx2 < xmin) - xmin = dx2; - if (dx2 > xmax) - xmax = dx2; - } - }); - var X2X2 = X4 - (X2 * X2); - var d = (X2 * X2X2 - X3 * X3); - var a = (X2Y * X2 - XY * X3) / d; - var b = (XY * X2X2 - X2Y * X3) / d; - var c = -a * X2; - var fn = function (xx) { - var shifted = xx - ux; - return a * shifted * shifted + b * shifted + c + uy; - }; - var out = interpose(xmin, xmax, fn); - out.a = a; - out.b = b - 2 * a * ux; - out.c = c - b * ux + a * ux * ux + uy; - out.predict = fn; - out.rSquared = determination(data, x, y, Y, fn); - return out; - }; - quadraticRegression.domain = function (arr) { - if (!arguments.length) - return domain; - domain = arr; - return quadraticRegression; - }; - quadraticRegression.x = function (fn) { - if (!arguments.length) - return x; - x = fn; - return quadraticRegression; - }; - quadraticRegression.y = function (fn) { - if (!arguments.length) - return y; - y = fn; - return quadraticRegression; - }; - return quadraticRegression; +function quadratic() { + let x = (d) => d[0], y = (d) => d[1], domain; + const quadraticRegression = function quadraticRegression(data) { + const [xv, yv, ux, uy] = points(data, (dd) => x(dd), (dd) => y(dd)); + const n = xv.length; + let X2 = 0, X3 = 0, X4 = 0, XY = 0, X2Y = 0, i, dx, dy, x2; + for (i = 0; i < n;) { + dx = xv[i]; + dy = yv[i++]; + x2 = dx * dx; + X2 += (x2 - X2) / i; + X3 += ((x2 * dx) - X3) / i; + X4 += ((x2 * x2) - X4) / i; + XY += ((dx * dy) - XY) / i; + X2Y += ((x2 * dy) - X2Y) / i; + } + let Y = 0, n0 = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; + visitPoints(data, x, y, (dx2, dy2) => { + n0++; + Y += (dy2 - Y) / n0; + if (!domain) { + if (dx2 < xmin) + xmin = dx2; + if (dx2 > xmax) + xmax = dx2; + } + }); + const X2X2 = X4 - (X2 * X2); + const d = (X2 * X2X2 - X3 * X3); + const a = (X2Y * X2 - XY * X3) / d; + const b = (XY * X2X2 - X2Y * X3) / d; + const c = -a * X2; + const fn = (xx) => { + const shifted = xx - ux; + return a * shifted * shifted + b * shifted + c + uy; + }; + const out = interpose(xmin, xmax, fn); + out.a = a; + out.b = b - 2 * a * ux; + out.c = c - b * ux + a * ux * ux + uy; + out.predict = fn; + out.rSquared = determination(data, x, y, Y, fn); + return out; + }; + quadraticRegression.domain = function (arr) { + if (!arguments.length) + return domain; + domain = arr; + return quadraticRegression; + }; + quadraticRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return quadraticRegression; + }; + quadraticRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return quadraticRegression; + }; + return quadraticRegression; } -// Adapted from regression-js by Tom Alexander -function polynomial() { - var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, order = 3, domain; - var polynomialRegression = function polynomialRegression(data) { - // Shortcut for lower-order polynomials: - if (order === 1) { - var o = linear().x(x).y(y).domain(domain)(data); - var result = [o[0], o[1]]; - result.coefficients = [o.b, o.a]; - result.predict = o.predict; - result.rSquared = o.rSquared; - return result; - } - if (order === 2) { - var o = quadratic().x(x).y(y).domain(domain)(data); - var result = [o[0], o[1]]; - result.coefficients = [o.c, o.b, o.a]; - result.predict = o.predict; - result.rSquared = o.rSquared; - return result; - } - var _a = points(data, x, y), xv = _a[0], yv = _a[1], ux = _a[2], uy = _a[3]; - var n = xv.length; - var k = order + 1; - var lhs = []; - var rhs = []; - var Y = 0, n0 = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; - visitPoints(data, x, y, function (dx, dy) { - n0++; - Y += (dy - Y) / n0; - if (!domain) { - if (dx < xmin) - xmin = dx; - if (dx > xmax) - xmax = dx; - } - }); - // Build normal equations - for (var i = 0; i < k; i++) { - // LHS - var v = 0; - for (var l = 0; l < n; l++) { - v += Math.pow(xv[l], i) * yv[l]; - } - lhs.push(v); - // RHS - var c = new Float64Array(k); - for (var j = 0; j < k; j++) { - var v2 = 0; - for (var l = 0; l < n; l++) { - v2 += Math.pow(xv[l], i + j); - } - c[j] = v2; - } - rhs.push(c); - } - rhs.push(new Float64Array(lhs)); - var coef = gaussianElimination(rhs); - var fn = function (xx) { - var shifted = xx - ux; - var val = uy + coef[0]; - for (var i = 1; i < k; i++) { - val += coef[i] * Math.pow(shifted, i); - } - return val; - }; - var out = interpose(xmin, xmax, fn); - out.coefficients = uncenter(k, coef, -ux, uy); - out.predict = fn; - out.rSquared = determination(data, x, y, Y, fn); - return out; - }; - polynomialRegression.domain = function (arr) { - if (!arguments.length) - return domain; - domain = arr; - return polynomialRegression; - }; - polynomialRegression.x = function (fn) { - if (!arguments.length) - return x; - x = fn; - return polynomialRegression; - }; - polynomialRegression.y = function (fn) { - if (!arguments.length) - return y; - y = fn; - return polynomialRegression; - }; - polynomialRegression.order = function (n) { - if (!arguments.length) - return order; - order = n; - return polynomialRegression; - }; - return polynomialRegression; -} -function uncenter(k, a, x, y) { - var z = new Array(k).fill(0); - for (var i = k - 1; i >= 0; --i) { - var v = a[i]; - z[i] += v; - var c = 1; - for (var j = 1; j <= i; ++j) { - c *= (i + 1 - j) / j; // binomial coefficient - z[i - j] += v * Math.pow(x, j) * c; - } - } - // bias term - z[0] += y; - return z; -} -// Solve A * x = b using Gaussian elimination -function gaussianElimination(matrix) { - var n = matrix.length - 1; - var coef = new Array(n); - for (var i = 0; i < n; i++) { - var r = i; - // find pivot row - for (var j = i + 1; j < n; j++) { - if (Math.abs(matrix[i][j]) > Math.abs(matrix[i][r])) { - r = j; - } - } - // swap columns - for (var k = i; k < n + 1; k++) { - var t = matrix[k][i]; - matrix[k][i] = matrix[k][r]; - matrix[k][r] = t; - } - // reduce - for (var j = i + 1; j < n; j++) { - for (var k = n; k >= i; k--) { - matrix[k][j] -= (matrix[k][i] * matrix[i][j]) / matrix[i][i]; - } - } - } - for (var j = n - 1; j >= 0; j--) { - var t = 0; - for (var k = j + 1; k < n; k++) { - t += matrix[k][j] * coef[k]; - } - coef[j] = (matrix[n][j] - t) / matrix[j][j]; - } - return coef; +// Adapted from regression-js by Tom Alexander +function polynomial() { + let x = (d) => d[0], y = (d) => d[1], order = 3, domain; + const polynomialRegression = function polynomialRegression(data) { + // Shortcut for lower-order polynomials: + if (order === 1) { + const o = linear().x(x).y(y).domain(domain)(data); + const result = [o[0], o[1]]; + result.coefficients = [o.b, o.a]; + result.predict = o.predict; + result.rSquared = o.rSquared; + return result; + } + if (order === 2) { + const o = quadratic().x(x).y(y).domain(domain)(data); + const result = [o[0], o[1]]; + result.coefficients = [o.c, o.b, o.a]; + result.predict = o.predict; + result.rSquared = o.rSquared; + return result; + } + const [xv, yv, ux, uy] = points(data, x, y); + const n = xv.length; + const k = order + 1; + const lhs = []; + const rhs = []; + let Y = 0, n0 = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; + visitPoints(data, x, y, (dx, dy) => { + n0++; + Y += (dy - Y) / n0; + if (!domain) { + if (dx < xmin) + xmin = dx; + if (dx > xmax) + xmax = dx; + } + }); + // Build normal equations + for (let i = 0; i < k; i++) { + // LHS + let v = 0; + for (let l = 0; l < n; l++) { + v += Math.pow(xv[l], i) * yv[l]; + } + lhs.push(v); + // RHS + const c = new Float64Array(k); + for (let j = 0; j < k; j++) { + let v2 = 0; + for (let l = 0; l < n; l++) { + v2 += Math.pow(xv[l], i + j); + } + c[j] = v2; + } + rhs.push(c); + } + rhs.push(new Float64Array(lhs)); + const coef = gaussianElimination(rhs); + const fn = (xx) => { + let shifted = xx - ux; + let val = uy + coef[0]; + for (let i = 1; i < k; i++) { + val += coef[i] * Math.pow(shifted, i); + } + return val; + }; + const out = interpose(xmin, xmax, fn); + out.coefficients = uncenter(k, coef, -ux, uy); + out.predict = fn; + out.rSquared = determination(data, x, y, Y, fn); + return out; + }; + polynomialRegression.domain = function (arr) { + if (!arguments.length) + return domain; + domain = arr; + return polynomialRegression; + }; + polynomialRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return polynomialRegression; + }; + polynomialRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return polynomialRegression; + }; + polynomialRegression.order = function (n) { + if (!arguments.length) + return order; + order = n; + return polynomialRegression; + }; + return polynomialRegression; +} +function uncenter(k, a, x, y) { + const z = new Array(k).fill(0); + for (let i = k - 1; i >= 0; --i) { + let v = a[i]; + z[i] += v; + let c = 1; + for (let j = 1; j <= i; ++j) { + c *= (i + 1 - j) / j; // binomial coefficient + z[i - j] += v * Math.pow(x, j) * c; + } + } + // bias term + z[0] += y; + return z; +} +// Solve A * x = b using Gaussian elimination +function gaussianElimination(matrix) { + const n = matrix.length - 1; + const coef = new Array(n); + for (let i = 0; i < n; i++) { + let r = i; + // find pivot row + for (let j = i + 1; j < n; j++) { + if (Math.abs(matrix[i][j]) > Math.abs(matrix[i][r])) { + r = j; + } + } + // swap columns + for (let k = i; k < n + 1; k++) { + const t = matrix[k][i]; + matrix[k][i] = matrix[k][r]; + matrix[k][r] = t; + } + // reduce + for (let j = i + 1; j < n; j++) { + for (let k = n; k >= i; k--) { + matrix[k][j] -= (matrix[k][i] * matrix[i][j]) / matrix[i][i]; + } + } + } + for (let j = n - 1; j >= 0; j--) { + let t = 0; + for (let k = j + 1; k < n; k++) { + t += matrix[k][j] * coef[k]; + } + coef[j] = (matrix[n][j] - t) / matrix[j][j]; + } + return coef; } -function power() { - var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, domain; - var powerRegression = function powerRegression(data) { - var n = 0, X = 0, Y = 0, XY = 0, X2 = 0, YS = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; - visitPoints(data, x, y, function (dx, dy) { - var lx = Math.log(dx), ly = Math.log(dy); - ++n; - X += (lx - X) / n; - Y += (ly - Y) / n; - XY += (lx * ly - XY) / n; - X2 += (lx * lx - X2) / n; - YS += (dy - YS) / n; - if (!domain) { - if (dx < xmin) - xmin = dx; - if (dx > xmax) - xmax = dx; - } - }); - var _a = ols(X, Y, XY, X2), a = _a[0], b = _a[1]; - a = Math.exp(a); - var fn = function (xx) { return a * Math.pow(xx, b); }; - var out = interpose(xmin, xmax, fn); - out.a = a; - out.b = b; - out.predict = fn; - out.rSquared = determination(data, x, y, YS, fn); - return out; - }; - powerRegression.domain = function (arr) { - if (!arguments.length) - return domain; - domain = arr; - return powerRegression; - }; - powerRegression.x = function (fn) { - if (!arguments.length) - return x; - x = fn; - return powerRegression; - }; - powerRegression.y = function (fn) { - if (!arguments.length) - return y; - y = fn; - return powerRegression; - }; - return powerRegression; +function power() { + let x = (d) => d[0], y = (d) => d[1], domain; + const powerRegression = function powerRegression(data) { + let n = 0, X = 0, Y = 0, XY = 0, X2 = 0, YS = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; + visitPoints(data, x, y, (dx, dy) => { + const lx = Math.log(dx), ly = Math.log(dy); + ++n; + X += (lx - X) / n; + Y += (ly - Y) / n; + XY += (lx * ly - XY) / n; + X2 += (lx * lx - X2) / n; + YS += (dy - YS) / n; + if (!domain) { + if (dx < xmin) + xmin = dx; + if (dx > xmax) + xmax = dx; + } + }); + let [a, b] = ols(X, Y, XY, X2); + a = Math.exp(a); + const fn = (xx) => a * Math.pow(xx, b); + const out = interpose(xmin, xmax, fn); + out.a = a; + out.b = b; + out.predict = fn; + out.rSquared = determination(data, x, y, YS, fn); + return out; + }; + powerRegression.domain = function (arr) { + if (!arguments.length) + return domain; + domain = arr; + return powerRegression; + }; + powerRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return powerRegression; + }; + powerRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return powerRegression; + }; + return powerRegression; } -function sigmoidal() { - var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, domain, maxIter = 2000, alpha = 1e-4; // learning rate - function sigmoidalRegression(data) { - var n = 0, Xmin = domain ? +domain[0] : Infinity, Xmax = domain ? +domain[1] : -Infinity, Ymin = Infinity, Ymax = -Infinity, sumY = 0; - // Gather data & track min/max for domain if not preset - visitPoints(data, x, y, function (dx, dy) { - n++; - sumY += dy; - if (!domain) { - if (dx < Xmin) - Xmin = dx; - if (dx > Xmax) - Xmax = dx; - } - if (dy < Ymin) - Ymin = dy; - if (dy > Ymax) - Ymax = dy; - }); - if (!domain && (Xmin === Infinity || Xmax === -Infinity)) { - Xmin = 0; - Xmax = 1; - } - // Initialize parameters - var A = Ymax - Ymin; // amplitude - var B = 1; // logistic slope - var C = Ymin; // baseline offset - var M = (Xmin + Xmax) / 2; // midpoint - // Predict function - function f(xx) { - return C + A / (1 + Math.exp(-B * (xx - M))); - } - var _loop_1 = function (iter) { - var dA = 0, dB = 0, dC = 0, dM = 0; - visitPoints(data, x, y, function (dx, dy) { - var yhat = f(dx); - var err = dy - yhat; - var ex = Math.exp(-B * (dx - M)); - var g = 1 / (1 + ex); // logistic - // partial derivatives - var df_dA = g; - var df_dC = 1; - var df_dB = A * g * (1 - g) * (dx - M); - // Note the negative sign for M: - var df_dM = -A * B * g * (1 - g); - var factor = -2 * err; - dA += factor * df_dA; - dB += factor * df_dB; - dC += factor * df_dC; - dM += factor * df_dM; - }); - A -= alpha * (dA / n); - B -= alpha * (dB / n); - C -= alpha * (dC / n); - M -= alpha * (dM / n); - }; - // Gradient Descent - for (var iter = 0; iter < maxIter; iter++) { - _loop_1(); - } - var predict = function (xx) { return C + A / (1 + Math.exp(-B * (xx - M))); }; - var out = interpose(Xmin, Xmax, predict); - out.A = A; - out.B = B; - out.C = C; - out.M = M; - out.predict = predict; - // R^2 - var meanY = sumY / n; - out.rSquared = determination(data, x, y, meanY, predict); - return out; - } - sigmoidalRegression.domain = function (arr) { - if (!arguments.length) - return domain; - domain = arr; - return sigmoidalRegression; - }; - sigmoidalRegression.x = function (fn) { - if (!arguments.length) - return x; - x = fn; - return sigmoidalRegression; - }; - sigmoidalRegression.y = function (fn) { - if (!arguments.length) - return y; - y = fn; - return sigmoidalRegression; - }; - return sigmoidalRegression; +function sigmoidal() { + let x = (d) => d[0], y = (d) => d[1], domain, maxIter = 2000, alpha = 1e-4; // learning rate + function sigmoidalRegression(data) { + let n = 0, Xmin = domain ? +domain[0] : Infinity, Xmax = domain ? +domain[1] : -Infinity, Ymin = Infinity, Ymax = -Infinity, sumY = 0; + // Gather data & track min/max for domain if not preset + visitPoints(data, x, y, (dx, dy) => { + n++; + sumY += dy; + if (!domain) { + if (dx < Xmin) + Xmin = dx; + if (dx > Xmax) + Xmax = dx; + } + if (dy < Ymin) + Ymin = dy; + if (dy > Ymax) + Ymax = dy; + }); + if (!domain && (Xmin === Infinity || Xmax === -Infinity)) { + Xmin = 0; + Xmax = 1; + } + // Initialize parameters + let A = Ymax - Ymin; // amplitude + let B = 1; // logistic slope + let C = Ymin; // baseline offset + let M = (Xmin + Xmax) / 2; // midpoint + // Predict function + function f(xx) { + return C + A / (1 + Math.exp(-B * (xx - M))); + } + // Gradient Descent + for (let iter = 0; iter < maxIter; iter++) { + let dA = 0, dB = 0, dC = 0, dM = 0; + visitPoints(data, x, y, (dx, dy) => { + const yhat = f(dx); + const err = dy - yhat; + const ex = Math.exp(-B * (dx - M)); + const g = 1 / (1 + ex); // logistic + // partial derivatives + const df_dA = g; + const df_dC = 1; + const df_dB = A * g * (1 - g) * (dx - M); + // Note the negative sign for M: + const df_dM = -A * B * g * (1 - g); + const factor = -2 * err; + dA += factor * df_dA; + dB += factor * df_dB; + dC += factor * df_dC; + dM += factor * df_dM; + }); + A -= alpha * (dA / n); + B -= alpha * (dB / n); + C -= alpha * (dC / n); + M -= alpha * (dM / n); + } + const predict = (xx) => C + A / (1 + Math.exp(-B * (xx - M))); + const out = interpose(Xmin, Xmax, predict); + out.A = A; + out.B = B; + out.C = C; + out.M = M; + out.predict = predict; + // R^2 + const meanY = sumY / n; + out.rSquared = determination(data, x, y, meanY, predict); + return out; + } + sigmoidalRegression.domain = function (arr) { + if (!arguments.length) + return domain; + domain = arr; + return sigmoidalRegression; + }; + sigmoidalRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return sigmoidalRegression; + }; + sigmoidalRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return sigmoidalRegression; + }; + return sigmoidalRegression; } exports.regressionExp = exponential; diff --git a/dist/d3-regression.esm.js b/dist/d3-regression.esm.js index f4d98e6..d7ddd95 100644 --- a/dist/d3-regression.esm.js +++ b/dist/d3-regression.esm.js @@ -1,760 +1,757 @@ -// https://github.com/HarryStevens/d3-regression#readme Version 1.3.10. Copyright 2025 Harry Stevens. -/** - * Adapted from vega-statistics by Jeffrey Heer - * License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE - * Source: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/packages/vega-statistics/src/regression/points.js - */ -function points(data, x, y, sort) { - data = data.filter(function (d, i) { - var u = x(d, i), v = y(d, i); - return u != null && isFinite(u) && v != null && isFinite(v); - }); - if (sort) { - data.sort(function (a, b) { return x(a) - x(b); }); - } - var n = data.length, X = new Float64Array(n), Y = new Float64Array(n); - // extract values, calculate means - var ux = 0, uy = 0, xv, yv, d; - for (var i = 0; i < n;) { - d = data[i]; - X[i] = xv = +x(d, i, data); - Y[i] = yv = +y(d, i, data); - ++i; - ux += (xv - ux) / i; - uy += (yv - uy) / i; - } - // mean center the data - for (var i = 0; i < n; ++i) { - X[i] -= ux; - Y[i] -= uy; - } - return [X, Y, ux, uy]; -} -/** - * Iterates over valid data points, invoking a callback for each. - */ -function visitPoints(data, x, y, cb) { - var iterations = 0; - for (var i = 0; i < data.length; i++) { - var d = data[i]; - var dx = +x(d, i, data); - var dy = +y(d, i, data); - if (dx != null && isFinite(dx) && dy != null && isFinite(dy)) { - cb(dx, dy, iterations++); - } - } +// https://github.com/HarryStevens/d3-regression#readme Version 1.3.10-pr48. Copyright 2025 Harry Stevens. +/** + * Adapted from vega-statistics by Jeffrey Heer + * License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE + * Source: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/packages/vega-statistics/src/regression/points.js + */ +function points(data, x, y, sort) { + data = data.filter((d, i) => { + let u = x(d, i), v = y(d, i); + return u != null && isFinite(u) && v != null && isFinite(v); + }); + if (sort) { + data.sort((a, b) => x(a) - x(b)); + } + const n = data.length, X = new Float64Array(n), Y = new Float64Array(n); + // extract values, calculate means + let ux = 0, uy = 0, xv, yv, d; + for (let i = 0; i < n;) { + d = data[i]; + X[i] = xv = +x(d, i, data); + Y[i] = yv = +y(d, i, data); + ++i; + ux += (xv - ux) / i; + uy += (yv - uy) / i; + } + // mean center the data + for (let i = 0; i < n; ++i) { + X[i] -= ux; + Y[i] -= uy; + } + return [X, Y, ux, uy]; +} +/** + * Iterates over valid data points, invoking a callback for each. + */ +function visitPoints(data, x, y, cb) { + let iterations = 0; + for (let i = 0; i < data.length; i++) { + const d = data[i]; + const dx = +x(d, i, data); + const dy = +y(d, i, data); + if (dx != null && isFinite(dx) && dy != null && isFinite(dy)) { + cb(dx, dy, iterations++); + } + } } -/** - * Given a dataset, x- and y-accessors, the mean center of the y-values (uY), - * and a prediction function, return the coefficient of determination, R^2. - */ -function determination(data, x, y, uY, predict) { - var SSE = 0, // Sum of Squared Errors - SST = 0; // Total Sum of Squares - visitPoints(data, x, y, function (dx, dy) { - var sse = dy - predict(dx); - var sst = dy - uY; - SSE += sse * sse; - SST += sst * sst; - }); - return 1 - SSE / SST; +/** + * Given a dataset, x- and y-accessors, the mean center of the y-values (uY), + * and a prediction function, return the coefficient of determination, R^2. + */ +function determination(data, x, y, uY, predict) { + let SSE = 0, // Sum of Squared Errors + SST = 0; // Total Sum of Squares + visitPoints(data, x, y, (dx, dy) => { + const sse = dy - predict(dx); + const sst = dy - uY; + SSE += sse * sse; + SST += sst * sst; + }); + return 1 - SSE / SST; } -/** - * Returns the angle of a line in degrees. - */ -function angle(line) { - return (Math.atan2(line[1][1] - line[0][1], line[1][0] - line[0][0]) * - (180 / Math.PI)); -} -/** - * Returns the midpoint of a line. - */ -function midpoint(line) { - return [ - (line[0][0] + line[1][0]) / 2, - (line[0][1] + line[1][1]) / 2 - ]; +/** + * Returns the angle of a line in degrees. + */ +function angle(line) { + return (Math.atan2(line[1][1] - line[0][1], line[1][0] - line[0][0]) * + (180 / Math.PI)); +} +/** + * Returns the midpoint of a line. + */ +function midpoint(line) { + return [ + (line[0][0] + line[1][0]) / 2, + (line[0][1] + line[1][1]) / 2 + ]; } -/** - * Given a start point (xmin), an end point (xmax), - * and a prediction function, returns a smooth line. - */ -function interpose(xmin, xmax, predict) { - var l = (Math.log(xmax - xmin) * Math.LOG10E + 1) | 0; - var precision = Math.pow(10, -l / 2 - 1); - var maxIter = 1e4; - var points = [px(xmin), px(xmax)]; - var iter = 0; - while (find(points) && iter < maxIter) - ; - return points; - function px(x) { - return [x, predict(x)]; - } - function find(points) { - iter++; - var n = points.length; - var found = false; - for (var i = 0; i < n - 1; i++) { - var p0 = points[i]; - var p1 = points[i + 1]; - var m = midpoint([p0, p1]); - var mp = px(m[0]); - var a0 = angle([p0, m]); - var a1 = angle([p0, mp]); - var a = Math.abs(a0 - a1); - if (a > precision) { - points.splice(i + 1, 0, mp); - found = true; - } - } - return found; - } +/** + * Given a start point (xmin), an end point (xmax), + * and a prediction function, returns a smooth line. + */ +function interpose(xmin, xmax, predict) { + const l = (Math.log(xmax - xmin) * Math.LOG10E + 1) | 0; + const precision = Math.pow(10, -l / 2 - 1); + const maxIter = 1e4; + let points = [px(xmin), px(xmax)]; + let iter = 0; + while (find(points) && iter < maxIter) + ; + return points; + function px(x) { + return [x, predict(x)]; + } + function find(points) { + iter++; + const n = points.length; + let found = false; + for (let i = 0; i < n - 1; i++) { + const p0 = points[i]; + const p1 = points[i + 1]; + const m = midpoint([p0, p1]); + const mp = px(m[0]); + const a0 = angle([p0, m]); + const a1 = angle([p0, mp]); + const a = Math.abs(a0 - a1); + if (a > precision) { + points.splice(i + 1, 0, mp); + found = true; + } + } + return found; + } } -/** - * Ordinary Least Squares from vega-statistics by Jeffrey Heer - * License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE - * Source: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/packages/vega-statistics/src/regression/ols.js - */ -function ols(uX, uY, uXY, uX2) { - var delta = uX2 - uX * uX, slope = Math.abs(delta) < 1e-24 ? 0 : (uXY - uX * uY) / delta, intercept = uY - slope * uX; - return [intercept, slope]; +/** + * Ordinary Least Squares from vega-statistics by Jeffrey Heer + * License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE + * Source: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/packages/vega-statistics/src/regression/ols.js + */ +function ols(uX, uY, uXY, uX2) { + const delta = uX2 - uX * uX, slope = Math.abs(delta) < 1e-24 ? 0 : (uXY - uX * uY) / delta, intercept = uY - slope * uX; + return [intercept, slope]; } -function exponential() { - var y = function (d) { return d[1]; }, x = function (d) { return d[0]; }, domain; - var exponentialRegression = function (data) { - var n = 0, Y = 0, YL = 0, XY = 0, XYL = 0, X2Y = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; - visitPoints(data, x, y, function (dx, dy) { - var ly = Math.log(dy), xy = dx * dy; - ++n; - Y += (dy - Y) / n; - XY += (xy - XY) / n; - X2Y += (dx * xy - X2Y) / n; - YL += (dy * ly - YL) / n; - XYL += (xy * ly - XYL) / n; - if (!domain) { - if (dx < xmin) - xmin = dx; - if (dx > xmax) - xmax = dx; - } - }); - var _a = ols(XY / Y, YL / Y, XYL / Y, X2Y / Y), a = _a[0], b = _a[1]; - a = Math.exp(a); - var fn = function (xx) { return a * Math.exp(b * xx); }; - var out = interpose(xmin, xmax, fn); - out.a = a; - out.b = b; - out.predict = fn; - out.rSquared = determination(data, x, y, Y, fn); - return out; - }; - exponentialRegression.domain = function (arr) { - if (!arguments.length) - return domain; - domain = arr; - return exponentialRegression; - }; - exponentialRegression.x = function (fn) { - if (!arguments.length) - return x; - x = fn; - return exponentialRegression; - }; - exponentialRegression.y = function (fn) { - if (!arguments.length) - return y; - y = fn; - return exponentialRegression; - }; - return exponentialRegression; +function exponential() { + let y = (d) => d[1], x = (d) => d[0], domain; + const exponentialRegression = function (data) { + let n = 0, Y = 0, YL = 0, XY = 0, XYL = 0, X2Y = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; + visitPoints(data, x, y, (dx, dy) => { + const ly = Math.log(dy), xy = dx * dy; + ++n; + Y += (dy - Y) / n; + XY += (xy - XY) / n; + X2Y += (dx * xy - X2Y) / n; + YL += (dy * ly - YL) / n; + XYL += (xy * ly - XYL) / n; + if (!domain) { + if (dx < xmin) + xmin = dx; + if (dx > xmax) + xmax = dx; + } + }); + let [a, b] = ols(XY / Y, YL / Y, XYL / Y, X2Y / Y); + a = Math.exp(a); + const fn = (xx) => a * Math.exp(b * xx); + const out = interpose(xmin, xmax, fn); + out.a = a; + out.b = b; + out.predict = fn; + out.rSquared = determination(data, x, y, Y, fn); + return out; + }; + exponentialRegression.domain = function (arr) { + if (!arguments.length) + return domain; + domain = arr; + return exponentialRegression; + }; + exponentialRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return exponentialRegression; + }; + exponentialRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return exponentialRegression; + }; + return exponentialRegression; } -function linear() { - var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, domain; - var linearRegression = function (data) { - var n = 0, X = 0, // sum of x - Y = 0, // sum of y - XY = 0, // sum of x*y - X2 = 0, // sum of x*x - xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; - visitPoints(data, x, y, function (dx, dy) { - ++n; - X += (dx - X) / n; - Y += (dy - Y) / n; - XY += (dx * dy - XY) / n; - X2 += (dx * dx - X2) / n; - if (!domain) { - if (dx < xmin) - xmin = dx; - if (dx > xmax) - xmax = dx; - } - }); - var _a = ols(X, Y, XY, X2), intercept = _a[0], slope = _a[1]; - var fn = function (xx) { return slope * xx + intercept; }; - var out = [[xmin, fn(xmin)], [xmax, fn(xmax)]]; - out.a = slope; - out.b = intercept; - out.predict = fn; - out.rSquared = determination(data, x, y, Y, fn); - return out; - }; - linearRegression.domain = function (arr) { - if (!arguments.length) - return domain; - domain = arr; - return linearRegression; - }; - linearRegression.x = function (fn) { - if (!arguments.length) - return x; - x = fn; - return linearRegression; - }; - linearRegression.y = function (fn) { - if (!arguments.length) - return y; - y = fn; - return linearRegression; - }; - return linearRegression; +function linear() { + let x = (d) => d[0], y = (d) => d[1], domain; + const linearRegression = function (data) { + let n = 0, X = 0, // sum of x + Y = 0, // sum of y + XY = 0, // sum of x*y + X2 = 0, // sum of x*x + xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; + visitPoints(data, x, y, (dx, dy) => { + ++n; + X += (dx - X) / n; + Y += (dy - Y) / n; + XY += (dx * dy - XY) / n; + X2 += (dx * dx - X2) / n; + if (!domain) { + if (dx < xmin) + xmin = dx; + if (dx > xmax) + xmax = dx; + } + }); + const [intercept, slope] = ols(X, Y, XY, X2); + const fn = (xx) => slope * xx + intercept; + const out = [[xmin, fn(xmin)], [xmax, fn(xmax)]]; + out.a = slope; + out.b = intercept; + out.predict = fn; + out.rSquared = determination(data, x, y, Y, fn); + return out; + }; + linearRegression.domain = function (arr) { + if (!arguments.length) + return domain; + domain = arr; + return linearRegression; + }; + linearRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return linearRegression; + }; + linearRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return linearRegression; + }; + return linearRegression; } -/** - * Returns the median value of an array of numbers. - */ -function median(arr) { - arr.sort(function (a, b) { return a - b; }); - var i = arr.length / 2; - return i % 1 === 0 ? (arr[i - 1] + arr[i]) / 2 : arr[Math.floor(i)]; +/** + * Returns the median value of an array of numbers. + */ +function median(arr) { + arr.sort((a, b) => a - b); + var i = arr.length / 2; + return i % 1 === 0 ? (arr[i - 1] + arr[i]) / 2 : arr[Math.floor(i)]; } -// Adapted from science.js by Jason Davies -var maxiters = 2, epsilon = 1e-12; -function loess() { - var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, bandwidth = 0.3; - var loessRegression = function loessRegression(data) { - var _a = points(data, function (dd) { return x(dd); }, function (dd) { return y(dd); }, true), xv = _a[0], yv = _a[1], ux = _a[2], uy = _a[3]; - var n = xv.length; - var bw = Math.max(2, ~~(bandwidth * n)); // # of nearest neighbors - var yhat = new Float64Array(n); - var residuals = new Float64Array(n); - var robustWeights = new Float64Array(n).fill(1); - for (var iter = -1; ++iter <= maxiters;) { - var interval = [0, bw - 1]; - for (var i = 0; i < n; ++i) { - var dx = xv[i]; - var i0 = interval[0]; - var i1 = interval[1]; - var edge = (dx - xv[i0]) > (xv[i1] - dx) ? i0 : i1; - var W = 0, X = 0, Y = 0, XY = 0, X2 = 0; - var denom = 1 / Math.abs(xv[edge] - dx || 1); - for (var k = i0; k <= i1; ++k) { - var xk = xv[k]; - var yk = yv[k]; - var w = tricube(Math.abs(dx - xk) * denom) * robustWeights[k]; - var xkw = xk * w; - W += w; - X += xkw; - Y += yk * w; - XY += yk * xkw; - X2 += xk * xkw; - } - // Linear regression fit - var _b = ols(X / W, Y / W, XY / W, X2 / W), a = _b[0], b = _b[1]; - yhat[i] = a + b * dx; - residuals[i] = Math.abs(yv[i] - yhat[i]); - updateInterval(xv, i + 1, interval); - } - if (iter === maxiters) { - break; - } - var medianResidual = median(residuals); - if (Math.abs(medianResidual) < epsilon) - break; - for (var i = 0, arg = void 0, w = void 0; i < n; ++i) { - arg = residuals[i] / (6 * medianResidual); - // Default to epsilon (rather than zero) for large deviations - // Keeping weights tiny but non-zero prevents singularites - robustWeights[i] = (arg >= 1) ? epsilon : ((w = 1 - arg * arg) * w); - } - } - return output(xv, yhat, ux, uy); - }; - loessRegression.bandwidth = function (bw) { - if (!arguments.length) - return bandwidth; - bandwidth = bw; - return loessRegression; - }; - loessRegression.x = function (fn) { - if (!arguments.length) - return x; - x = fn; - return loessRegression; - }; - loessRegression.y = function (fn) { - if (!arguments.length) - return y; - y = fn; - return loessRegression; - }; - return loessRegression; -} -// Weighting kernel for local regression -function tricube(x) { - return (x = 1 - x * x * x) * x * x; -} -// Advance sliding window interval of nearest neighbors -function updateInterval(xv, i, interval) { - var val = xv[i], left = interval[0], right = interval[1] + 1; - if (right >= xv.length) - return; - // Step right if distance to new right edge is <= distance to old left edge - // Step when distance is equal to ensure movement over duplicate x values - while (i > left && (xv[right] - val) <= (val - xv[left])) { - interval[0] = ++left; - interval[1] = right; - ++right; - } -} -// Generate smoothed output points -// Average points with repeated x values -function output(xv, yhat, ux, uy) { - var n = xv.length, out = []; - var i = 0, cnt = 0, prev = [], v; - for (; i < n; ++i) { - v = xv[i] + ux; - if (prev[0] === v) { - // Average output values via online update - prev[1] += (yhat[i] - prev[1]) / (++cnt); - } - else { - // Add new output point - cnt = 0; - prev[1] += uy; - prev = [v, yhat[i]]; - out.push(prev); - } - } - prev[1] += uy; - return out; +// Adapted from science.js by Jason Davies +const maxiters = 2, epsilon = 1e-12; +function loess() { + let x = (d) => d[0], y = (d) => d[1], bandwidth = 0.3; + const loessRegression = function loessRegression(data) { + const [xv, yv, ux, uy] = points(data, (dd) => x(dd), (dd) => y(dd), true); + const n = xv.length; + const bw = Math.max(2, ~~(bandwidth * n)); // # of nearest neighbors + const yhat = new Float64Array(n); + const residuals = new Float64Array(n); + const robustWeights = new Float64Array(n).fill(1); + for (let iter = -1; ++iter <= maxiters;) { + const interval = [0, bw - 1]; + for (let i = 0; i < n; ++i) { + const dx = xv[i]; + const i0 = interval[0]; + const i1 = interval[1]; + const edge = (dx - xv[i0]) > (xv[i1] - dx) ? i0 : i1; + let W = 0, X = 0, Y = 0, XY = 0, X2 = 0; + const denom = 1 / Math.abs(xv[edge] - dx || 1); + for (let k = i0; k <= i1; ++k) { + const xk = xv[k]; + const yk = yv[k]; + const w = tricube(Math.abs(dx - xk) * denom) * robustWeights[k]; + const xkw = xk * w; + W += w; + X += xkw; + Y += yk * w; + XY += yk * xkw; + X2 += xk * xkw; + } + // Linear regression fit + const [a, b] = ols(X / W, Y / W, XY / W, X2 / W); + yhat[i] = a + b * dx; + residuals[i] = Math.abs(yv[i] - yhat[i]); + updateInterval(xv, i + 1, interval); + } + if (iter === maxiters) { + break; + } + const medianResidual = median(residuals); + if (Math.abs(medianResidual) < epsilon) + break; + for (let i = 0, arg, w; i < n; ++i) { + arg = residuals[i] / (6 * medianResidual); + // Default to epsilon (rather than zero) for large deviations + // Keeping weights tiny but non-zero prevents singularites + robustWeights[i] = (arg >= 1) ? epsilon : ((w = 1 - arg * arg) * w); + } + } + return output(xv, yhat, ux, uy); + }; + loessRegression.bandwidth = function (bw) { + if (!arguments.length) + return bandwidth; + bandwidth = bw; + return loessRegression; + }; + loessRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return loessRegression; + }; + loessRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return loessRegression; + }; + return loessRegression; +} +// Weighting kernel for local regression +function tricube(x) { + return (x = 1 - x * x * x) * x * x; +} +// Advance sliding window interval of nearest neighbors +function updateInterval(xv, i, interval) { + let val = xv[i], left = interval[0], right = interval[1] + 1; + if (right >= xv.length) + return; + // Step right if distance to new right edge is <= distance to old left edge + // Step when distance is equal to ensure movement over duplicate x values + while (i > left && (xv[right] - val) <= (val - xv[left])) { + interval[0] = ++left; + interval[1] = right; + ++right; + } +} +// Generate smoothed output points +// Average points with repeated x values +function output(xv, yhat, ux, uy) { + const n = xv.length, out = []; + let i = 0, cnt = 0, prev = [], v; + for (; i < n; ++i) { + v = xv[i] + ux; + if (prev[0] === v) { + // Average output values via online update + prev[1] += (yhat[i] - prev[1]) / (++cnt); + } + else { + // Add new output point + cnt = 0; + prev[1] += uy; + prev = [v, yhat[i]]; + out.push(prev); + } + } + prev[1] += uy; + return out; } -function logarithmic() { - var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, base = Math.E, domain; - var logarithmicRegression = function (data) { - var n = 0, X = 0, Y = 0, XY = 0, X2 = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity, lb = Math.log(base); - visitPoints(data, x, y, function (dx, dy) { - var lx = Math.log(dx) / lb; - ++n; - X += (lx - X) / n; - Y += (dy - Y) / n; - XY += (lx * dy - XY) / n; - X2 += (lx * lx - X2) / n; - if (!domain) { - if (dx < xmin) - xmin = dx; - if (dx > xmax) - xmax = dx; - } - }); - var _a = ols(X, Y, XY, X2), intercept = _a[0], slope = _a[1]; - var fn = function (xx) { return slope * Math.log(xx) / lb + intercept; }; - var out = interpose(xmin, xmax, fn); - out.a = slope; - out.b = intercept; - out.predict = fn; - out.rSquared = determination(data, x, y, Y, fn); - return out; - }; - logarithmicRegression.domain = function (arr) { - if (!arguments.length) - return domain; - domain = arr; - return logarithmicRegression; - }; - logarithmicRegression.x = function (fn) { - if (!arguments.length) - return x; - x = fn; - return logarithmicRegression; - }; - logarithmicRegression.y = function (fn) { - if (!arguments.length) - return y; - y = fn; - return logarithmicRegression; - }; - logarithmicRegression.base = function (b) { - if (!arguments.length) - return base; - base = b; - return logarithmicRegression; - }; - return logarithmicRegression; +function logarithmic() { + let x = (d) => d[0], y = (d) => d[1], base = Math.E, domain; + const logarithmicRegression = function (data) { + let n = 0, X = 0, Y = 0, XY = 0, X2 = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity, lb = Math.log(base); + visitPoints(data, x, y, (dx, dy) => { + const lx = Math.log(dx) / lb; + ++n; + X += (lx - X) / n; + Y += (dy - Y) / n; + XY += (lx * dy - XY) / n; + X2 += (lx * lx - X2) / n; + if (!domain) { + if (dx < xmin) + xmin = dx; + if (dx > xmax) + xmax = dx; + } + }); + const [intercept, slope] = ols(X, Y, XY, X2); + const fn = (xx) => slope * Math.log(xx) / lb + intercept; + const out = interpose(xmin, xmax, fn); + out.a = slope; + out.b = intercept; + out.predict = fn; + out.rSquared = determination(data, x, y, Y, fn); + return out; + }; + logarithmicRegression.domain = function (arr) { + if (!arguments.length) + return domain; + domain = arr; + return logarithmicRegression; + }; + logarithmicRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return logarithmicRegression; + }; + logarithmicRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return logarithmicRegression; + }; + logarithmicRegression.base = function (b) { + if (!arguments.length) + return base; + base = b; + return logarithmicRegression; + }; + return logarithmicRegression; } -function quadratic() { - var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, domain; - var quadraticRegression = function quadraticRegression(data) { - var _a = points(data, function (dd) { return x(dd); }, function (dd) { return y(dd); }), xv = _a[0], yv = _a[1], ux = _a[2], uy = _a[3]; - var n = xv.length; - var X2 = 0, X3 = 0, X4 = 0, XY = 0, X2Y = 0, i, dx, dy, x2; - for (i = 0; i < n;) { - dx = xv[i]; - dy = yv[i++]; - x2 = dx * dx; - X2 += (x2 - X2) / i; - X3 += ((x2 * dx) - X3) / i; - X4 += ((x2 * x2) - X4) / i; - XY += ((dx * dy) - XY) / i; - X2Y += ((x2 * dy) - X2Y) / i; - } - var Y = 0, n0 = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; - visitPoints(data, x, y, function (dx2, dy2) { - n0++; - Y += (dy2 - Y) / n0; - if (!domain) { - if (dx2 < xmin) - xmin = dx2; - if (dx2 > xmax) - xmax = dx2; - } - }); - var X2X2 = X4 - (X2 * X2); - var d = (X2 * X2X2 - X3 * X3); - var a = (X2Y * X2 - XY * X3) / d; - var b = (XY * X2X2 - X2Y * X3) / d; - var c = -a * X2; - var fn = function (xx) { - var shifted = xx - ux; - return a * shifted * shifted + b * shifted + c + uy; - }; - var out = interpose(xmin, xmax, fn); - out.a = a; - out.b = b - 2 * a * ux; - out.c = c - b * ux + a * ux * ux + uy; - out.predict = fn; - out.rSquared = determination(data, x, y, Y, fn); - return out; - }; - quadraticRegression.domain = function (arr) { - if (!arguments.length) - return domain; - domain = arr; - return quadraticRegression; - }; - quadraticRegression.x = function (fn) { - if (!arguments.length) - return x; - x = fn; - return quadraticRegression; - }; - quadraticRegression.y = function (fn) { - if (!arguments.length) - return y; - y = fn; - return quadraticRegression; - }; - return quadraticRegression; +function quadratic() { + let x = (d) => d[0], y = (d) => d[1], domain; + const quadraticRegression = function quadraticRegression(data) { + const [xv, yv, ux, uy] = points(data, (dd) => x(dd), (dd) => y(dd)); + const n = xv.length; + let X2 = 0, X3 = 0, X4 = 0, XY = 0, X2Y = 0, i, dx, dy, x2; + for (i = 0; i < n;) { + dx = xv[i]; + dy = yv[i++]; + x2 = dx * dx; + X2 += (x2 - X2) / i; + X3 += ((x2 * dx) - X3) / i; + X4 += ((x2 * x2) - X4) / i; + XY += ((dx * dy) - XY) / i; + X2Y += ((x2 * dy) - X2Y) / i; + } + let Y = 0, n0 = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; + visitPoints(data, x, y, (dx2, dy2) => { + n0++; + Y += (dy2 - Y) / n0; + if (!domain) { + if (dx2 < xmin) + xmin = dx2; + if (dx2 > xmax) + xmax = dx2; + } + }); + const X2X2 = X4 - (X2 * X2); + const d = (X2 * X2X2 - X3 * X3); + const a = (X2Y * X2 - XY * X3) / d; + const b = (XY * X2X2 - X2Y * X3) / d; + const c = -a * X2; + const fn = (xx) => { + const shifted = xx - ux; + return a * shifted * shifted + b * shifted + c + uy; + }; + const out = interpose(xmin, xmax, fn); + out.a = a; + out.b = b - 2 * a * ux; + out.c = c - b * ux + a * ux * ux + uy; + out.predict = fn; + out.rSquared = determination(data, x, y, Y, fn); + return out; + }; + quadraticRegression.domain = function (arr) { + if (!arguments.length) + return domain; + domain = arr; + return quadraticRegression; + }; + quadraticRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return quadraticRegression; + }; + quadraticRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return quadraticRegression; + }; + return quadraticRegression; } -// Adapted from regression-js by Tom Alexander -function polynomial() { - var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, order = 3, domain; - var polynomialRegression = function polynomialRegression(data) { - // Shortcut for lower-order polynomials: - if (order === 1) { - var o = linear().x(x).y(y).domain(domain)(data); - var result = [o[0], o[1]]; - result.coefficients = [o.b, o.a]; - result.predict = o.predict; - result.rSquared = o.rSquared; - return result; - } - if (order === 2) { - var o = quadratic().x(x).y(y).domain(domain)(data); - var result = [o[0], o[1]]; - result.coefficients = [o.c, o.b, o.a]; - result.predict = o.predict; - result.rSquared = o.rSquared; - return result; - } - var _a = points(data, x, y), xv = _a[0], yv = _a[1], ux = _a[2], uy = _a[3]; - var n = xv.length; - var k = order + 1; - var lhs = []; - var rhs = []; - var Y = 0, n0 = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; - visitPoints(data, x, y, function (dx, dy) { - n0++; - Y += (dy - Y) / n0; - if (!domain) { - if (dx < xmin) - xmin = dx; - if (dx > xmax) - xmax = dx; - } - }); - // Build normal equations - for (var i = 0; i < k; i++) { - // LHS - var v = 0; - for (var l = 0; l < n; l++) { - v += Math.pow(xv[l], i) * yv[l]; - } - lhs.push(v); - // RHS - var c = new Float64Array(k); - for (var j = 0; j < k; j++) { - var v2 = 0; - for (var l = 0; l < n; l++) { - v2 += Math.pow(xv[l], i + j); - } - c[j] = v2; - } - rhs.push(c); - } - rhs.push(new Float64Array(lhs)); - var coef = gaussianElimination(rhs); - var fn = function (xx) { - var shifted = xx - ux; - var val = uy + coef[0]; - for (var i = 1; i < k; i++) { - val += coef[i] * Math.pow(shifted, i); - } - return val; - }; - var out = interpose(xmin, xmax, fn); - out.coefficients = uncenter(k, coef, -ux, uy); - out.predict = fn; - out.rSquared = determination(data, x, y, Y, fn); - return out; - }; - polynomialRegression.domain = function (arr) { - if (!arguments.length) - return domain; - domain = arr; - return polynomialRegression; - }; - polynomialRegression.x = function (fn) { - if (!arguments.length) - return x; - x = fn; - return polynomialRegression; - }; - polynomialRegression.y = function (fn) { - if (!arguments.length) - return y; - y = fn; - return polynomialRegression; - }; - polynomialRegression.order = function (n) { - if (!arguments.length) - return order; - order = n; - return polynomialRegression; - }; - return polynomialRegression; -} -function uncenter(k, a, x, y) { - var z = new Array(k).fill(0); - for (var i = k - 1; i >= 0; --i) { - var v = a[i]; - z[i] += v; - var c = 1; - for (var j = 1; j <= i; ++j) { - c *= (i + 1 - j) / j; // binomial coefficient - z[i - j] += v * Math.pow(x, j) * c; - } - } - // bias term - z[0] += y; - return z; -} -// Solve A * x = b using Gaussian elimination -function gaussianElimination(matrix) { - var n = matrix.length - 1; - var coef = new Array(n); - for (var i = 0; i < n; i++) { - var r = i; - // find pivot row - for (var j = i + 1; j < n; j++) { - if (Math.abs(matrix[i][j]) > Math.abs(matrix[i][r])) { - r = j; - } - } - // swap columns - for (var k = i; k < n + 1; k++) { - var t = matrix[k][i]; - matrix[k][i] = matrix[k][r]; - matrix[k][r] = t; - } - // reduce - for (var j = i + 1; j < n; j++) { - for (var k = n; k >= i; k--) { - matrix[k][j] -= (matrix[k][i] * matrix[i][j]) / matrix[i][i]; - } - } - } - for (var j = n - 1; j >= 0; j--) { - var t = 0; - for (var k = j + 1; k < n; k++) { - t += matrix[k][j] * coef[k]; - } - coef[j] = (matrix[n][j] - t) / matrix[j][j]; - } - return coef; +// Adapted from regression-js by Tom Alexander +function polynomial() { + let x = (d) => d[0], y = (d) => d[1], order = 3, domain; + const polynomialRegression = function polynomialRegression(data) { + // Shortcut for lower-order polynomials: + if (order === 1) { + const o = linear().x(x).y(y).domain(domain)(data); + const result = [o[0], o[1]]; + result.coefficients = [o.b, o.a]; + result.predict = o.predict; + result.rSquared = o.rSquared; + return result; + } + if (order === 2) { + const o = quadratic().x(x).y(y).domain(domain)(data); + const result = [o[0], o[1]]; + result.coefficients = [o.c, o.b, o.a]; + result.predict = o.predict; + result.rSquared = o.rSquared; + return result; + } + const [xv, yv, ux, uy] = points(data, x, y); + const n = xv.length; + const k = order + 1; + const lhs = []; + const rhs = []; + let Y = 0, n0 = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; + visitPoints(data, x, y, (dx, dy) => { + n0++; + Y += (dy - Y) / n0; + if (!domain) { + if (dx < xmin) + xmin = dx; + if (dx > xmax) + xmax = dx; + } + }); + // Build normal equations + for (let i = 0; i < k; i++) { + // LHS + let v = 0; + for (let l = 0; l < n; l++) { + v += Math.pow(xv[l], i) * yv[l]; + } + lhs.push(v); + // RHS + const c = new Float64Array(k); + for (let j = 0; j < k; j++) { + let v2 = 0; + for (let l = 0; l < n; l++) { + v2 += Math.pow(xv[l], i + j); + } + c[j] = v2; + } + rhs.push(c); + } + rhs.push(new Float64Array(lhs)); + const coef = gaussianElimination(rhs); + const fn = (xx) => { + let shifted = xx - ux; + let val = uy + coef[0]; + for (let i = 1; i < k; i++) { + val += coef[i] * Math.pow(shifted, i); + } + return val; + }; + const out = interpose(xmin, xmax, fn); + out.coefficients = uncenter(k, coef, -ux, uy); + out.predict = fn; + out.rSquared = determination(data, x, y, Y, fn); + return out; + }; + polynomialRegression.domain = function (arr) { + if (!arguments.length) + return domain; + domain = arr; + return polynomialRegression; + }; + polynomialRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return polynomialRegression; + }; + polynomialRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return polynomialRegression; + }; + polynomialRegression.order = function (n) { + if (!arguments.length) + return order; + order = n; + return polynomialRegression; + }; + return polynomialRegression; +} +function uncenter(k, a, x, y) { + const z = new Array(k).fill(0); + for (let i = k - 1; i >= 0; --i) { + let v = a[i]; + z[i] += v; + let c = 1; + for (let j = 1; j <= i; ++j) { + c *= (i + 1 - j) / j; // binomial coefficient + z[i - j] += v * Math.pow(x, j) * c; + } + } + // bias term + z[0] += y; + return z; +} +// Solve A * x = b using Gaussian elimination +function gaussianElimination(matrix) { + const n = matrix.length - 1; + const coef = new Array(n); + for (let i = 0; i < n; i++) { + let r = i; + // find pivot row + for (let j = i + 1; j < n; j++) { + if (Math.abs(matrix[i][j]) > Math.abs(matrix[i][r])) { + r = j; + } + } + // swap columns + for (let k = i; k < n + 1; k++) { + const t = matrix[k][i]; + matrix[k][i] = matrix[k][r]; + matrix[k][r] = t; + } + // reduce + for (let j = i + 1; j < n; j++) { + for (let k = n; k >= i; k--) { + matrix[k][j] -= (matrix[k][i] * matrix[i][j]) / matrix[i][i]; + } + } + } + for (let j = n - 1; j >= 0; j--) { + let t = 0; + for (let k = j + 1; k < n; k++) { + t += matrix[k][j] * coef[k]; + } + coef[j] = (matrix[n][j] - t) / matrix[j][j]; + } + return coef; } -function power() { - var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, domain; - var powerRegression = function powerRegression(data) { - var n = 0, X = 0, Y = 0, XY = 0, X2 = 0, YS = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; - visitPoints(data, x, y, function (dx, dy) { - var lx = Math.log(dx), ly = Math.log(dy); - ++n; - X += (lx - X) / n; - Y += (ly - Y) / n; - XY += (lx * ly - XY) / n; - X2 += (lx * lx - X2) / n; - YS += (dy - YS) / n; - if (!domain) { - if (dx < xmin) - xmin = dx; - if (dx > xmax) - xmax = dx; - } - }); - var _a = ols(X, Y, XY, X2), a = _a[0], b = _a[1]; - a = Math.exp(a); - var fn = function (xx) { return a * Math.pow(xx, b); }; - var out = interpose(xmin, xmax, fn); - out.a = a; - out.b = b; - out.predict = fn; - out.rSquared = determination(data, x, y, YS, fn); - return out; - }; - powerRegression.domain = function (arr) { - if (!arguments.length) - return domain; - domain = arr; - return powerRegression; - }; - powerRegression.x = function (fn) { - if (!arguments.length) - return x; - x = fn; - return powerRegression; - }; - powerRegression.y = function (fn) { - if (!arguments.length) - return y; - y = fn; - return powerRegression; - }; - return powerRegression; +function power() { + let x = (d) => d[0], y = (d) => d[1], domain; + const powerRegression = function powerRegression(data) { + let n = 0, X = 0, Y = 0, XY = 0, X2 = 0, YS = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; + visitPoints(data, x, y, (dx, dy) => { + const lx = Math.log(dx), ly = Math.log(dy); + ++n; + X += (lx - X) / n; + Y += (ly - Y) / n; + XY += (lx * ly - XY) / n; + X2 += (lx * lx - X2) / n; + YS += (dy - YS) / n; + if (!domain) { + if (dx < xmin) + xmin = dx; + if (dx > xmax) + xmax = dx; + } + }); + let [a, b] = ols(X, Y, XY, X2); + a = Math.exp(a); + const fn = (xx) => a * Math.pow(xx, b); + const out = interpose(xmin, xmax, fn); + out.a = a; + out.b = b; + out.predict = fn; + out.rSquared = determination(data, x, y, YS, fn); + return out; + }; + powerRegression.domain = function (arr) { + if (!arguments.length) + return domain; + domain = arr; + return powerRegression; + }; + powerRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return powerRegression; + }; + powerRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return powerRegression; + }; + return powerRegression; } -function sigmoidal() { - var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, domain, maxIter = 2000, alpha = 1e-4; // learning rate - function sigmoidalRegression(data) { - var n = 0, Xmin = domain ? +domain[0] : Infinity, Xmax = domain ? +domain[1] : -Infinity, Ymin = Infinity, Ymax = -Infinity, sumY = 0; - // Gather data & track min/max for domain if not preset - visitPoints(data, x, y, function (dx, dy) { - n++; - sumY += dy; - if (!domain) { - if (dx < Xmin) - Xmin = dx; - if (dx > Xmax) - Xmax = dx; - } - if (dy < Ymin) - Ymin = dy; - if (dy > Ymax) - Ymax = dy; - }); - if (!domain && (Xmin === Infinity || Xmax === -Infinity)) { - Xmin = 0; - Xmax = 1; - } - // Initialize parameters - var A = Ymax - Ymin; // amplitude - var B = 1; // logistic slope - var C = Ymin; // baseline offset - var M = (Xmin + Xmax) / 2; // midpoint - // Predict function - function f(xx) { - return C + A / (1 + Math.exp(-B * (xx - M))); - } - var _loop_1 = function (iter) { - var dA = 0, dB = 0, dC = 0, dM = 0; - visitPoints(data, x, y, function (dx, dy) { - var yhat = f(dx); - var err = dy - yhat; - var ex = Math.exp(-B * (dx - M)); - var g = 1 / (1 + ex); // logistic - // partial derivatives - var df_dA = g; - var df_dC = 1; - var df_dB = A * g * (1 - g) * (dx - M); - // Note the negative sign for M: - var df_dM = -A * B * g * (1 - g); - var factor = -2 * err; - dA += factor * df_dA; - dB += factor * df_dB; - dC += factor * df_dC; - dM += factor * df_dM; - }); - A -= alpha * (dA / n); - B -= alpha * (dB / n); - C -= alpha * (dC / n); - M -= alpha * (dM / n); - }; - // Gradient Descent - for (var iter = 0; iter < maxIter; iter++) { - _loop_1(); - } - var predict = function (xx) { return C + A / (1 + Math.exp(-B * (xx - M))); }; - var out = interpose(Xmin, Xmax, predict); - out.A = A; - out.B = B; - out.C = C; - out.M = M; - out.predict = predict; - // R^2 - var meanY = sumY / n; - out.rSquared = determination(data, x, y, meanY, predict); - return out; - } - sigmoidalRegression.domain = function (arr) { - if (!arguments.length) - return domain; - domain = arr; - return sigmoidalRegression; - }; - sigmoidalRegression.x = function (fn) { - if (!arguments.length) - return x; - x = fn; - return sigmoidalRegression; - }; - sigmoidalRegression.y = function (fn) { - if (!arguments.length) - return y; - y = fn; - return sigmoidalRegression; - }; - return sigmoidalRegression; +function sigmoidal() { + let x = (d) => d[0], y = (d) => d[1], domain, maxIter = 2000, alpha = 1e-4; // learning rate + function sigmoidalRegression(data) { + let n = 0, Xmin = domain ? +domain[0] : Infinity, Xmax = domain ? +domain[1] : -Infinity, Ymin = Infinity, Ymax = -Infinity, sumY = 0; + // Gather data & track min/max for domain if not preset + visitPoints(data, x, y, (dx, dy) => { + n++; + sumY += dy; + if (!domain) { + if (dx < Xmin) + Xmin = dx; + if (dx > Xmax) + Xmax = dx; + } + if (dy < Ymin) + Ymin = dy; + if (dy > Ymax) + Ymax = dy; + }); + if (!domain && (Xmin === Infinity || Xmax === -Infinity)) { + Xmin = 0; + Xmax = 1; + } + // Initialize parameters + let A = Ymax - Ymin; // amplitude + let B = 1; // logistic slope + let C = Ymin; // baseline offset + let M = (Xmin + Xmax) / 2; // midpoint + // Predict function + function f(xx) { + return C + A / (1 + Math.exp(-B * (xx - M))); + } + // Gradient Descent + for (let iter = 0; iter < maxIter; iter++) { + let dA = 0, dB = 0, dC = 0, dM = 0; + visitPoints(data, x, y, (dx, dy) => { + const yhat = f(dx); + const err = dy - yhat; + const ex = Math.exp(-B * (dx - M)); + const g = 1 / (1 + ex); // logistic + // partial derivatives + const df_dA = g; + const df_dC = 1; + const df_dB = A * g * (1 - g) * (dx - M); + // Note the negative sign for M: + const df_dM = -A * B * g * (1 - g); + const factor = -2 * err; + dA += factor * df_dA; + dB += factor * df_dB; + dC += factor * df_dC; + dM += factor * df_dM; + }); + A -= alpha * (dA / n); + B -= alpha * (dB / n); + C -= alpha * (dC / n); + M -= alpha * (dM / n); + } + const predict = (xx) => C + A / (1 + Math.exp(-B * (xx - M))); + const out = interpose(Xmin, Xmax, predict); + out.A = A; + out.B = B; + out.C = C; + out.M = M; + out.predict = predict; + // R^2 + const meanY = sumY / n; + out.rSquared = determination(data, x, y, meanY, predict); + return out; + } + sigmoidalRegression.domain = function (arr) { + if (!arguments.length) + return domain; + domain = arr; + return sigmoidalRegression; + }; + sigmoidalRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return sigmoidalRegression; + }; + sigmoidalRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return sigmoidalRegression; + }; + return sigmoidalRegression; } export { exponential as regressionExp, linear as regressionLinear, loess as regressionLoess, logarithmic as regressionLog, polynomial as regressionPoly, power as regressionPow, quadratic as regressionQuad, sigmoidal as regressionSigmoidal }; diff --git a/dist/d3-regression.js b/dist/d3-regression.js index f6b0111..2c3d809 100644 --- a/dist/d3-regression.js +++ b/dist/d3-regression.js @@ -1,766 +1,763 @@ -// https://github.com/HarryStevens/d3-regression#readme Version 1.3.10. Copyright 2025 Harry Stevens. +// https://github.com/HarryStevens/d3-regression#readme Version 1.3.10-pr48. Copyright 2025 Harry Stevens. (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : - (global = global || self, factory(global.d3 = {})); -}(this, (function (exports) { 'use strict'; + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.d3 = {})); +})(this, (function (exports) { 'use strict'; - /** - * Adapted from vega-statistics by Jeffrey Heer - * License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE - * Source: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/packages/vega-statistics/src/regression/points.js - */ - function points(data, x, y, sort) { - data = data.filter(function (d, i) { - var u = x(d, i), v = y(d, i); - return u != null && isFinite(u) && v != null && isFinite(v); - }); - if (sort) { - data.sort(function (a, b) { return x(a) - x(b); }); - } - var n = data.length, X = new Float64Array(n), Y = new Float64Array(n); - // extract values, calculate means - var ux = 0, uy = 0, xv, yv, d; - for (var i = 0; i < n;) { - d = data[i]; - X[i] = xv = +x(d, i, data); - Y[i] = yv = +y(d, i, data); - ++i; - ux += (xv - ux) / i; - uy += (yv - uy) / i; - } - // mean center the data - for (var i = 0; i < n; ++i) { - X[i] -= ux; - Y[i] -= uy; - } - return [X, Y, ux, uy]; - } - /** - * Iterates over valid data points, invoking a callback for each. - */ - function visitPoints(data, x, y, cb) { - var iterations = 0; - for (var i = 0; i < data.length; i++) { - var d = data[i]; - var dx = +x(d, i, data); - var dy = +y(d, i, data); - if (dx != null && isFinite(dx) && dy != null && isFinite(dy)) { - cb(dx, dy, iterations++); - } - } + /** + * Adapted from vega-statistics by Jeffrey Heer + * License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE + * Source: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/packages/vega-statistics/src/regression/points.js + */ + function points(data, x, y, sort) { + data = data.filter((d, i) => { + let u = x(d, i), v = y(d, i); + return u != null && isFinite(u) && v != null && isFinite(v); + }); + if (sort) { + data.sort((a, b) => x(a) - x(b)); + } + const n = data.length, X = new Float64Array(n), Y = new Float64Array(n); + // extract values, calculate means + let ux = 0, uy = 0, xv, yv, d; + for (let i = 0; i < n;) { + d = data[i]; + X[i] = xv = +x(d, i, data); + Y[i] = yv = +y(d, i, data); + ++i; + ux += (xv - ux) / i; + uy += (yv - uy) / i; + } + // mean center the data + for (let i = 0; i < n; ++i) { + X[i] -= ux; + Y[i] -= uy; + } + return [X, Y, ux, uy]; + } + /** + * Iterates over valid data points, invoking a callback for each. + */ + function visitPoints(data, x, y, cb) { + let iterations = 0; + for (let i = 0; i < data.length; i++) { + const d = data[i]; + const dx = +x(d, i, data); + const dy = +y(d, i, data); + if (dx != null && isFinite(dx) && dy != null && isFinite(dy)) { + cb(dx, dy, iterations++); + } + } } - /** - * Given a dataset, x- and y-accessors, the mean center of the y-values (uY), - * and a prediction function, return the coefficient of determination, R^2. - */ - function determination(data, x, y, uY, predict) { - var SSE = 0, // Sum of Squared Errors - SST = 0; // Total Sum of Squares - visitPoints(data, x, y, function (dx, dy) { - var sse = dy - predict(dx); - var sst = dy - uY; - SSE += sse * sse; - SST += sst * sst; - }); - return 1 - SSE / SST; + /** + * Given a dataset, x- and y-accessors, the mean center of the y-values (uY), + * and a prediction function, return the coefficient of determination, R^2. + */ + function determination(data, x, y, uY, predict) { + let SSE = 0, // Sum of Squared Errors + SST = 0; // Total Sum of Squares + visitPoints(data, x, y, (dx, dy) => { + const sse = dy - predict(dx); + const sst = dy - uY; + SSE += sse * sse; + SST += sst * sst; + }); + return 1 - SSE / SST; } - /** - * Returns the angle of a line in degrees. - */ - function angle(line) { - return (Math.atan2(line[1][1] - line[0][1], line[1][0] - line[0][0]) * - (180 / Math.PI)); - } - /** - * Returns the midpoint of a line. - */ - function midpoint(line) { - return [ - (line[0][0] + line[1][0]) / 2, - (line[0][1] + line[1][1]) / 2 - ]; + /** + * Returns the angle of a line in degrees. + */ + function angle(line) { + return (Math.atan2(line[1][1] - line[0][1], line[1][0] - line[0][0]) * + (180 / Math.PI)); + } + /** + * Returns the midpoint of a line. + */ + function midpoint(line) { + return [ + (line[0][0] + line[1][0]) / 2, + (line[0][1] + line[1][1]) / 2 + ]; } - /** - * Given a start point (xmin), an end point (xmax), - * and a prediction function, returns a smooth line. - */ - function interpose(xmin, xmax, predict) { - var l = (Math.log(xmax - xmin) * Math.LOG10E + 1) | 0; - var precision = Math.pow(10, -l / 2 - 1); - var maxIter = 1e4; - var points = [px(xmin), px(xmax)]; - var iter = 0; - while (find(points) && iter < maxIter) - ; - return points; - function px(x) { - return [x, predict(x)]; - } - function find(points) { - iter++; - var n = points.length; - var found = false; - for (var i = 0; i < n - 1; i++) { - var p0 = points[i]; - var p1 = points[i + 1]; - var m = midpoint([p0, p1]); - var mp = px(m[0]); - var a0 = angle([p0, m]); - var a1 = angle([p0, mp]); - var a = Math.abs(a0 - a1); - if (a > precision) { - points.splice(i + 1, 0, mp); - found = true; - } - } - return found; - } + /** + * Given a start point (xmin), an end point (xmax), + * and a prediction function, returns a smooth line. + */ + function interpose(xmin, xmax, predict) { + const l = (Math.log(xmax - xmin) * Math.LOG10E + 1) | 0; + const precision = Math.pow(10, -l / 2 - 1); + const maxIter = 1e4; + let points = [px(xmin), px(xmax)]; + let iter = 0; + while (find(points) && iter < maxIter) + ; + return points; + function px(x) { + return [x, predict(x)]; + } + function find(points) { + iter++; + const n = points.length; + let found = false; + for (let i = 0; i < n - 1; i++) { + const p0 = points[i]; + const p1 = points[i + 1]; + const m = midpoint([p0, p1]); + const mp = px(m[0]); + const a0 = angle([p0, m]); + const a1 = angle([p0, mp]); + const a = Math.abs(a0 - a1); + if (a > precision) { + points.splice(i + 1, 0, mp); + found = true; + } + } + return found; + } } - /** - * Ordinary Least Squares from vega-statistics by Jeffrey Heer - * License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE - * Source: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/packages/vega-statistics/src/regression/ols.js - */ - function ols(uX, uY, uXY, uX2) { - var delta = uX2 - uX * uX, slope = Math.abs(delta) < 1e-24 ? 0 : (uXY - uX * uY) / delta, intercept = uY - slope * uX; - return [intercept, slope]; + /** + * Ordinary Least Squares from vega-statistics by Jeffrey Heer + * License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE + * Source: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/packages/vega-statistics/src/regression/ols.js + */ + function ols(uX, uY, uXY, uX2) { + const delta = uX2 - uX * uX, slope = Math.abs(delta) < 1e-24 ? 0 : (uXY - uX * uY) / delta, intercept = uY - slope * uX; + return [intercept, slope]; } - function exponential() { - var y = function (d) { return d[1]; }, x = function (d) { return d[0]; }, domain; - var exponentialRegression = function (data) { - var n = 0, Y = 0, YL = 0, XY = 0, XYL = 0, X2Y = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; - visitPoints(data, x, y, function (dx, dy) { - var ly = Math.log(dy), xy = dx * dy; - ++n; - Y += (dy - Y) / n; - XY += (xy - XY) / n; - X2Y += (dx * xy - X2Y) / n; - YL += (dy * ly - YL) / n; - XYL += (xy * ly - XYL) / n; - if (!domain) { - if (dx < xmin) - xmin = dx; - if (dx > xmax) - xmax = dx; - } - }); - var _a = ols(XY / Y, YL / Y, XYL / Y, X2Y / Y), a = _a[0], b = _a[1]; - a = Math.exp(a); - var fn = function (xx) { return a * Math.exp(b * xx); }; - var out = interpose(xmin, xmax, fn); - out.a = a; - out.b = b; - out.predict = fn; - out.rSquared = determination(data, x, y, Y, fn); - return out; - }; - exponentialRegression.domain = function (arr) { - if (!arguments.length) - return domain; - domain = arr; - return exponentialRegression; - }; - exponentialRegression.x = function (fn) { - if (!arguments.length) - return x; - x = fn; - return exponentialRegression; - }; - exponentialRegression.y = function (fn) { - if (!arguments.length) - return y; - y = fn; - return exponentialRegression; - }; - return exponentialRegression; + function exponential() { + let y = (d) => d[1], x = (d) => d[0], domain; + const exponentialRegression = function (data) { + let n = 0, Y = 0, YL = 0, XY = 0, XYL = 0, X2Y = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; + visitPoints(data, x, y, (dx, dy) => { + const ly = Math.log(dy), xy = dx * dy; + ++n; + Y += (dy - Y) / n; + XY += (xy - XY) / n; + X2Y += (dx * xy - X2Y) / n; + YL += (dy * ly - YL) / n; + XYL += (xy * ly - XYL) / n; + if (!domain) { + if (dx < xmin) + xmin = dx; + if (dx > xmax) + xmax = dx; + } + }); + let [a, b] = ols(XY / Y, YL / Y, XYL / Y, X2Y / Y); + a = Math.exp(a); + const fn = (xx) => a * Math.exp(b * xx); + const out = interpose(xmin, xmax, fn); + out.a = a; + out.b = b; + out.predict = fn; + out.rSquared = determination(data, x, y, Y, fn); + return out; + }; + exponentialRegression.domain = function (arr) { + if (!arguments.length) + return domain; + domain = arr; + return exponentialRegression; + }; + exponentialRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return exponentialRegression; + }; + exponentialRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return exponentialRegression; + }; + return exponentialRegression; } - function linear() { - var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, domain; - var linearRegression = function (data) { - var n = 0, X = 0, // sum of x - Y = 0, // sum of y - XY = 0, // sum of x*y - X2 = 0, // sum of x*x - xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; - visitPoints(data, x, y, function (dx, dy) { - ++n; - X += (dx - X) / n; - Y += (dy - Y) / n; - XY += (dx * dy - XY) / n; - X2 += (dx * dx - X2) / n; - if (!domain) { - if (dx < xmin) - xmin = dx; - if (dx > xmax) - xmax = dx; - } - }); - var _a = ols(X, Y, XY, X2), intercept = _a[0], slope = _a[1]; - var fn = function (xx) { return slope * xx + intercept; }; - var out = [[xmin, fn(xmin)], [xmax, fn(xmax)]]; - out.a = slope; - out.b = intercept; - out.predict = fn; - out.rSquared = determination(data, x, y, Y, fn); - return out; - }; - linearRegression.domain = function (arr) { - if (!arguments.length) - return domain; - domain = arr; - return linearRegression; - }; - linearRegression.x = function (fn) { - if (!arguments.length) - return x; - x = fn; - return linearRegression; - }; - linearRegression.y = function (fn) { - if (!arguments.length) - return y; - y = fn; - return linearRegression; - }; - return linearRegression; + function linear() { + let x = (d) => d[0], y = (d) => d[1], domain; + const linearRegression = function (data) { + let n = 0, X = 0, // sum of x + Y = 0, // sum of y + XY = 0, // sum of x*y + X2 = 0, // sum of x*x + xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; + visitPoints(data, x, y, (dx, dy) => { + ++n; + X += (dx - X) / n; + Y += (dy - Y) / n; + XY += (dx * dy - XY) / n; + X2 += (dx * dx - X2) / n; + if (!domain) { + if (dx < xmin) + xmin = dx; + if (dx > xmax) + xmax = dx; + } + }); + const [intercept, slope] = ols(X, Y, XY, X2); + const fn = (xx) => slope * xx + intercept; + const out = [[xmin, fn(xmin)], [xmax, fn(xmax)]]; + out.a = slope; + out.b = intercept; + out.predict = fn; + out.rSquared = determination(data, x, y, Y, fn); + return out; + }; + linearRegression.domain = function (arr) { + if (!arguments.length) + return domain; + domain = arr; + return linearRegression; + }; + linearRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return linearRegression; + }; + linearRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return linearRegression; + }; + return linearRegression; } - /** - * Returns the median value of an array of numbers. - */ - function median(arr) { - arr.sort(function (a, b) { return a - b; }); - var i = arr.length / 2; - return i % 1 === 0 ? (arr[i - 1] + arr[i]) / 2 : arr[Math.floor(i)]; + /** + * Returns the median value of an array of numbers. + */ + function median(arr) { + arr.sort((a, b) => a - b); + var i = arr.length / 2; + return i % 1 === 0 ? (arr[i - 1] + arr[i]) / 2 : arr[Math.floor(i)]; } - // Adapted from science.js by Jason Davies - var maxiters = 2, epsilon = 1e-12; - function loess() { - var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, bandwidth = 0.3; - var loessRegression = function loessRegression(data) { - var _a = points(data, function (dd) { return x(dd); }, function (dd) { return y(dd); }, true), xv = _a[0], yv = _a[1], ux = _a[2], uy = _a[3]; - var n = xv.length; - var bw = Math.max(2, ~~(bandwidth * n)); // # of nearest neighbors - var yhat = new Float64Array(n); - var residuals = new Float64Array(n); - var robustWeights = new Float64Array(n).fill(1); - for (var iter = -1; ++iter <= maxiters;) { - var interval = [0, bw - 1]; - for (var i = 0; i < n; ++i) { - var dx = xv[i]; - var i0 = interval[0]; - var i1 = interval[1]; - var edge = (dx - xv[i0]) > (xv[i1] - dx) ? i0 : i1; - var W = 0, X = 0, Y = 0, XY = 0, X2 = 0; - var denom = 1 / Math.abs(xv[edge] - dx || 1); - for (var k = i0; k <= i1; ++k) { - var xk = xv[k]; - var yk = yv[k]; - var w = tricube(Math.abs(dx - xk) * denom) * robustWeights[k]; - var xkw = xk * w; - W += w; - X += xkw; - Y += yk * w; - XY += yk * xkw; - X2 += xk * xkw; - } - // Linear regression fit - var _b = ols(X / W, Y / W, XY / W, X2 / W), a = _b[0], b = _b[1]; - yhat[i] = a + b * dx; - residuals[i] = Math.abs(yv[i] - yhat[i]); - updateInterval(xv, i + 1, interval); - } - if (iter === maxiters) { - break; - } - var medianResidual = median(residuals); - if (Math.abs(medianResidual) < epsilon) - break; - for (var i = 0, arg = void 0, w = void 0; i < n; ++i) { - arg = residuals[i] / (6 * medianResidual); - // Default to epsilon (rather than zero) for large deviations - // Keeping weights tiny but non-zero prevents singularites - robustWeights[i] = (arg >= 1) ? epsilon : ((w = 1 - arg * arg) * w); - } - } - return output(xv, yhat, ux, uy); - }; - loessRegression.bandwidth = function (bw) { - if (!arguments.length) - return bandwidth; - bandwidth = bw; - return loessRegression; - }; - loessRegression.x = function (fn) { - if (!arguments.length) - return x; - x = fn; - return loessRegression; - }; - loessRegression.y = function (fn) { - if (!arguments.length) - return y; - y = fn; - return loessRegression; - }; - return loessRegression; - } - // Weighting kernel for local regression - function tricube(x) { - return (x = 1 - x * x * x) * x * x; - } - // Advance sliding window interval of nearest neighbors - function updateInterval(xv, i, interval) { - var val = xv[i], left = interval[0], right = interval[1] + 1; - if (right >= xv.length) - return; - // Step right if distance to new right edge is <= distance to old left edge - // Step when distance is equal to ensure movement over duplicate x values - while (i > left && (xv[right] - val) <= (val - xv[left])) { - interval[0] = ++left; - interval[1] = right; - ++right; - } - } - // Generate smoothed output points - // Average points with repeated x values - function output(xv, yhat, ux, uy) { - var n = xv.length, out = []; - var i = 0, cnt = 0, prev = [], v; - for (; i < n; ++i) { - v = xv[i] + ux; - if (prev[0] === v) { - // Average output values via online update - prev[1] += (yhat[i] - prev[1]) / (++cnt); - } - else { - // Add new output point - cnt = 0; - prev[1] += uy; - prev = [v, yhat[i]]; - out.push(prev); - } - } - prev[1] += uy; - return out; + // Adapted from science.js by Jason Davies + const maxiters = 2, epsilon = 1e-12; + function loess() { + let x = (d) => d[0], y = (d) => d[1], bandwidth = 0.3; + const loessRegression = function loessRegression(data) { + const [xv, yv, ux, uy] = points(data, (dd) => x(dd), (dd) => y(dd), true); + const n = xv.length; + const bw = Math.max(2, ~~(bandwidth * n)); // # of nearest neighbors + const yhat = new Float64Array(n); + const residuals = new Float64Array(n); + const robustWeights = new Float64Array(n).fill(1); + for (let iter = -1; ++iter <= maxiters;) { + const interval = [0, bw - 1]; + for (let i = 0; i < n; ++i) { + const dx = xv[i]; + const i0 = interval[0]; + const i1 = interval[1]; + const edge = (dx - xv[i0]) > (xv[i1] - dx) ? i0 : i1; + let W = 0, X = 0, Y = 0, XY = 0, X2 = 0; + const denom = 1 / Math.abs(xv[edge] - dx || 1); + for (let k = i0; k <= i1; ++k) { + const xk = xv[k]; + const yk = yv[k]; + const w = tricube(Math.abs(dx - xk) * denom) * robustWeights[k]; + const xkw = xk * w; + W += w; + X += xkw; + Y += yk * w; + XY += yk * xkw; + X2 += xk * xkw; + } + // Linear regression fit + const [a, b] = ols(X / W, Y / W, XY / W, X2 / W); + yhat[i] = a + b * dx; + residuals[i] = Math.abs(yv[i] - yhat[i]); + updateInterval(xv, i + 1, interval); + } + if (iter === maxiters) { + break; + } + const medianResidual = median(residuals); + if (Math.abs(medianResidual) < epsilon) + break; + for (let i = 0, arg, w; i < n; ++i) { + arg = residuals[i] / (6 * medianResidual); + // Default to epsilon (rather than zero) for large deviations + // Keeping weights tiny but non-zero prevents singularites + robustWeights[i] = (arg >= 1) ? epsilon : ((w = 1 - arg * arg) * w); + } + } + return output(xv, yhat, ux, uy); + }; + loessRegression.bandwidth = function (bw) { + if (!arguments.length) + return bandwidth; + bandwidth = bw; + return loessRegression; + }; + loessRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return loessRegression; + }; + loessRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return loessRegression; + }; + return loessRegression; + } + // Weighting kernel for local regression + function tricube(x) { + return (x = 1 - x * x * x) * x * x; + } + // Advance sliding window interval of nearest neighbors + function updateInterval(xv, i, interval) { + let val = xv[i], left = interval[0], right = interval[1] + 1; + if (right >= xv.length) + return; + // Step right if distance to new right edge is <= distance to old left edge + // Step when distance is equal to ensure movement over duplicate x values + while (i > left && (xv[right] - val) <= (val - xv[left])) { + interval[0] = ++left; + interval[1] = right; + ++right; + } + } + // Generate smoothed output points + // Average points with repeated x values + function output(xv, yhat, ux, uy) { + const n = xv.length, out = []; + let i = 0, cnt = 0, prev = [], v; + for (; i < n; ++i) { + v = xv[i] + ux; + if (prev[0] === v) { + // Average output values via online update + prev[1] += (yhat[i] - prev[1]) / (++cnt); + } + else { + // Add new output point + cnt = 0; + prev[1] += uy; + prev = [v, yhat[i]]; + out.push(prev); + } + } + prev[1] += uy; + return out; } - function logarithmic() { - var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, base = Math.E, domain; - var logarithmicRegression = function (data) { - var n = 0, X = 0, Y = 0, XY = 0, X2 = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity, lb = Math.log(base); - visitPoints(data, x, y, function (dx, dy) { - var lx = Math.log(dx) / lb; - ++n; - X += (lx - X) / n; - Y += (dy - Y) / n; - XY += (lx * dy - XY) / n; - X2 += (lx * lx - X2) / n; - if (!domain) { - if (dx < xmin) - xmin = dx; - if (dx > xmax) - xmax = dx; - } - }); - var _a = ols(X, Y, XY, X2), intercept = _a[0], slope = _a[1]; - var fn = function (xx) { return slope * Math.log(xx) / lb + intercept; }; - var out = interpose(xmin, xmax, fn); - out.a = slope; - out.b = intercept; - out.predict = fn; - out.rSquared = determination(data, x, y, Y, fn); - return out; - }; - logarithmicRegression.domain = function (arr) { - if (!arguments.length) - return domain; - domain = arr; - return logarithmicRegression; - }; - logarithmicRegression.x = function (fn) { - if (!arguments.length) - return x; - x = fn; - return logarithmicRegression; - }; - logarithmicRegression.y = function (fn) { - if (!arguments.length) - return y; - y = fn; - return logarithmicRegression; - }; - logarithmicRegression.base = function (b) { - if (!arguments.length) - return base; - base = b; - return logarithmicRegression; - }; - return logarithmicRegression; + function logarithmic() { + let x = (d) => d[0], y = (d) => d[1], base = Math.E, domain; + const logarithmicRegression = function (data) { + let n = 0, X = 0, Y = 0, XY = 0, X2 = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity, lb = Math.log(base); + visitPoints(data, x, y, (dx, dy) => { + const lx = Math.log(dx) / lb; + ++n; + X += (lx - X) / n; + Y += (dy - Y) / n; + XY += (lx * dy - XY) / n; + X2 += (lx * lx - X2) / n; + if (!domain) { + if (dx < xmin) + xmin = dx; + if (dx > xmax) + xmax = dx; + } + }); + const [intercept, slope] = ols(X, Y, XY, X2); + const fn = (xx) => slope * Math.log(xx) / lb + intercept; + const out = interpose(xmin, xmax, fn); + out.a = slope; + out.b = intercept; + out.predict = fn; + out.rSquared = determination(data, x, y, Y, fn); + return out; + }; + logarithmicRegression.domain = function (arr) { + if (!arguments.length) + return domain; + domain = arr; + return logarithmicRegression; + }; + logarithmicRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return logarithmicRegression; + }; + logarithmicRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return logarithmicRegression; + }; + logarithmicRegression.base = function (b) { + if (!arguments.length) + return base; + base = b; + return logarithmicRegression; + }; + return logarithmicRegression; } - function quadratic() { - var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, domain; - var quadraticRegression = function quadraticRegression(data) { - var _a = points(data, function (dd) { return x(dd); }, function (dd) { return y(dd); }), xv = _a[0], yv = _a[1], ux = _a[2], uy = _a[3]; - var n = xv.length; - var X2 = 0, X3 = 0, X4 = 0, XY = 0, X2Y = 0, i, dx, dy, x2; - for (i = 0; i < n;) { - dx = xv[i]; - dy = yv[i++]; - x2 = dx * dx; - X2 += (x2 - X2) / i; - X3 += ((x2 * dx) - X3) / i; - X4 += ((x2 * x2) - X4) / i; - XY += ((dx * dy) - XY) / i; - X2Y += ((x2 * dy) - X2Y) / i; - } - var Y = 0, n0 = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; - visitPoints(data, x, y, function (dx2, dy2) { - n0++; - Y += (dy2 - Y) / n0; - if (!domain) { - if (dx2 < xmin) - xmin = dx2; - if (dx2 > xmax) - xmax = dx2; - } - }); - var X2X2 = X4 - (X2 * X2); - var d = (X2 * X2X2 - X3 * X3); - var a = (X2Y * X2 - XY * X3) / d; - var b = (XY * X2X2 - X2Y * X3) / d; - var c = -a * X2; - var fn = function (xx) { - var shifted = xx - ux; - return a * shifted * shifted + b * shifted + c + uy; - }; - var out = interpose(xmin, xmax, fn); - out.a = a; - out.b = b - 2 * a * ux; - out.c = c - b * ux + a * ux * ux + uy; - out.predict = fn; - out.rSquared = determination(data, x, y, Y, fn); - return out; - }; - quadraticRegression.domain = function (arr) { - if (!arguments.length) - return domain; - domain = arr; - return quadraticRegression; - }; - quadraticRegression.x = function (fn) { - if (!arguments.length) - return x; - x = fn; - return quadraticRegression; - }; - quadraticRegression.y = function (fn) { - if (!arguments.length) - return y; - y = fn; - return quadraticRegression; - }; - return quadraticRegression; + function quadratic() { + let x = (d) => d[0], y = (d) => d[1], domain; + const quadraticRegression = function quadraticRegression(data) { + const [xv, yv, ux, uy] = points(data, (dd) => x(dd), (dd) => y(dd)); + const n = xv.length; + let X2 = 0, X3 = 0, X4 = 0, XY = 0, X2Y = 0, i, dx, dy, x2; + for (i = 0; i < n;) { + dx = xv[i]; + dy = yv[i++]; + x2 = dx * dx; + X2 += (x2 - X2) / i; + X3 += ((x2 * dx) - X3) / i; + X4 += ((x2 * x2) - X4) / i; + XY += ((dx * dy) - XY) / i; + X2Y += ((x2 * dy) - X2Y) / i; + } + let Y = 0, n0 = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; + visitPoints(data, x, y, (dx2, dy2) => { + n0++; + Y += (dy2 - Y) / n0; + if (!domain) { + if (dx2 < xmin) + xmin = dx2; + if (dx2 > xmax) + xmax = dx2; + } + }); + const X2X2 = X4 - (X2 * X2); + const d = (X2 * X2X2 - X3 * X3); + const a = (X2Y * X2 - XY * X3) / d; + const b = (XY * X2X2 - X2Y * X3) / d; + const c = -a * X2; + const fn = (xx) => { + const shifted = xx - ux; + return a * shifted * shifted + b * shifted + c + uy; + }; + const out = interpose(xmin, xmax, fn); + out.a = a; + out.b = b - 2 * a * ux; + out.c = c - b * ux + a * ux * ux + uy; + out.predict = fn; + out.rSquared = determination(data, x, y, Y, fn); + return out; + }; + quadraticRegression.domain = function (arr) { + if (!arguments.length) + return domain; + domain = arr; + return quadraticRegression; + }; + quadraticRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return quadraticRegression; + }; + quadraticRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return quadraticRegression; + }; + return quadraticRegression; } - // Adapted from regression-js by Tom Alexander - function polynomial() { - var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, order = 3, domain; - var polynomialRegression = function polynomialRegression(data) { - // Shortcut for lower-order polynomials: - if (order === 1) { - var o = linear().x(x).y(y).domain(domain)(data); - var result = [o[0], o[1]]; - result.coefficients = [o.b, o.a]; - result.predict = o.predict; - result.rSquared = o.rSquared; - return result; - } - if (order === 2) { - var o = quadratic().x(x).y(y).domain(domain)(data); - var result = [o[0], o[1]]; - result.coefficients = [o.c, o.b, o.a]; - result.predict = o.predict; - result.rSquared = o.rSquared; - return result; - } - var _a = points(data, x, y), xv = _a[0], yv = _a[1], ux = _a[2], uy = _a[3]; - var n = xv.length; - var k = order + 1; - var lhs = []; - var rhs = []; - var Y = 0, n0 = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; - visitPoints(data, x, y, function (dx, dy) { - n0++; - Y += (dy - Y) / n0; - if (!domain) { - if (dx < xmin) - xmin = dx; - if (dx > xmax) - xmax = dx; - } - }); - // Build normal equations - for (var i = 0; i < k; i++) { - // LHS - var v = 0; - for (var l = 0; l < n; l++) { - v += Math.pow(xv[l], i) * yv[l]; - } - lhs.push(v); - // RHS - var c = new Float64Array(k); - for (var j = 0; j < k; j++) { - var v2 = 0; - for (var l = 0; l < n; l++) { - v2 += Math.pow(xv[l], i + j); - } - c[j] = v2; - } - rhs.push(c); - } - rhs.push(new Float64Array(lhs)); - var coef = gaussianElimination(rhs); - var fn = function (xx) { - var shifted = xx - ux; - var val = uy + coef[0]; - for (var i = 1; i < k; i++) { - val += coef[i] * Math.pow(shifted, i); - } - return val; - }; - var out = interpose(xmin, xmax, fn); - out.coefficients = uncenter(k, coef, -ux, uy); - out.predict = fn; - out.rSquared = determination(data, x, y, Y, fn); - return out; - }; - polynomialRegression.domain = function (arr) { - if (!arguments.length) - return domain; - domain = arr; - return polynomialRegression; - }; - polynomialRegression.x = function (fn) { - if (!arguments.length) - return x; - x = fn; - return polynomialRegression; - }; - polynomialRegression.y = function (fn) { - if (!arguments.length) - return y; - y = fn; - return polynomialRegression; - }; - polynomialRegression.order = function (n) { - if (!arguments.length) - return order; - order = n; - return polynomialRegression; - }; - return polynomialRegression; - } - function uncenter(k, a, x, y) { - var z = new Array(k).fill(0); - for (var i = k - 1; i >= 0; --i) { - var v = a[i]; - z[i] += v; - var c = 1; - for (var j = 1; j <= i; ++j) { - c *= (i + 1 - j) / j; // binomial coefficient - z[i - j] += v * Math.pow(x, j) * c; - } - } - // bias term - z[0] += y; - return z; - } - // Solve A * x = b using Gaussian elimination - function gaussianElimination(matrix) { - var n = matrix.length - 1; - var coef = new Array(n); - for (var i = 0; i < n; i++) { - var r = i; - // find pivot row - for (var j = i + 1; j < n; j++) { - if (Math.abs(matrix[i][j]) > Math.abs(matrix[i][r])) { - r = j; - } - } - // swap columns - for (var k = i; k < n + 1; k++) { - var t = matrix[k][i]; - matrix[k][i] = matrix[k][r]; - matrix[k][r] = t; - } - // reduce - for (var j = i + 1; j < n; j++) { - for (var k = n; k >= i; k--) { - matrix[k][j] -= (matrix[k][i] * matrix[i][j]) / matrix[i][i]; - } - } - } - for (var j = n - 1; j >= 0; j--) { - var t = 0; - for (var k = j + 1; k < n; k++) { - t += matrix[k][j] * coef[k]; - } - coef[j] = (matrix[n][j] - t) / matrix[j][j]; - } - return coef; + // Adapted from regression-js by Tom Alexander + function polynomial() { + let x = (d) => d[0], y = (d) => d[1], order = 3, domain; + const polynomialRegression = function polynomialRegression(data) { + // Shortcut for lower-order polynomials: + if (order === 1) { + const o = linear().x(x).y(y).domain(domain)(data); + const result = [o[0], o[1]]; + result.coefficients = [o.b, o.a]; + result.predict = o.predict; + result.rSquared = o.rSquared; + return result; + } + if (order === 2) { + const o = quadratic().x(x).y(y).domain(domain)(data); + const result = [o[0], o[1]]; + result.coefficients = [o.c, o.b, o.a]; + result.predict = o.predict; + result.rSquared = o.rSquared; + return result; + } + const [xv, yv, ux, uy] = points(data, x, y); + const n = xv.length; + const k = order + 1; + const lhs = []; + const rhs = []; + let Y = 0, n0 = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; + visitPoints(data, x, y, (dx, dy) => { + n0++; + Y += (dy - Y) / n0; + if (!domain) { + if (dx < xmin) + xmin = dx; + if (dx > xmax) + xmax = dx; + } + }); + // Build normal equations + for (let i = 0; i < k; i++) { + // LHS + let v = 0; + for (let l = 0; l < n; l++) { + v += Math.pow(xv[l], i) * yv[l]; + } + lhs.push(v); + // RHS + const c = new Float64Array(k); + for (let j = 0; j < k; j++) { + let v2 = 0; + for (let l = 0; l < n; l++) { + v2 += Math.pow(xv[l], i + j); + } + c[j] = v2; + } + rhs.push(c); + } + rhs.push(new Float64Array(lhs)); + const coef = gaussianElimination(rhs); + const fn = (xx) => { + let shifted = xx - ux; + let val = uy + coef[0]; + for (let i = 1; i < k; i++) { + val += coef[i] * Math.pow(shifted, i); + } + return val; + }; + const out = interpose(xmin, xmax, fn); + out.coefficients = uncenter(k, coef, -ux, uy); + out.predict = fn; + out.rSquared = determination(data, x, y, Y, fn); + return out; + }; + polynomialRegression.domain = function (arr) { + if (!arguments.length) + return domain; + domain = arr; + return polynomialRegression; + }; + polynomialRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return polynomialRegression; + }; + polynomialRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return polynomialRegression; + }; + polynomialRegression.order = function (n) { + if (!arguments.length) + return order; + order = n; + return polynomialRegression; + }; + return polynomialRegression; + } + function uncenter(k, a, x, y) { + const z = new Array(k).fill(0); + for (let i = k - 1; i >= 0; --i) { + let v = a[i]; + z[i] += v; + let c = 1; + for (let j = 1; j <= i; ++j) { + c *= (i + 1 - j) / j; // binomial coefficient + z[i - j] += v * Math.pow(x, j) * c; + } + } + // bias term + z[0] += y; + return z; + } + // Solve A * x = b using Gaussian elimination + function gaussianElimination(matrix) { + const n = matrix.length - 1; + const coef = new Array(n); + for (let i = 0; i < n; i++) { + let r = i; + // find pivot row + for (let j = i + 1; j < n; j++) { + if (Math.abs(matrix[i][j]) > Math.abs(matrix[i][r])) { + r = j; + } + } + // swap columns + for (let k = i; k < n + 1; k++) { + const t = matrix[k][i]; + matrix[k][i] = matrix[k][r]; + matrix[k][r] = t; + } + // reduce + for (let j = i + 1; j < n; j++) { + for (let k = n; k >= i; k--) { + matrix[k][j] -= (matrix[k][i] * matrix[i][j]) / matrix[i][i]; + } + } + } + for (let j = n - 1; j >= 0; j--) { + let t = 0; + for (let k = j + 1; k < n; k++) { + t += matrix[k][j] * coef[k]; + } + coef[j] = (matrix[n][j] - t) / matrix[j][j]; + } + return coef; } - function power() { - var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, domain; - var powerRegression = function powerRegression(data) { - var n = 0, X = 0, Y = 0, XY = 0, X2 = 0, YS = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; - visitPoints(data, x, y, function (dx, dy) { - var lx = Math.log(dx), ly = Math.log(dy); - ++n; - X += (lx - X) / n; - Y += (ly - Y) / n; - XY += (lx * ly - XY) / n; - X2 += (lx * lx - X2) / n; - YS += (dy - YS) / n; - if (!domain) { - if (dx < xmin) - xmin = dx; - if (dx > xmax) - xmax = dx; - } - }); - var _a = ols(X, Y, XY, X2), a = _a[0], b = _a[1]; - a = Math.exp(a); - var fn = function (xx) { return a * Math.pow(xx, b); }; - var out = interpose(xmin, xmax, fn); - out.a = a; - out.b = b; - out.predict = fn; - out.rSquared = determination(data, x, y, YS, fn); - return out; - }; - powerRegression.domain = function (arr) { - if (!arguments.length) - return domain; - domain = arr; - return powerRegression; - }; - powerRegression.x = function (fn) { - if (!arguments.length) - return x; - x = fn; - return powerRegression; - }; - powerRegression.y = function (fn) { - if (!arguments.length) - return y; - y = fn; - return powerRegression; - }; - return powerRegression; + function power() { + let x = (d) => d[0], y = (d) => d[1], domain; + const powerRegression = function powerRegression(data) { + let n = 0, X = 0, Y = 0, XY = 0, X2 = 0, YS = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; + visitPoints(data, x, y, (dx, dy) => { + const lx = Math.log(dx), ly = Math.log(dy); + ++n; + X += (lx - X) / n; + Y += (ly - Y) / n; + XY += (lx * ly - XY) / n; + X2 += (lx * lx - X2) / n; + YS += (dy - YS) / n; + if (!domain) { + if (dx < xmin) + xmin = dx; + if (dx > xmax) + xmax = dx; + } + }); + let [a, b] = ols(X, Y, XY, X2); + a = Math.exp(a); + const fn = (xx) => a * Math.pow(xx, b); + const out = interpose(xmin, xmax, fn); + out.a = a; + out.b = b; + out.predict = fn; + out.rSquared = determination(data, x, y, YS, fn); + return out; + }; + powerRegression.domain = function (arr) { + if (!arguments.length) + return domain; + domain = arr; + return powerRegression; + }; + powerRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return powerRegression; + }; + powerRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return powerRegression; + }; + return powerRegression; } - function sigmoidal() { - var x = function (d) { return d[0]; }, y = function (d) { return d[1]; }, domain, maxIter = 2000, alpha = 1e-4; // learning rate - function sigmoidalRegression(data) { - var n = 0, Xmin = domain ? +domain[0] : Infinity, Xmax = domain ? +domain[1] : -Infinity, Ymin = Infinity, Ymax = -Infinity, sumY = 0; - // Gather data & track min/max for domain if not preset - visitPoints(data, x, y, function (dx, dy) { - n++; - sumY += dy; - if (!domain) { - if (dx < Xmin) - Xmin = dx; - if (dx > Xmax) - Xmax = dx; - } - if (dy < Ymin) - Ymin = dy; - if (dy > Ymax) - Ymax = dy; - }); - if (!domain && (Xmin === Infinity || Xmax === -Infinity)) { - Xmin = 0; - Xmax = 1; - } - // Initialize parameters - var A = Ymax - Ymin; // amplitude - var B = 1; // logistic slope - var C = Ymin; // baseline offset - var M = (Xmin + Xmax) / 2; // midpoint - // Predict function - function f(xx) { - return C + A / (1 + Math.exp(-B * (xx - M))); - } - var _loop_1 = function (iter) { - var dA = 0, dB = 0, dC = 0, dM = 0; - visitPoints(data, x, y, function (dx, dy) { - var yhat = f(dx); - var err = dy - yhat; - var ex = Math.exp(-B * (dx - M)); - var g = 1 / (1 + ex); // logistic - // partial derivatives - var df_dA = g; - var df_dC = 1; - var df_dB = A * g * (1 - g) * (dx - M); - // Note the negative sign for M: - var df_dM = -A * B * g * (1 - g); - var factor = -2 * err; - dA += factor * df_dA; - dB += factor * df_dB; - dC += factor * df_dC; - dM += factor * df_dM; - }); - A -= alpha * (dA / n); - B -= alpha * (dB / n); - C -= alpha * (dC / n); - M -= alpha * (dM / n); - }; - // Gradient Descent - for (var iter = 0; iter < maxIter; iter++) { - _loop_1(); - } - var predict = function (xx) { return C + A / (1 + Math.exp(-B * (xx - M))); }; - var out = interpose(Xmin, Xmax, predict); - out.A = A; - out.B = B; - out.C = C; - out.M = M; - out.predict = predict; - // R^2 - var meanY = sumY / n; - out.rSquared = determination(data, x, y, meanY, predict); - return out; - } - sigmoidalRegression.domain = function (arr) { - if (!arguments.length) - return domain; - domain = arr; - return sigmoidalRegression; - }; - sigmoidalRegression.x = function (fn) { - if (!arguments.length) - return x; - x = fn; - return sigmoidalRegression; - }; - sigmoidalRegression.y = function (fn) { - if (!arguments.length) - return y; - y = fn; - return sigmoidalRegression; - }; - return sigmoidalRegression; + function sigmoidal() { + let x = (d) => d[0], y = (d) => d[1], domain, maxIter = 2000, alpha = 1e-4; // learning rate + function sigmoidalRegression(data) { + let n = 0, Xmin = domain ? +domain[0] : Infinity, Xmax = domain ? +domain[1] : -Infinity, Ymin = Infinity, Ymax = -Infinity, sumY = 0; + // Gather data & track min/max for domain if not preset + visitPoints(data, x, y, (dx, dy) => { + n++; + sumY += dy; + if (!domain) { + if (dx < Xmin) + Xmin = dx; + if (dx > Xmax) + Xmax = dx; + } + if (dy < Ymin) + Ymin = dy; + if (dy > Ymax) + Ymax = dy; + }); + if (!domain && (Xmin === Infinity || Xmax === -Infinity)) { + Xmin = 0; + Xmax = 1; + } + // Initialize parameters + let A = Ymax - Ymin; // amplitude + let B = 1; // logistic slope + let C = Ymin; // baseline offset + let M = (Xmin + Xmax) / 2; // midpoint + // Predict function + function f(xx) { + return C + A / (1 + Math.exp(-B * (xx - M))); + } + // Gradient Descent + for (let iter = 0; iter < maxIter; iter++) { + let dA = 0, dB = 0, dC = 0, dM = 0; + visitPoints(data, x, y, (dx, dy) => { + const yhat = f(dx); + const err = dy - yhat; + const ex = Math.exp(-B * (dx - M)); + const g = 1 / (1 + ex); // logistic + // partial derivatives + const df_dA = g; + const df_dC = 1; + const df_dB = A * g * (1 - g) * (dx - M); + // Note the negative sign for M: + const df_dM = -A * B * g * (1 - g); + const factor = -2 * err; + dA += factor * df_dA; + dB += factor * df_dB; + dC += factor * df_dC; + dM += factor * df_dM; + }); + A -= alpha * (dA / n); + B -= alpha * (dB / n); + C -= alpha * (dC / n); + M -= alpha * (dM / n); + } + const predict = (xx) => C + A / (1 + Math.exp(-B * (xx - M))); + const out = interpose(Xmin, Xmax, predict); + out.A = A; + out.B = B; + out.C = C; + out.M = M; + out.predict = predict; + // R^2 + const meanY = sumY / n; + out.rSquared = determination(data, x, y, meanY, predict); + return out; + } + sigmoidalRegression.domain = function (arr) { + if (!arguments.length) + return domain; + domain = arr; + return sigmoidalRegression; + }; + sigmoidalRegression.x = function (fn) { + if (!arguments.length) + return x; + x = fn; + return sigmoidalRegression; + }; + sigmoidalRegression.y = function (fn) { + if (!arguments.length) + return y; + y = fn; + return sigmoidalRegression; + }; + return sigmoidalRegression; } exports.regressionExp = exponential; @@ -774,4 +771,4 @@ Object.defineProperty(exports, '__esModule', { value: true }); -}))); +})); diff --git a/dist/d3-regression.min.js b/dist/d3-regression.min.js deleted file mode 100644 index 1227620..0000000 --- a/dist/d3-regression.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(n,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports):"function"==typeof define&&define.amd?define(["exports"],r):(n=n||self,r(n.d3={}))}(this,function(n){"use strict";function r(n,r,t,e){n=n.filter(function(n,e){var u=r(n,e),o=t(n,e);return null!=u&&isFinite(u)&&null!=o&&isFinite(o)}),e&&n.sort(function(n,t){return r(n)-r(t)});for(var u,o,a,i=n.length,f=new Float64Array(i),c=new Float64Array(i),v=0,h=0,l=0;li&&(n.splice(a+1,0,l),t=!0)}return t}(f)&&c<1e4;);return f}function i(n,r,t,e){var u=e-n*n,o=Math.abs(u)<1e-24?0:(t-n*r)/u;return[r-o*n,o]}function f(){var n,r=function(n){return n[1]},u=function(n){return n[0]},o=function(o){var f=0,c=0,v=0,h=0,l=0,g=0,s=n?+n[0]:1/0,d=n?+n[1]:-1/0;t(o,u,r,function(r,t){var e=Math.log(t),u=r*t;++f,c+=(t-c)/f,h+=(u-h)/f,g+=(r*u-g)/f,v+=(t*e-v)/f,l+=(u*e-l)/f,n||(rd&&(d=r))});var p=i(h/c,v/c,l/c,g/c),M=p[0],y=p[1];M=Math.exp(M);var b=function(n){return M*Math.exp(y*n)},x=a(s,d,b);return x.a=M,x.b=y,x.predict=b,x.rSquared=e(o,u,r,c,b),x};return o.domain=function(r){return arguments.length?(n=r,o):n},o.x=function(n){return arguments.length?(u=n,o):u},o.y=function(n){return arguments.length?(r=n,o):r},o}function c(){var n,r=function(n){return n[0]},u=function(n){return n[1]},o=function(o){var a=0,f=0,c=0,v=0,h=0,l=n?+n[0]:1/0,g=n?+n[1]:-1/0;t(o,r,u,function(r,t){++a,f+=(r-f)/a,c+=(t-c)/a,v+=(r*t-v)/a,h+=(r*r-h)/a,n||(rg&&(g=r))});var s=i(f,c,v,h),d=s[0],p=s[1],M=function(n){return p*n+d},y=[[l,M(l)],[g,M(g)]];return y.a=p,y.b=d,y.predict=M,y.rSquared=e(o,r,u,c,M),y};return o.domain=function(r){return arguments.length?(n=r,o):n},o.x=function(n){return arguments.length?(r=n,o):r},o.y=function(n){return arguments.length?(u=n,o):u},o}function v(n){n.sort(function(n,r){return n-r});var r=n.length/2;return r%1==0?(n[r-1]+n[r])/2:n[Math.floor(r)]}function h(){var n=function(n){return n[0]},t=function(n){return n[1]},e=.3,u=function(u){for(var o=r(u,function(r){return n(r)},function(n){return t(n)},!0),a=o[0],f=o[1],c=o[2],h=o[3],d=a.length,p=Math.max(2,~~(e*d)),M=new Float64Array(d),y=new Float64Array(d),b=new Float64Array(d).fill(1),x=-1;++x<=m;){for(var w=[0,p-1],q=0;qa[L]-F?A:L,E=0,j=0,k=0,O=0,_=0,B=1/Math.abs(a[P]-F||1),C=A;C<=L;++C){var G=a[C],I=f[C],Q=l(Math.abs(F-G)*B)*b[C],z=G*Q;E+=Q,j+=z,k+=I*Q,O+=I*z,_+=G*z}var D=i(j/E,k/E,O/E,_/E),H=D[0],J=D[1];M[q]=H+J*F,y[q]=Math.abs(f[q]-M[q]),g(a,q+1,w)}if(x===m)break;var K=v(y);if(Math.abs(K)=1?S:(Q=1-N*N)*Q}return s(a,M,c,h)};return u.bandwidth=function(n){return arguments.length?(e=n,u):e},u.x=function(r){return arguments.length?(n=r,u):n},u.y=function(n){return arguments.length?(t=n,u):t},u}function l(n){return(n=1-n*n*n)*n*n}function g(n,r,t){var e=n[r],u=t[0],o=t[1]+1;if(!(o>=n.length))for(;r>u&&n[o]-e<=e-n[u];)t[0]=++u,t[1]=o,++o}function s(n,r,t,e){for(var u,o=n.length,a=[],i=0,f=0,c=[];id&&(d=r))});var M=i(v,h,l,g),y=M[0],b=M[1],x=function(n){return b*Math.log(n)/p+y},w=a(s,d,x);return w.a=b,w.b=y,w.predict=x,w.rSquared=e(f,r,u,h,x),w};return f.domain=function(r){return arguments.length?(n=r,f):n},f.x=function(n){return arguments.length?(r=n,f):r},f.y=function(n){return arguments.length?(u=n,f):u},f.base=function(n){return arguments.length?(o=n,f):o},f}function p(){var n,u=function(n){return n[0]},o=function(n){return n[1]},i=function(i){var f,c,v,h,l=r(i,function(n){return u(n)},function(n){return o(n)}),g=l[0],s=l[1],d=l[2],p=l[3],M=g.length,y=0,b=0,x=0,w=0,m=0;for(f=0;fA&&(A=r))});var L=x-y*y,P=y*L-b*b,E=(m*y-w*b)/P,j=(w*L-m*b)/P,k=-E*y,O=function(n){var r=n-d;return E*r*r+j*r+k+p},_=a(F,A,O);return _.a=E,_.b=j-2*E*d,_.c=k-j*d+E*d*d+p,_.predict=O,_.rSquared=e(i,u,o,S,O),_};return i.domain=function(r){return arguments.length?(n=r,i):n},i.x=function(n){return arguments.length?(u=n,i):u},i.y=function(n){return arguments.length?(o=n,i):o},i}function M(){var n,u=function(n){return n[0]},o=function(n){return n[1]},i=3,f=function(f){if(1===i){var v=c().x(u).y(o).domain(n)(f),h=[v[0],v[1]];return h.coefficients=[v.b,v.a],h.predict=v.predict,h.rSquared=v.rSquared,h}if(2===i){var v=p().x(u).y(o).domain(n)(f),h=[v[0],v[1]];return h.coefficients=[v.c,v.b,v.a],h.predict=v.predict,h.rSquared=v.rSquared,h}var l=r(f,u,o),g=l[0],s=l[1],d=l[2],M=l[3],x=g.length,w=i+1,m=[],S=[],q=0,F=0,A=n?+n[0]:1/0,L=n?+n[1]:-1/0;t(f,u,o,function(r,t){F++,q+=(t-q)/F,n||(rL&&(L=r))});for(var P=0;P=0;--o){var a=r[o];u[o]+=a;for(var i=1,f=1;f<=o;++f)i*=(o+1-f)/f,u[o-f]+=a*Math.pow(t,f)*i}return u[0]+=e,u}function b(n){for(var r=n.length-1,t=new Array(r),e=0;eMath.abs(n[e][u])&&(u=o);for(var a=e;a=e;a--)n[a][o]-=n[a][e]*n[e][o]/n[e][e]}for(var o=r-1;o>=0;o--){for(var i=0,a=o+1;ad&&(d=r))});var p=i(c,v,h,l),M=p[0],y=p[1];M=Math.exp(M);var b=function(n){return M*Math.pow(n,y)},x=a(s,d,b);return x.a=M,x.b=y,x.predict=b,x.rSquared=e(o,r,u,g,b),x};return o.domain=function(r){return arguments.length?(n=r,o):n},o.x=function(n){return arguments.length?(r=n,o):r},o.y=function(n){return arguments.length?(u=n,o):u},o}function w(){function n(n){function c(n){return y+p/(1+Math.exp(-M*(n-b)))}var v=0,h=r?+r[0]:1/0,l=r?+r[1]:-1/0,g=1/0,s=-1/0,d=0;t(n,u,o,function(n,t){v++,d+=t,r||(nl&&(l=n)),ts&&(s=t)}),r||h!==1/0&&l!==-1/0||(h=0,l=1);for(var p=s-g,M=1,y=g,b=(h+l)/2,x=0;x { - (data: T[]): ExponentialOutput; - domain(): Domain; - domain(arr: Domain): this; - x(): Accessor; - x(fn: Accessor): this; - y(): Accessor; - y(fn: Accessor): this; -} -export default function exponential(): ExponentialRegression; +import { PredictFunction, Domain, DataPoint, Accessor } from "./types"; +export type ExponentialOutput = [DataPoint, DataPoint] & { + a: number; + b: number; + predict: PredictFunction; + rSquared: number; +}; +export interface ExponentialRegression { + (data: T[]): ExponentialOutput; + domain(): Domain; + domain(arr: Domain): this; + x(): Accessor; + x(fn: Accessor): this; + y(): Accessor; + y(fn: Accessor): this; +} +export default function exponential(): ExponentialRegression; diff --git a/dist/src/linear.d.ts b/dist/src/linear.d.ts index 7857536..287ad23 100644 --- a/dist/src/linear.d.ts +++ b/dist/src/linear.d.ts @@ -1,17 +1,17 @@ -import { PredictFunction, Accessor, DataPoint, Domain } from "./types"; -export type LinearOutput = [DataPoint, DataPoint] & { - a: number; - b: number; - predict: PredictFunction; - rSquared: number; -}; -export interface LinearRegression { - (data: T[]): LinearOutput; - domain(): Domain; - domain(arr: Domain): this; - x(): Accessor; - x(fn: Accessor): this; - y(): Accessor; - y(fn: Accessor): this; -} -export default function linear(): LinearRegression; +import { PredictFunction, Accessor, DataPoint, Domain } from "./types"; +export type LinearOutput = [DataPoint, DataPoint] & { + a: number; + b: number; + predict: PredictFunction; + rSquared: number; +}; +export interface LinearRegression { + (data: T[]): LinearOutput; + domain(): Domain; + domain(arr: Domain): this; + x(): Accessor; + x(fn: Accessor): this; + y(): Accessor; + y(fn: Accessor): this; +} +export default function linear(): LinearRegression; diff --git a/dist/src/loess.d.ts b/dist/src/loess.d.ts index ec2f0e6..eb2c8a6 100644 --- a/dist/src/loess.d.ts +++ b/dist/src/loess.d.ts @@ -1,11 +1,11 @@ -import { Accessor, DataPoint } from "./types"; -export interface LoessRegression { - (data: T[]): DataPoint[]; - bandwidth(): number; - bandwidth(bw: number): this; - x(): Accessor; - x(fn: Accessor): this; - y(): Accessor; - y(fn: Accessor): this; -} -export default function loess(): LoessRegression; +import { Accessor, DataPoint } from "./types"; +export interface LoessRegression { + (data: T[]): DataPoint[]; + bandwidth(): number; + bandwidth(bw: number): this; + x(): Accessor; + x(fn: Accessor): this; + y(): Accessor; + y(fn: Accessor): this; +} +export default function loess(): LoessRegression; diff --git a/dist/src/logarithmic.d.ts b/dist/src/logarithmic.d.ts index 1420628..3f73c70 100644 --- a/dist/src/logarithmic.d.ts +++ b/dist/src/logarithmic.d.ts @@ -1,20 +1,20 @@ -import { PredictFunction, DataPoint, Accessor, Domain } from "./types"; -type LogarithmicOutput = [DataPoint, DataPoint] & { - a: number; - b: number; - predict: PredictFunction; - rSquared: number; -}; -export interface LogarithmicRegression { - (data: T[]): LogarithmicOutput; - domain(): Domain; - domain(arr: Domain): this; - x(): Accessor; - x(fn: Accessor): this; - y(): Accessor; - y(fn: Accessor): this; - base(): number; - base(b: number): this; -} -export default function logarithmic(): LogarithmicRegression; -export {}; +import { PredictFunction, DataPoint, Accessor, Domain } from "./types"; +type LogarithmicOutput = [DataPoint, DataPoint] & { + a: number; + b: number; + predict: PredictFunction; + rSquared: number; +}; +export interface LogarithmicRegression { + (data: T[]): LogarithmicOutput; + domain(): Domain; + domain(arr: Domain): this; + x(): Accessor; + x(fn: Accessor): this; + y(): Accessor; + y(fn: Accessor): this; + base(): number; + base(b: number): this; +} +export default function logarithmic(): LogarithmicRegression; +export {}; diff --git a/dist/src/polynomial.d.ts b/dist/src/polynomial.d.ts index b32400a..4f27312 100644 --- a/dist/src/polynomial.d.ts +++ b/dist/src/polynomial.d.ts @@ -1,18 +1,18 @@ -import { PredictFunction, Accessor, DataPoint, Domain } from "./types"; -export type PolynomialOutput = [DataPoint, DataPoint] & { - coefficients: number[]; - predict: PredictFunction; - rSquared: number; -}; -export interface PolynomialRegression { - (data: T[]): PolynomialOutput; - domain(): Domain; - domain(domain?: Domain): this; - x(): Accessor; - x(x: Accessor): this; - y(): Accessor; - y(y: Accessor): this; - order(): number; - order(order: number): this; -} -export default function polynomial(): PolynomialRegression; +import { PredictFunction, Accessor, DataPoint, Domain } from "./types"; +export type PolynomialOutput = [DataPoint, DataPoint] & { + coefficients: number[]; + predict: PredictFunction; + rSquared: number; +}; +export interface PolynomialRegression { + (data: T[]): PolynomialOutput; + domain(): Domain; + domain(domain?: Domain): this; + x(): Accessor; + x(x: Accessor): this; + y(): Accessor; + y(y: Accessor): this; + order(): number; + order(order: number): this; +} +export default function polynomial(): PolynomialRegression; diff --git a/dist/src/power.d.ts b/dist/src/power.d.ts index c6b8f9a..3700a87 100644 --- a/dist/src/power.d.ts +++ b/dist/src/power.d.ts @@ -1,18 +1,18 @@ -import { PredictFunction, DataPoint, Accessor, Domain } from "./types"; -export type PowerOutput = [DataPoint, DataPoint] & { - a: number; - b: number; - predict: PredictFunction; - rSquared: number; -}; -interface PowerRegression { - (data: T[]): PowerOutput; - domain(): Domain; - domain(domain?: Domain): this; - x(): Accessor; - x(x: Accessor): this; - y(): Accessor; - y(y: Accessor): this; -} -export default function power(): PowerRegression; -export {}; +import { PredictFunction, DataPoint, Accessor, Domain } from "./types"; +export type PowerOutput = [DataPoint, DataPoint] & { + a: number; + b: number; + predict: PredictFunction; + rSquared: number; +}; +interface PowerRegression { + (data: T[]): PowerOutput; + domain(): Domain; + domain(domain?: Domain): this; + x(): Accessor; + x(x: Accessor): this; + y(): Accessor; + y(y: Accessor): this; +} +export default function power(): PowerRegression; +export {}; diff --git a/dist/src/quadratic.d.ts b/dist/src/quadratic.d.ts index 15c6567..cec95e8 100644 --- a/dist/src/quadratic.d.ts +++ b/dist/src/quadratic.d.ts @@ -1,19 +1,19 @@ -import { Accessor, DataPoint, PredictFunction, Domain } from "./types"; -export type QuadraticOutput = [DataPoint, DataPoint] & { - a: number; - b: number; - c: number; - predict: PredictFunction; - rSquared: number; -}; -interface QuadraticRegression { - (data: T[]): QuadraticOutput; - domain(): Domain; - domain(domain?: Domain): this; - x(): Accessor; - x(x: Accessor): this; - y(): Accessor; - y(y: Accessor): this; -} -export default function quadratic(): QuadraticRegression; -export {}; +import { Accessor, DataPoint, PredictFunction, Domain } from "./types"; +export type QuadraticOutput = [DataPoint, DataPoint] & { + a: number; + b: number; + c: number; + predict: PredictFunction; + rSquared: number; +}; +interface QuadraticRegression { + (data: T[]): QuadraticOutput; + domain(): Domain; + domain(domain?: Domain): this; + x(): Accessor; + x(x: Accessor): this; + y(): Accessor; + y(y: Accessor): this; +} +export default function quadratic(): QuadraticRegression; +export {}; diff --git a/dist/src/sigmoidal.d.ts b/dist/src/sigmoidal.d.ts index b7ffe6f..8207ef9 100644 --- a/dist/src/sigmoidal.d.ts +++ b/dist/src/sigmoidal.d.ts @@ -1,24 +1,24 @@ -import { PredictFunction, Domain, DataPoint, Accessor } from "./types"; -/** - * Sigmoidal (logistic) regression of the form: - * f(x) = C + A / (1 + exp(-B * (x - M))) - * where A, B, C, M are parameters found via gradient descent. - */ -export type SigmoidalOutput = [DataPoint, DataPoint] & { - A: number; - B: number; - C: number; - M: number; - predict: PredictFunction; - rSquared: number; -}; -export interface SigmoidalRegression { - (data: T[]): SigmoidalOutput; - domain(): Domain; - domain(domain: Domain): this; - x(): Accessor; - x(fn: Accessor): this; - y(): Accessor; - y(fn: Accessor): this; -} -export default function sigmoidal(): SigmoidalRegression; +import { PredictFunction, Domain, DataPoint, Accessor } from "./types"; +/** + * Sigmoidal (logistic) regression of the form: + * f(x) = C + A / (1 + exp(-B * (x - M))) + * where A, B, C, M are parameters found via gradient descent. + */ +export type SigmoidalOutput = [DataPoint, DataPoint] & { + A: number; + B: number; + C: number; + M: number; + predict: PredictFunction; + rSquared: number; +}; +export interface SigmoidalRegression { + (data: T[]): SigmoidalOutput; + domain(): Domain; + domain(domain: Domain): this; + x(): Accessor; + x(fn: Accessor): this; + y(): Accessor; + y(fn: Accessor): this; +} +export default function sigmoidal(): SigmoidalRegression; diff --git a/dist/src/types.d.ts b/dist/src/types.d.ts index f31848d..e0465ba 100644 --- a/dist/src/types.d.ts +++ b/dist/src/types.d.ts @@ -1,4 +1,4 @@ -export type DataPoint = [number, number]; -export type Accessor = (d: T, i?: number, data?: T[]) => number; -export type PredictFunction = (x: number) => number; -export type Domain = [number, number] | undefined; +export type DataPoint = [number, number]; +export type Accessor = (d: T, i?: number, data?: T[]) => number; +export type PredictFunction = (x: number) => number; +export type Domain = [number, number] | undefined; diff --git a/dist/src/utils/determination.d.ts b/dist/src/utils/determination.d.ts index 69bbed2..3e1cfe4 100644 --- a/dist/src/utils/determination.d.ts +++ b/dist/src/utils/determination.d.ts @@ -1,6 +1,6 @@ -import { Accessor, PredictFunction } from "../types"; -/** - * Given a dataset, x- and y-accessors, the mean center of the y-values (uY), - * and a prediction function, return the coefficient of determination, R^2. - */ -export declare function determination(data: T[], x: Accessor, y: Accessor, uY: number, predict: PredictFunction): number; +import { Accessor, PredictFunction } from "../types"; +/** + * Given a dataset, x- and y-accessors, the mean center of the y-values (uY), + * and a prediction function, return the coefficient of determination, R^2. + */ +export declare function determination(data: T[], x: Accessor, y: Accessor, uY: number, predict: PredictFunction): number; diff --git a/dist/src/utils/geometry.d.ts b/dist/src/utils/geometry.d.ts index b6f871f..2d22072 100644 --- a/dist/src/utils/geometry.d.ts +++ b/dist/src/utils/geometry.d.ts @@ -1,9 +1,9 @@ -import { DataPoint } from "../types"; -/** - * Returns the angle of a line in degrees. - */ -export declare function angle(line: [DataPoint, DataPoint]): number; -/** - * Returns the midpoint of a line. - */ -export declare function midpoint(line: [DataPoint, DataPoint]): DataPoint; +import { DataPoint } from "../types"; +/** + * Returns the angle of a line in degrees. + */ +export declare function angle(line: [DataPoint, DataPoint]): number; +/** + * Returns the midpoint of a line. + */ +export declare function midpoint(line: [DataPoint, DataPoint]): DataPoint; diff --git a/dist/src/utils/interpose.d.ts b/dist/src/utils/interpose.d.ts index 1c5dd07..0c228c6 100644 --- a/dist/src/utils/interpose.d.ts +++ b/dist/src/utils/interpose.d.ts @@ -1,6 +1,6 @@ -import { PredictFunction, DataPoint } from "../types"; -/** - * Given a start point (xmin), an end point (xmax), - * and a prediction function, returns a smooth line. - */ -export declare function interpose(xmin: number, xmax: number, predict: PredictFunction): [DataPoint, DataPoint]; +import { PredictFunction, DataPoint } from "../types"; +/** + * Given a start point (xmin), an end point (xmax), + * and a prediction function, returns a smooth line. + */ +export declare function interpose(xmin: number, xmax: number, predict: PredictFunction): [DataPoint, DataPoint]; diff --git a/dist/src/utils/median.d.ts b/dist/src/utils/median.d.ts index 0022487..f89c690 100644 --- a/dist/src/utils/median.d.ts +++ b/dist/src/utils/median.d.ts @@ -1,4 +1,4 @@ -/** - * Returns the median value of an array of numbers. - */ -export declare function median(arr: Float64Array): number; +/** + * Returns the median value of an array of numbers. + */ +export declare function median(arr: Float64Array): number; diff --git a/dist/src/utils/ols.d.ts b/dist/src/utils/ols.d.ts index fbca901..565d7b0 100644 --- a/dist/src/utils/ols.d.ts +++ b/dist/src/utils/ols.d.ts @@ -1,6 +1,6 @@ -/** - * Ordinary Least Squares from vega-statistics by Jeffrey Heer - * License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE - * Source: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/packages/vega-statistics/src/regression/ols.js - */ -export declare function ols(uX: number, uY: number, uXY: number, uX2: number): [number, number]; +/** + * Ordinary Least Squares from vega-statistics by Jeffrey Heer + * License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE + * Source: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/packages/vega-statistics/src/regression/ols.js + */ +export declare function ols(uX: number, uY: number, uXY: number, uX2: number): [number, number]; diff --git a/dist/src/utils/points.d.ts b/dist/src/utils/points.d.ts index f471c45..632ca08 100644 --- a/dist/src/utils/points.d.ts +++ b/dist/src/utils/points.d.ts @@ -1,11 +1,11 @@ -import { Accessor } from "../types"; -/** - * Adapted from vega-statistics by Jeffrey Heer - * License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE - * Source: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/packages/vega-statistics/src/regression/points.js - */ -export declare function points(data: T[], x: Accessor, y: Accessor, sort?: boolean): [Float64Array, Float64Array, number, number]; -/** - * Iterates over valid data points, invoking a callback for each. - */ -export declare function visitPoints(data: T[], x: Accessor, y: Accessor, cb: (dx: number, dy: number, index: number) => void): void; +import { Accessor } from "../types"; +/** + * Adapted from vega-statistics by Jeffrey Heer + * License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE + * Source: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/packages/vega-statistics/src/regression/points.js + */ +export declare function points(data: T[], x: Accessor, y: Accessor, sort?: boolean): [Float64Array, Float64Array, number, number]; +/** + * Iterates over valid data points, invoking a callback for each. + */ +export declare function visitPoints(data: T[], x: Accessor, y: Accessor, cb: (dx: number, dy: number, index: number) => void): void; diff --git a/package.json b/package.json index babb340..10d6ee3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "d3-regression", - "version": "1.3.10", + "name": "@gka/d3-regression", + "version": "1.3.10-pr48", "description": "Calculate statistical regressions for two-dimensional data", "keywords": [ "d3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..d61d2eb --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,3028 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + devDependencies: + '@babel/core': + specifier: ^7.4.4 + version: 7.28.4 + '@babel/preset-env': + specifier: ^7.4.4 + version: 7.28.3(@babel/core@7.28.4) + babel: + specifier: ^6.23.0 + version: 6.23.0 + package-preamble: + specifier: ^0.1.0 + version: 0.1.0 + rollup: + specifier: ^2.10.0 + version: 2.79.2 + rollup-plugin-babel: + specifier: ^4.4.0 + version: 4.4.0(@babel/core@7.28.4)(rollup@2.79.2) + rollup-plugin-commonjs: + specifier: ^10.1.0 + version: 10.1.0(rollup@2.79.2) + rollup-plugin-node-resolve: + specifier: ^5.2.0 + version: 5.2.0(rollup@2.79.2) + rollup-plugin-typescript2: + specifier: ^0.35.0 + version: 0.35.0(rollup@2.79.2)(typescript@4.9.5) + tape: + specifier: ^4.10.1 + version: 4.17.0 + typescript: + specifier: ^4.9.5 + version: 4.9.5 + uglify-js: + specifier: ^2.8.29 + version: 2.8.29 + +packages: + + '@babel/code-frame@7.27.1': + resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.28.4': + resolution: {integrity: sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.28.4': + resolution: {integrity: sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.28.3': + resolution: {integrity: sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-annotate-as-pure@7.27.3': + resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.27.2': + resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-create-class-features-plugin@7.28.3': + resolution: {integrity: sha512-V9f6ZFIYSLNEbuGA/92uOvYsGCJNsuA8ESZ4ldc09bWk/j8H8TKiPw8Mk1eG6olpnO0ALHJmYfZvF4MEE4gajg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-create-regexp-features-plugin@7.27.1': + resolution: {integrity: sha512-uVDC72XVf8UbrH5qQTc18Agb8emwjTiZrQE11Nv3CuBEZmVvTwwE9CBUEvHku06gQCAyYf8Nv6ja1IN+6LMbxQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-define-polyfill-provider@0.6.5': + resolution: {integrity: sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-member-expression-to-functions@7.27.1': + resolution: {integrity: sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.27.1': + resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.28.3': + resolution: {integrity: sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-optimise-call-expression@7.27.1': + resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-plugin-utils@7.27.1': + resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-remap-async-to-generator@7.27.1': + resolution: {integrity: sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-replace-supers@7.27.1': + resolution: {integrity: sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + resolution: {integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.27.1': + resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-wrap-function@7.28.3': + resolution: {integrity: sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.28.4': + resolution: {integrity: sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.28.4': + resolution: {integrity: sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.27.1': + resolution: {integrity: sha512-QPG3C9cCVRQLxAVwmefEmwdTanECuUBMQZ/ym5kiw3XKCGA7qkuQLcjWWHcrD/GKbn/WmJwaezfuuAOcyKlRPA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1': + resolution: {integrity: sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1': + resolution: {integrity: sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1': + resolution: {integrity: sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.13.0 + + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.3': + resolution: {integrity: sha512-b6YTX108evsvE4YgWyQ921ZAFFQm3Bn+CA3+ZXlNVnPhx+UfsVURoPjfGAPCjBgrqo30yX/C2nZGX96DxvR9Iw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2': + resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-assertions@7.27.1': + resolution: {integrity: sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-attributes@7.27.1': + resolution: {integrity: sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-unicode-sets-regex@7.18.6': + resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-arrow-functions@7.27.1': + resolution: {integrity: sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-async-generator-functions@7.28.0': + resolution: {integrity: sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-async-to-generator@7.27.1': + resolution: {integrity: sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-block-scoped-functions@7.27.1': + resolution: {integrity: sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-block-scoping@7.28.4': + resolution: {integrity: sha512-1yxmvN0MJHOhPVmAsmoW5liWwoILobu/d/ShymZmj867bAdxGbehIrew1DuLpw2Ukv+qDSSPQdYW1dLNE7t11A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-class-properties@7.27.1': + resolution: {integrity: sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-class-static-block@7.28.3': + resolution: {integrity: sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.12.0 + + '@babel/plugin-transform-classes@7.28.4': + resolution: {integrity: sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-computed-properties@7.27.1': + resolution: {integrity: sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-destructuring@7.28.0': + resolution: {integrity: sha512-v1nrSMBiKcodhsyJ4Gf+Z0U/yawmJDBOTpEB3mcQY52r9RIyPneGyAS/yM6seP/8I+mWI3elOMtT5dB8GJVs+A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-dotall-regex@7.27.1': + resolution: {integrity: sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-duplicate-keys@7.27.1': + resolution: {integrity: sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.27.1': + resolution: {integrity: sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-dynamic-import@7.27.1': + resolution: {integrity: sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-explicit-resource-management@7.28.0': + resolution: {integrity: sha512-K8nhUcn3f6iB+P3gwCv/no7OdzOZQcKchW6N389V6PD8NUWKZHzndOd9sPDVbMoBsbmjMqlB4L9fm+fEFNVlwQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-exponentiation-operator@7.27.1': + resolution: {integrity: sha512-uspvXnhHvGKf2r4VVtBpeFnuDWsJLQ6MF6lGJLC89jBR1uoVeqM416AZtTuhTezOfgHicpJQmoD5YUakO/YmXQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-export-namespace-from@7.27.1': + resolution: {integrity: sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-for-of@7.27.1': + resolution: {integrity: sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-function-name@7.27.1': + resolution: {integrity: sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-json-strings@7.27.1': + resolution: {integrity: sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-literals@7.27.1': + resolution: {integrity: sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-logical-assignment-operators@7.27.1': + resolution: {integrity: sha512-SJvDs5dXxiae4FbSL1aBJlG4wvl594N6YEVVn9e3JGulwioy6z3oPjx/sQBO3Y4NwUu5HNix6KJ3wBZoewcdbw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-member-expression-literals@7.27.1': + resolution: {integrity: sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-amd@7.27.1': + resolution: {integrity: sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-commonjs@7.27.1': + resolution: {integrity: sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-systemjs@7.27.1': + resolution: {integrity: sha512-w5N1XzsRbc0PQStASMksmUeqECuzKuTJer7kFagK8AXgpCMkeDMO5S+aaFb7A51ZYDF7XI34qsTX+fkHiIm5yA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-umd@7.27.1': + resolution: {integrity: sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-named-capturing-groups-regex@7.27.1': + resolution: {integrity: sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-new-target@7.27.1': + resolution: {integrity: sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-nullish-coalescing-operator@7.27.1': + resolution: {integrity: sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-numeric-separator@7.27.1': + resolution: {integrity: sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-object-rest-spread@7.28.4': + resolution: {integrity: sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-object-super@7.27.1': + resolution: {integrity: sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-optional-catch-binding@7.27.1': + resolution: {integrity: sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-optional-chaining@7.27.1': + resolution: {integrity: sha512-BQmKPPIuc8EkZgNKsv0X4bPmOoayeu4F1YCwx2/CfmDSXDbp7GnzlUH+/ul5VGfRg1AoFPsrIThlEBj2xb4CAg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-parameters@7.27.7': + resolution: {integrity: sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-private-methods@7.27.1': + resolution: {integrity: sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-private-property-in-object@7.27.1': + resolution: {integrity: sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-property-literals@7.27.1': + resolution: {integrity: sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-regenerator@7.28.4': + resolution: {integrity: sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-regexp-modifiers@7.27.1': + resolution: {integrity: sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-reserved-words@7.27.1': + resolution: {integrity: sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-shorthand-properties@7.27.1': + resolution: {integrity: sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-spread@7.27.1': + resolution: {integrity: sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-sticky-regex@7.27.1': + resolution: {integrity: sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-template-literals@7.27.1': + resolution: {integrity: sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typeof-symbol@7.27.1': + resolution: {integrity: sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-escapes@7.27.1': + resolution: {integrity: sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-property-regex@7.27.1': + resolution: {integrity: sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-regex@7.27.1': + resolution: {integrity: sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-sets-regex@7.27.1': + resolution: {integrity: sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/preset-env@7.28.3': + resolution: {integrity: sha512-ROiDcM+GbYVPYBOeCR6uBXKkQpBExLl8k9HO1ygXEyds39j+vCCsjmj7S8GOniZQlEs81QlkdJZe76IpLSiqpg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/preset-modules@0.1.6-no-external-plugins': + resolution: {integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==} + peerDependencies: + '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0 + + '@babel/template@7.27.2': + resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.28.4': + resolution: {integrity: sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.28.4': + resolution: {integrity: sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==} + engines: {node: '>=6.9.0'} + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@ljharb/resumer@0.0.1': + resolution: {integrity: sha512-skQiAOrCfO7vRTq53cxznMpks7wS1va95UCidALlOVWqvBAzwPVErwizDwoMqNVMEn1mDq0utxZd02eIrvF1lw==} + engines: {node: '>= 0.4'} + + '@ljharb/through@2.3.14': + resolution: {integrity: sha512-ajBvlKpWucBB17FuQYUShqpqy8GRgYEpJW0vWJbUu1CV9lWyrDCapy0lScU8T8Z6qn49sSwJB3+M+evYIdGg+A==} + engines: {node: '>= 0.4'} + + '@rollup/pluginutils@4.2.1': + resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==} + engines: {node: '>= 8.0.0'} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/node@24.5.2': + resolution: {integrity: sha512-FYxk1I7wPv3K2XBaoyH2cTnocQEu8AOZ60hPbsyukMPLv5/5qr7V1i8PLHdl6Zf87I+xZXFvPCXYjiTFq+YSDQ==} + + '@types/resolve@0.0.8': + resolution: {integrity: sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==} + + align-text@0.1.4: + resolution: {integrity: sha512-GrTZLRpmp6wIC2ztrWW9MjjTgSKccffgFagbNDOX95/dcjEcYZibYTeaOntySQLcdw1ztBoFkviiUvTMbb9MYg==} + engines: {node: '>=0.10.0'} + + array-buffer-byte-length@1.0.2: + resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} + engines: {node: '>= 0.4'} + + arraybuffer.prototype.slice@1.0.4: + resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} + engines: {node: '>= 0.4'} + + async-function@1.0.0: + resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} + engines: {node: '>= 0.4'} + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + babel-plugin-polyfill-corejs2@0.4.14: + resolution: {integrity: sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + babel-plugin-polyfill-corejs3@0.13.0: + resolution: {integrity: sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + babel-plugin-polyfill-regenerator@0.6.5: + resolution: {integrity: sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + babel@6.23.0: + resolution: {integrity: sha512-ZDcCaI8Vlct8PJ3DvmyqUz+5X2Ylz3ZuuItBe/74yXosk2dwyVo/aN7MCJ8HJzhnnJ+6yP4o+lDgG9MBe91DLA==} + deprecated: In 6.x, the babel package has been deprecated in favor of babel-cli. Check https://opencollective.com/babel to support the Babel maintainers + hasBin: true + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + baseline-browser-mapping@2.8.6: + resolution: {integrity: sha512-wrH5NNqren/QMtKUEEJf7z86YjfqW/2uw3IL3/xpqZUC95SSVIFXYQeeGjL6FT/X68IROu6RMehZQS5foy2BXw==} + hasBin: true + + brace-expansion@1.1.12: + resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} + + browserslist@4.26.2: + resolution: {integrity: sha512-ECFzp6uFOSB+dcZ5BK/IBaGWssbSYBHvuMeMt3MMFyhI0Z8SqGgEkBLARgpRH3hutIgPVsALcMwbDrJqPxQ65A==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + builtin-modules@3.3.0: + resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} + engines: {node: '>=6'} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bind@1.0.8: + resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + camelcase@1.2.1: + resolution: {integrity: sha512-wzLkDa4K/mzI1OSITC+DUyjgIl/ETNHE9QvYgy6J6Jvqyyz4C0Xfd+lQhb19sX2jMpZV4IssUn0VDVmglV+s4g==} + engines: {node: '>=0.10.0'} + + caniuse-lite@1.0.30001743: + resolution: {integrity: sha512-e6Ojr7RV14Un7dz6ASD0aZDmQPT/A+eZU+nuTNfjqmRrmkmQlnTNWH0SKmqagx9PeW87UVqapSurtAXifmtdmw==} + + center-align@0.1.3: + resolution: {integrity: sha512-Baz3aNe2gd2LP2qk5U+sDk/m4oSuwSDcBfayTCTBoWpfIGO5XFxPmjILQII4NGiZjD6DoDI6kf7gKaxkf7s3VQ==} + engines: {node: '>=0.10.0'} + + cliui@2.1.0: + resolution: {integrity: sha512-GIOYRizG+TGoc7Wgc1LiOTLare95R3mzKgoln+Q/lE4ceiYH19gUpl0l0Ffq4lJDEf3FxujMe6IBfOCs7pfqNA==} + + commondir@1.0.1: + resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + core-js-compat@3.45.1: + resolution: {integrity: sha512-tqTt5T4PzsMIZ430XGviK4vzYSoeNJ6CXODi6c/voxOT6IZqBht5/EKaSNnYiEjjRYxjVz7DQIsOsY0XNi8PIA==} + + data-view-buffer@1.0.2: + resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} + engines: {node: '>= 0.4'} + + data-view-byte-length@1.0.2: + resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} + engines: {node: '>= 0.4'} + + data-view-byte-offset@1.0.1: + resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} + engines: {node: '>= 0.4'} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decamelize@1.2.0: + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} + engines: {node: '>=0.10.0'} + + deep-equal@1.1.2: + resolution: {integrity: sha512-5tdhKF6DbU7iIzrIOa1AOUt39ZRm13cmL1cGEh//aqR8x9+tNfbywRf0n5FD/18OKMdo7DNEtrX2t22ZAkI+eg==} + engines: {node: '>= 0.4'} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + + defined@1.0.1: + resolution: {integrity: sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==} + + dotignore@0.1.2: + resolution: {integrity: sha512-UGGGWfSauusaVJC+8fgV+NVvBXkCTmVv7sk6nojDZZvuOUNGUy0Zk4UpHQD6EDjS0jpBwcACvH4eofvyzBcRDw==} + hasBin: true + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + electron-to-chromium@1.5.222: + resolution: {integrity: sha512-gA7psSwSwQRE60CEoLz6JBCQPIxNeuzB2nL8vE03GK/OHxlvykbLyeiumQy1iH5C2f3YbRAZpGCMT12a/9ih9w==} + + es-abstract@1.24.0: + resolution: {integrity: sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==} + engines: {node: '>= 0.4'} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + es-to-primitive@1.3.0: + resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} + engines: {node: '>= 0.4'} + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + estree-walker@0.6.1: + resolution: {integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==} + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + find-cache-dir@3.3.2: + resolution: {integrity: sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==} + engines: {node: '>=8'} + + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + + for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + engines: {node: '>= 0.4'} + + fs-extra@10.1.0: + resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} + engines: {node: '>=12'} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + function.prototype.name@1.1.8: + resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} + engines: {node: '>= 0.4'} + + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-symbol-description@1.1.0: + resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} + engines: {node: '>= 0.4'} + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported + + globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} + engines: {node: '>= 0.4'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + has-bigints@1.1.0: + resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} + engines: {node: '>= 0.4'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.2.0: + resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} + engines: {node: '>= 0.4'} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + has@1.0.4: + resolution: {integrity: sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==} + engines: {node: '>= 0.4.0'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + internal-slot@1.1.0: + resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} + engines: {node: '>= 0.4'} + + is-arguments@1.2.0: + resolution: {integrity: sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==} + engines: {node: '>= 0.4'} + + is-array-buffer@3.0.5: + resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} + engines: {node: '>= 0.4'} + + is-async-function@2.1.1: + resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} + engines: {node: '>= 0.4'} + + is-bigint@1.1.0: + resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} + engines: {node: '>= 0.4'} + + is-boolean-object@1.2.2: + resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} + engines: {node: '>= 0.4'} + + is-buffer@1.1.6: + resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + + is-data-view@1.0.2: + resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} + engines: {node: '>= 0.4'} + + is-date-object@1.1.0: + resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} + engines: {node: '>= 0.4'} + + is-finalizationregistry@1.1.1: + resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} + engines: {node: '>= 0.4'} + + is-generator-function@1.1.0: + resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==} + engines: {node: '>= 0.4'} + + is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} + + is-module@1.0.0: + resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} + + is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} + engines: {node: '>= 0.4'} + + is-number-object@1.1.1: + resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} + engines: {node: '>= 0.4'} + + is-reference@1.2.1: + resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} + + is-regex@1.1.4: + resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + engines: {node: '>= 0.4'} + + is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} + engines: {node: '>= 0.4'} + + is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} + engines: {node: '>= 0.4'} + + is-shared-array-buffer@1.0.4: + resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} + engines: {node: '>= 0.4'} + + is-string@1.1.1: + resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} + engines: {node: '>= 0.4'} + + is-symbol@1.1.1: + resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} + engines: {node: '>= 0.4'} + + is-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} + engines: {node: '>= 0.4'} + + is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} + + is-weakref@1.1.1: + resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} + engines: {node: '>= 0.4'} + + is-weakset@2.0.4: + resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} + engines: {node: '>= 0.4'} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + jsesc@3.0.2: + resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} + engines: {node: '>=6'} + hasBin: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsonfile@6.2.0: + resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} + + kind-of@3.2.2: + resolution: {integrity: sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==} + engines: {node: '>=0.10.0'} + + lazy-cache@1.0.4: + resolution: {integrity: sha512-RE2g0b5VGZsOCFOCgP7omTRYFqydmZkBwl5oNnQ1lDYC57uyO9KqNnNVxT7COSHTxrRCWVcAVOcbjk+tvh/rgQ==} + engines: {node: '>=0.10.0'} + + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + + lodash.debounce@4.0.8: + resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} + + longest@1.0.1: + resolution: {integrity: sha512-k+yt5n3l48JU4k8ftnKG6V7u32wyH2NfKzeMto9F/QRE0amxy/LayxwlvjjkZEIzqR+19IrtFO8p5kB9QaYUFg==} + engines: {node: '>=0.10.0'} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + magic-string@0.25.9: + resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} + + make-dir@3.1.0: + resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} + engines: {node: '>=8'} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + mock-property@1.0.3: + resolution: {integrity: sha512-2emPTb1reeLLYwHxyVx993iYyCHEiRRO+y8NFXFPL5kl5q14sgTK76cXyEKkeKCHeRw35SfdkUJ10Q1KfHuiIQ==} + engines: {node: '>= 0.4'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + node-releases@2.0.21: + resolution: {integrity: sha512-5b0pgg78U3hwXkCM8Z9b2FJdPZlr9Psr9V2gQPESdGHqbntyFJKFW4r5TeWGFzafGY3hzs1JC62VEQMbl1JFkw==} + + object-inspect@1.12.3: + resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + object-is@1.1.6: + resolution: {integrity: sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object.assign@4.1.7: + resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} + engines: {node: '>= 0.4'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + own-keys@1.0.1: + resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} + engines: {node: '>= 0.4'} + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + package-preamble@0.1.0: + resolution: {integrity: sha512-K9cr2xQAkPlq9fmKv1fzD1MXRTp2n5BLD/6Zj+QgIWiBYNl0wvasOavABoMXBtNmWBPVB4aKb8MqLL2FU18Nmg==} + hasBin: true + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + pkg-dir@4.2.0: + resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} + engines: {node: '>=8'} + + possible-typed-array-names@1.1.0: + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} + engines: {node: '>= 0.4'} + + reflect.getprototypeof@1.0.10: + resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} + engines: {node: '>= 0.4'} + + regenerate-unicode-properties@10.2.2: + resolution: {integrity: sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==} + engines: {node: '>=4'} + + regenerate@1.4.2: + resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} + + regexp.prototype.flags@1.5.4: + resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} + engines: {node: '>= 0.4'} + + regexpu-core@6.3.1: + resolution: {integrity: sha512-DzcswPr252wEr7Qz8AyAVbfyBDKLoYp6eRA1We2Fa9qirRFSdtkP5sHr3yglDKy2BbA0fd2T+j/CUSKes3FeVQ==} + engines: {node: '>=4'} + + regjsgen@0.8.0: + resolution: {integrity: sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==} + + regjsparser@0.12.0: + resolution: {integrity: sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==} + hasBin: true + + repeat-string@1.6.1: + resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} + engines: {node: '>=0.10'} + + resolve@1.22.10: + resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} + engines: {node: '>= 0.4'} + hasBin: true + + right-align@0.1.3: + resolution: {integrity: sha512-yqINtL/G7vs2v+dFIZmFUDbnVyFUJFKd6gK22Kgo6R4jfJGFtisKyncWDDULgjfqf4ASQuIQyjJ7XZ+3aWpsAg==} + engines: {node: '>=0.10.0'} + + rollup-plugin-babel@4.4.0: + resolution: {integrity: sha512-Lek/TYp1+7g7I+uMfJnnSJ7YWoD58ajo6Oarhlex7lvUce+RCKRuGRSgztDO3/MF/PuGKmUL5iTHKf208UNszw==} + deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-babel. + peerDependencies: + '@babel/core': 7 || ^7.0.0-rc.2 + rollup: '>=0.60.0 <3' + + rollup-plugin-commonjs@10.1.0: + resolution: {integrity: sha512-jlXbjZSQg8EIeAAvepNwhJj++qJWNJw1Cl0YnOqKtP5Djx+fFGkp3WRh+W0ASCaFG5w1jhmzDxgu3SJuVxPF4Q==} + deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-commonjs. + peerDependencies: + rollup: '>=1.12.0' + + rollup-plugin-node-resolve@5.2.0: + resolution: {integrity: sha512-jUlyaDXts7TW2CqQ4GaO5VJ4PwwaV8VUGA7+km3n6k6xtOEacf61u0VXwN80phY/evMcaS+9eIeJ9MOyDxt5Zw==} + deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-node-resolve. + peerDependencies: + rollup: '>=1.11.0' + + rollup-plugin-typescript2@0.35.0: + resolution: {integrity: sha512-szcIO9hPUx3PhQl91u4pfNAH2EKbtrXaES+m163xQVE5O1CC0ea6YZV/5woiDDW3CR9jF2CszPrKN+AFiND0bg==} + peerDependencies: + rollup: '>=1.26.3' + typescript: '>=2.4.0' + + rollup-pluginutils@2.8.2: + resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==} + + rollup@2.79.2: + resolution: {integrity: sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==} + engines: {node: '>=10.0.0'} + hasBin: true + + safe-array-concat@1.1.3: + resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} + engines: {node: '>=0.4'} + + safe-push-apply@1.0.0: + resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} + engines: {node: '>= 0.4'} + + safe-regex-test@1.1.0: + resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} + engines: {node: '>= 0.4'} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.7.2: + resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} + engines: {node: '>=10'} + hasBin: true + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + + set-proto@1.0.0: + resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} + engines: {node: '>= 0.4'} + + side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + + source-map@0.5.7: + resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} + engines: {node: '>=0.10.0'} + + sourcemap-codec@1.4.8: + resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} + deprecated: Please use @jridgewell/sourcemap-codec instead + + stop-iteration-iterator@1.1.0: + resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} + engines: {node: '>= 0.4'} + + string.prototype.trim@1.2.10: + resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} + engines: {node: '>= 0.4'} + + string.prototype.trimend@1.0.9: + resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} + engines: {node: '>= 0.4'} + + string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + tape@4.17.0: + resolution: {integrity: sha512-KCuXjYxCZ3ru40dmND+oCLsXyuA8hoseu2SS404Px5ouyS0A99v8X/mdiLqsR5MTAyamMBN7PRwt2Dv3+xGIxw==} + hasBin: true + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + typed-array-buffer@1.0.3: + resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} + engines: {node: '>= 0.4'} + + typed-array-byte-length@1.0.3: + resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} + engines: {node: '>= 0.4'} + + typed-array-byte-offset@1.0.4: + resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} + engines: {node: '>= 0.4'} + + typed-array-length@1.0.7: + resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} + engines: {node: '>= 0.4'} + + typescript@4.9.5: + resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} + engines: {node: '>=4.2.0'} + hasBin: true + + uglify-js@2.8.29: + resolution: {integrity: sha512-qLq/4y2pjcU3vhlhseXGGJ7VbFO4pBANu0kwl8VCa9KEI0V8VfZIx2Fy3w01iSTA/pGwKZSmu/+I4etLNDdt5w==} + engines: {node: '>=0.8.0'} + hasBin: true + + uglify-to-browserify@1.0.2: + resolution: {integrity: sha512-vb2s1lYx2xBtUgy+ta+b2J/GLVUR+wmpINwHePmPRhOsIVCG2wDzKJ0n14GslH1BifsqVzSOwQhRaCAsZ/nI4Q==} + + unbox-primitive@1.1.0: + resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} + engines: {node: '>= 0.4'} + + undici-types@7.12.0: + resolution: {integrity: sha512-goOacqME2GYyOZZfb5Lgtu+1IDmAlAEu5xnD3+xTzS10hT0vzpf0SPjkXwAw9Jm+4n/mQGDP3LO8CPbYROeBfQ==} + + unicode-canonical-property-names-ecmascript@2.0.1: + resolution: {integrity: sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==} + engines: {node: '>=4'} + + unicode-match-property-ecmascript@2.0.0: + resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} + engines: {node: '>=4'} + + unicode-match-property-value-ecmascript@2.2.1: + resolution: {integrity: sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==} + engines: {node: '>=4'} + + unicode-property-aliases-ecmascript@2.2.0: + resolution: {integrity: sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==} + engines: {node: '>=4'} + + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + + update-browserslist-db@1.1.3: + resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + which-boxed-primitive@1.1.1: + resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} + engines: {node: '>= 0.4'} + + which-builtin-type@1.2.1: + resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} + engines: {node: '>= 0.4'} + + which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} + + which-typed-array@1.1.19: + resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} + engines: {node: '>= 0.4'} + + window-size@0.1.0: + resolution: {integrity: sha512-1pTPQDKTdd61ozlKGNCjhNRd+KPmgLSGa3mZTHoOliaGcESD8G1PXhh7c1fgiPjVbNVfgy2Faw4BI8/m0cC8Mg==} + engines: {node: '>= 0.8.0'} + + wordwrap@0.0.2: + resolution: {integrity: sha512-xSBsCeh+g+dinoBv3GAOWM4LcVVO68wLXRanibtBSdUvkGWQRGeE9P7IwU9EmDDi4jA6L44lz15CGMwdw9N5+Q==} + engines: {node: '>=0.4.0'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yargs@3.10.0: + resolution: {integrity: sha512-QFzUah88GAGy9lyDKGBqZdkYApt63rCXYBGYnEP4xDJPXNqXXnBDACnbrXnViV6jRSqAePwrATi2i8mfYm4L1A==} + +snapshots: + + '@babel/code-frame@7.27.1': + dependencies: + '@babel/helper-validator-identifier': 7.27.1 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.28.4': {} + + '@babel/core@7.28.4': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.3 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.4) + '@babel/helpers': 7.28.4 + '@babel/parser': 7.28.4 + '@babel/template': 7.27.2 + '@babel/traverse': 7.28.4 + '@babel/types': 7.28.4 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.28.3': + dependencies: + '@babel/parser': 7.28.4 + '@babel/types': 7.28.4 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-annotate-as-pure@7.27.3': + dependencies: + '@babel/types': 7.28.4 + + '@babel/helper-compilation-targets@7.27.2': + dependencies: + '@babel/compat-data': 7.28.4 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.26.2 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-create-class-features-plugin@7.28.3(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-member-expression-to-functions': 7.27.1 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.4) + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/traverse': 7.28.4 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-create-regexp-features-plugin@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-annotate-as-pure': 7.27.3 + regexpu-core: 6.3.1 + semver: 6.3.1 + + '@babel/helper-define-polyfill-provider@0.6.5(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-plugin-utils': 7.27.1 + debug: 4.4.3 + lodash.debounce: 4.0.8 + resolve: 1.22.10 + transitivePeerDependencies: + - supports-color + + '@babel/helper-globals@7.28.0': {} + + '@babel/helper-member-expression-to-functions@7.27.1': + dependencies: + '@babel/traverse': 7.28.4 + '@babel/types': 7.28.4 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-imports@7.27.1': + dependencies: + '@babel/traverse': 7.28.4 + '@babel/types': 7.28.4 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + '@babel/traverse': 7.28.4 + transitivePeerDependencies: + - supports-color + + '@babel/helper-optimise-call-expression@7.27.1': + dependencies: + '@babel/types': 7.28.4 + + '@babel/helper-plugin-utils@7.27.1': {} + + '@babel/helper-remap-async-to-generator@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-wrap-function': 7.28.3 + '@babel/traverse': 7.28.4 + transitivePeerDependencies: + - supports-color + + '@babel/helper-replace-supers@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-member-expression-to-functions': 7.27.1 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/traverse': 7.28.4 + transitivePeerDependencies: + - supports-color + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + dependencies: + '@babel/traverse': 7.28.4 + '@babel/types': 7.28.4 + transitivePeerDependencies: + - supports-color + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.27.1': {} + + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helper-wrap-function@7.28.3': + dependencies: + '@babel/template': 7.27.2 + '@babel/traverse': 7.28.4 + '@babel/types': 7.28.4 + transitivePeerDependencies: + - supports-color + + '@babel/helpers@7.28.4': + dependencies: + '@babel/template': 7.27.2 + '@babel/types': 7.28.4 + + '@babel/parser@7.28.4': + dependencies: + '@babel/types': 7.28.4 + + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/traverse': 7.28.4 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/plugin-transform-optional-chaining': 7.27.1(@babel/core@7.28.4) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.3(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/traverse': 7.28.4 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + + '@babel/plugin-syntax-import-assertions@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.4) + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-async-generator-functions@7.28.0(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.28.4) + '@babel/traverse': 7.28.4 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-async-to-generator@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.28.4) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-block-scoped-functions@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-block-scoping@7.28.4(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-class-properties@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-create-class-features-plugin': 7.28.3(@babel/core@7.28.4) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-class-static-block@7.28.3(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-create-class-features-plugin': 7.28.3(@babel/core@7.28.4) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-classes@7.28.4(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-globals': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.4) + '@babel/traverse': 7.28.4 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-computed-properties@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/template': 7.27.2 + + '@babel/plugin-transform-destructuring@7.28.0(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/traverse': 7.28.4 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-dotall-regex@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.4) + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-duplicate-keys@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.4) + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-dynamic-import@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-explicit-resource-management@7.28.0(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-destructuring': 7.28.0(@babel/core@7.28.4) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-exponentiation-operator@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-export-namespace-from@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-for-of@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-function-name@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/traverse': 7.28.4 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-json-strings@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-literals@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-logical-assignment-operators@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-member-expression-literals@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-modules-amd@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.4) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-commonjs@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.4) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-systemjs@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.4) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + '@babel/traverse': 7.28.4 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-umd@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.4) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-named-capturing-groups-regex@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.4) + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-new-target@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-nullish-coalescing-operator@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-numeric-separator@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-object-rest-spread@7.28.4(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-destructuring': 7.28.0(@babel/core@7.28.4) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.28.4) + '@babel/traverse': 7.28.4 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-object-super@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.4) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-optional-catch-binding@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-optional-chaining@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-parameters@7.27.7(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-private-methods@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-create-class-features-plugin': 7.28.3(@babel/core@7.28.4) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-private-property-in-object@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-create-class-features-plugin': 7.28.3(@babel/core@7.28.4) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-property-literals@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-regenerator@7.28.4(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-regexp-modifiers@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.4) + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-reserved-words@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-shorthand-properties@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-spread@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-sticky-regex@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-template-literals@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-typeof-symbol@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-unicode-escapes@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-unicode-property-regex@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.4) + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-unicode-regex@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.4) + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-unicode-sets-regex@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.4) + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/preset-env@7.28.3(@babel/core@7.28.4)': + dependencies: + '@babel/compat-data': 7.28.4 + '@babel/core': 7.28.4 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-validator-option': 7.27.1 + '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.28.3(@babel/core@7.28.4) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.28.4) + '@babel/plugin-syntax-import-assertions': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.28.4) + '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-async-generator-functions': 7.28.0(@babel/core@7.28.4) + '@babel/plugin-transform-async-to-generator': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-block-scoped-functions': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-block-scoping': 7.28.4(@babel/core@7.28.4) + '@babel/plugin-transform-class-properties': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-class-static-block': 7.28.3(@babel/core@7.28.4) + '@babel/plugin-transform-classes': 7.28.4(@babel/core@7.28.4) + '@babel/plugin-transform-computed-properties': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-destructuring': 7.28.0(@babel/core@7.28.4) + '@babel/plugin-transform-dotall-regex': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-duplicate-keys': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-dynamic-import': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-explicit-resource-management': 7.28.0(@babel/core@7.28.4) + '@babel/plugin-transform-exponentiation-operator': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-export-namespace-from': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-for-of': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-function-name': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-json-strings': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-literals': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-logical-assignment-operators': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-member-expression-literals': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-modules-amd': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-modules-systemjs': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-modules-umd': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-named-capturing-groups-regex': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-new-target': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-nullish-coalescing-operator': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-numeric-separator': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-object-rest-spread': 7.28.4(@babel/core@7.28.4) + '@babel/plugin-transform-object-super': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-optional-catch-binding': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-optional-chaining': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.28.4) + '@babel/plugin-transform-private-methods': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-private-property-in-object': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-property-literals': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-regenerator': 7.28.4(@babel/core@7.28.4) + '@babel/plugin-transform-regexp-modifiers': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-reserved-words': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-spread': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-sticky-regex': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-typeof-symbol': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-unicode-escapes': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-unicode-property-regex': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-unicode-regex': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-unicode-sets-regex': 7.27.1(@babel/core@7.28.4) + '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.28.4) + babel-plugin-polyfill-corejs2: 0.4.14(@babel/core@7.28.4) + babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.28.4) + babel-plugin-polyfill-regenerator: 0.6.5(@babel/core@7.28.4) + core-js-compat: 3.45.1 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/types': 7.28.4 + esutils: 2.0.3 + + '@babel/template@7.27.2': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/parser': 7.28.4 + '@babel/types': 7.28.4 + + '@babel/traverse@7.28.4': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.3 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.28.4 + '@babel/template': 7.27.2 + '@babel/types': 7.28.4 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.28.4': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@ljharb/resumer@0.0.1': + dependencies: + '@ljharb/through': 2.3.14 + + '@ljharb/through@2.3.14': + dependencies: + call-bind: 1.0.8 + + '@rollup/pluginutils@4.2.1': + dependencies: + estree-walker: 2.0.2 + picomatch: 2.3.1 + + '@types/estree@1.0.8': {} + + '@types/node@24.5.2': + dependencies: + undici-types: 7.12.0 + + '@types/resolve@0.0.8': + dependencies: + '@types/node': 24.5.2 + + align-text@0.1.4: + dependencies: + kind-of: 3.2.2 + longest: 1.0.1 + repeat-string: 1.6.1 + + array-buffer-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + is-array-buffer: 3.0.5 + + arraybuffer.prototype.slice@1.0.4: + dependencies: + array-buffer-byte-length: 1.0.2 + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + is-array-buffer: 3.0.5 + + async-function@1.0.0: {} + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.1.0 + + babel-plugin-polyfill-corejs2@0.4.14(@babel/core@7.28.4): + dependencies: + '@babel/compat-data': 7.28.4 + '@babel/core': 7.28.4 + '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.4) + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + babel-plugin-polyfill-corejs3@0.13.0(@babel/core@7.28.4): + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.4) + core-js-compat: 3.45.1 + transitivePeerDependencies: + - supports-color + + babel-plugin-polyfill-regenerator@0.6.5(@babel/core@7.28.4): + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.4) + transitivePeerDependencies: + - supports-color + + babel@6.23.0: {} + + balanced-match@1.0.2: {} + + baseline-browser-mapping@2.8.6: {} + + brace-expansion@1.1.12: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + browserslist@4.26.2: + dependencies: + baseline-browser-mapping: 2.8.6 + caniuse-lite: 1.0.30001743 + electron-to-chromium: 1.5.222 + node-releases: 2.0.21 + update-browserslist-db: 1.1.3(browserslist@4.26.2) + + builtin-modules@3.3.0: {} + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bind@1.0.8: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + get-intrinsic: 1.3.0 + set-function-length: 1.2.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + camelcase@1.2.1: {} + + caniuse-lite@1.0.30001743: {} + + center-align@0.1.3: + dependencies: + align-text: 0.1.4 + lazy-cache: 1.0.4 + + cliui@2.1.0: + dependencies: + center-align: 0.1.3 + right-align: 0.1.3 + wordwrap: 0.0.2 + + commondir@1.0.1: {} + + concat-map@0.0.1: {} + + convert-source-map@2.0.0: {} + + core-js-compat@3.45.1: + dependencies: + browserslist: 4.26.2 + + data-view-buffer@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-offset@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + decamelize@1.2.0: {} + + deep-equal@1.1.2: + dependencies: + is-arguments: 1.2.0 + is-date-object: 1.1.0 + is-regex: 1.1.4 + object-is: 1.1.6 + object-keys: 1.1.1 + regexp.prototype.flags: 1.5.4 + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + defined@1.0.1: {} + + dotignore@0.1.2: + dependencies: + minimatch: 3.1.2 + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + electron-to-chromium@1.5.222: {} + + es-abstract@1.24.0: + dependencies: + array-buffer-byte-length: 1.0.2 + arraybuffer.prototype.slice: 1.0.4 + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.4 + data-view-buffer: 1.0.2 + data-view-byte-length: 1.0.2 + data-view-byte-offset: 1.0.1 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-set-tostringtag: 2.1.0 + es-to-primitive: 1.3.0 + function.prototype.name: 1.1.8 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + get-symbol-description: 1.1.0 + globalthis: 1.0.4 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + internal-slot: 1.1.0 + is-array-buffer: 3.0.5 + is-callable: 1.2.7 + is-data-view: 1.0.2 + is-negative-zero: 2.0.3 + is-regex: 1.2.1 + is-set: 2.0.3 + is-shared-array-buffer: 1.0.4 + is-string: 1.1.1 + is-typed-array: 1.1.15 + is-weakref: 1.1.1 + math-intrinsics: 1.1.0 + object-inspect: 1.13.4 + object-keys: 1.1.1 + object.assign: 4.1.7 + own-keys: 1.0.1 + regexp.prototype.flags: 1.5.4 + safe-array-concat: 1.1.3 + safe-push-apply: 1.0.0 + safe-regex-test: 1.1.0 + set-proto: 1.0.0 + stop-iteration-iterator: 1.1.0 + string.prototype.trim: 1.2.10 + string.prototype.trimend: 1.0.9 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.3 + typed-array-byte-length: 1.0.3 + typed-array-byte-offset: 1.0.4 + typed-array-length: 1.0.7 + unbox-primitive: 1.1.0 + which-typed-array: 1.1.19 + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + es-to-primitive@1.3.0: + dependencies: + is-callable: 1.2.7 + is-date-object: 1.1.0 + is-symbol: 1.1.1 + + escalade@3.2.0: {} + + estree-walker@0.6.1: {} + + estree-walker@2.0.2: {} + + esutils@2.0.3: {} + + find-cache-dir@3.3.2: + dependencies: + commondir: 1.0.1 + make-dir: 3.1.0 + pkg-dir: 4.2.0 + + find-up@4.1.0: + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + + for-each@0.3.5: + dependencies: + is-callable: 1.2.7 + + fs-extra@10.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.2.0 + universalify: 2.0.1 + + fs.realpath@1.0.0: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + function.prototype.name@1.1.8: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + functions-have-names: 1.2.3 + hasown: 2.0.2 + is-callable: 1.2.7 + + functions-have-names@1.2.3: {} + + gensync@1.0.0-beta.2: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + get-symbol-description@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + globalthis@1.0.4: + dependencies: + define-properties: 1.2.1 + gopd: 1.2.0 + + gopd@1.2.0: {} + + graceful-fs@4.2.11: {} + + has-bigints@1.1.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + + has-proto@1.2.0: + dependencies: + dunder-proto: 1.0.1 + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + has@1.0.4: {} + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + internal-slot@1.1.0: + dependencies: + es-errors: 1.3.0 + hasown: 2.0.2 + side-channel: 1.1.0 + + is-arguments@1.2.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-array-buffer@3.0.5: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + + is-async-function@2.1.1: + dependencies: + async-function: 1.0.0 + call-bound: 1.0.4 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-bigint@1.1.0: + dependencies: + has-bigints: 1.1.0 + + is-boolean-object@1.2.2: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-buffer@1.1.6: {} + + is-callable@1.2.7: {} + + is-core-module@2.16.1: + dependencies: + hasown: 2.0.2 + + is-data-view@1.0.2: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + is-typed-array: 1.1.15 + + is-date-object@1.1.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-finalizationregistry@1.1.1: + dependencies: + call-bound: 1.0.4 + + is-generator-function@1.1.0: + dependencies: + call-bound: 1.0.4 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-map@2.0.3: {} + + is-module@1.0.0: {} + + is-negative-zero@2.0.3: {} + + is-number-object@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-reference@1.2.1: + dependencies: + '@types/estree': 1.0.8 + + is-regex@1.1.4: + dependencies: + call-bind: 1.0.8 + has-tostringtag: 1.0.2 + + is-regex@1.2.1: + dependencies: + call-bound: 1.0.4 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + is-set@2.0.3: {} + + is-shared-array-buffer@1.0.4: + dependencies: + call-bound: 1.0.4 + + is-string@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-symbol@1.1.1: + dependencies: + call-bound: 1.0.4 + has-symbols: 1.1.0 + safe-regex-test: 1.1.0 + + is-typed-array@1.1.15: + dependencies: + which-typed-array: 1.1.19 + + is-weakmap@2.0.2: {} + + is-weakref@1.1.1: + dependencies: + call-bound: 1.0.4 + + is-weakset@2.0.4: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + + isarray@2.0.5: {} + + js-tokens@4.0.0: {} + + jsesc@3.0.2: {} + + jsesc@3.1.0: {} + + json5@2.2.3: {} + + jsonfile@6.2.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + + kind-of@3.2.2: + dependencies: + is-buffer: 1.1.6 + + lazy-cache@1.0.4: {} + + locate-path@5.0.0: + dependencies: + p-locate: 4.1.0 + + lodash.debounce@4.0.8: {} + + longest@1.0.1: {} + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + magic-string@0.25.9: + dependencies: + sourcemap-codec: 1.4.8 + + make-dir@3.1.0: + dependencies: + semver: 6.3.1 + + math-intrinsics@1.1.0: {} + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.12 + + minimist@1.2.8: {} + + mock-property@1.0.3: + dependencies: + define-data-property: 1.1.4 + functions-have-names: 1.2.3 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + hasown: 2.0.2 + isarray: 2.0.5 + + ms@2.1.3: {} + + node-releases@2.0.21: {} + + object-inspect@1.12.3: {} + + object-inspect@1.13.4: {} + + object-is@1.1.6: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + + object-keys@1.1.1: {} + + object.assign@4.1.7: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + has-symbols: 1.1.0 + object-keys: 1.1.1 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + own-keys@1.0.1: + dependencies: + get-intrinsic: 1.3.0 + object-keys: 1.1.1 + safe-push-apply: 1.0.0 + + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + + p-locate@4.1.0: + dependencies: + p-limit: 2.3.0 + + p-try@2.2.0: {} + + package-preamble@0.1.0: {} + + path-exists@4.0.0: {} + + path-is-absolute@1.0.1: {} + + path-parse@1.0.7: {} + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + pkg-dir@4.2.0: + dependencies: + find-up: 4.1.0 + + possible-typed-array-names@1.1.0: {} + + reflect.getprototypeof@1.0.10: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + which-builtin-type: 1.2.1 + + regenerate-unicode-properties@10.2.2: + dependencies: + regenerate: 1.4.2 + + regenerate@1.4.2: {} + + regexp.prototype.flags@1.5.4: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-errors: 1.3.0 + get-proto: 1.0.1 + gopd: 1.2.0 + set-function-name: 2.0.2 + + regexpu-core@6.3.1: + dependencies: + regenerate: 1.4.2 + regenerate-unicode-properties: 10.2.2 + regjsgen: 0.8.0 + regjsparser: 0.12.0 + unicode-match-property-ecmascript: 2.0.0 + unicode-match-property-value-ecmascript: 2.2.1 + + regjsgen@0.8.0: {} + + regjsparser@0.12.0: + dependencies: + jsesc: 3.0.2 + + repeat-string@1.6.1: {} + + resolve@1.22.10: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + right-align@0.1.3: + dependencies: + align-text: 0.1.4 + + rollup-plugin-babel@4.4.0(@babel/core@7.28.4)(rollup@2.79.2): + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-module-imports': 7.27.1 + rollup: 2.79.2 + rollup-pluginutils: 2.8.2 + transitivePeerDependencies: + - supports-color + + rollup-plugin-commonjs@10.1.0(rollup@2.79.2): + dependencies: + estree-walker: 0.6.1 + is-reference: 1.2.1 + magic-string: 0.25.9 + resolve: 1.22.10 + rollup: 2.79.2 + rollup-pluginutils: 2.8.2 + + rollup-plugin-node-resolve@5.2.0(rollup@2.79.2): + dependencies: + '@types/resolve': 0.0.8 + builtin-modules: 3.3.0 + is-module: 1.0.0 + resolve: 1.22.10 + rollup: 2.79.2 + rollup-pluginutils: 2.8.2 + + rollup-plugin-typescript2@0.35.0(rollup@2.79.2)(typescript@4.9.5): + dependencies: + '@rollup/pluginutils': 4.2.1 + find-cache-dir: 3.3.2 + fs-extra: 10.1.0 + rollup: 2.79.2 + semver: 7.7.2 + tslib: 2.8.1 + typescript: 4.9.5 + + rollup-pluginutils@2.8.2: + dependencies: + estree-walker: 0.6.1 + + rollup@2.79.2: + optionalDependencies: + fsevents: 2.3.3 + + safe-array-concat@1.1.3: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + has-symbols: 1.1.0 + isarray: 2.0.5 + + safe-push-apply@1.0.0: + dependencies: + es-errors: 1.3.0 + isarray: 2.0.5 + + safe-regex-test@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-regex: 1.2.1 + + semver@6.3.1: {} + + semver@7.7.2: {} + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + + set-function-name@2.0.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + + set-proto@1.0.0: + dependencies: + dunder-proto: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + + side-channel-list@1.0.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + source-map@0.5.7: {} + + sourcemap-codec@1.4.8: {} + + stop-iteration-iterator@1.1.0: + dependencies: + es-errors: 1.3.0 + internal-slot: 1.1.0 + + string.prototype.trim@1.2.10: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-data-property: 1.1.4 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-object-atoms: 1.1.1 + has-property-descriptors: 1.0.2 + + string.prototype.trimend@1.0.9: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + string.prototype.trimstart@1.0.8: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + supports-preserve-symlinks-flag@1.0.0: {} + + tape@4.17.0: + dependencies: + '@ljharb/resumer': 0.0.1 + '@ljharb/through': 2.3.14 + call-bind: 1.0.8 + deep-equal: 1.1.2 + defined: 1.0.1 + dotignore: 0.1.2 + for-each: 0.3.5 + glob: 7.2.3 + has: 1.0.4 + inherits: 2.0.4 + is-regex: 1.1.4 + minimist: 1.2.8 + mock-property: 1.0.3 + object-inspect: 1.12.3 + resolve: 1.22.10 + string.prototype.trim: 1.2.10 + + tslib@2.8.1: {} + + typed-array-buffer@1.0.3: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-typed-array: 1.1.15 + + typed-array-byte-length@1.0.3: + dependencies: + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + + typed-array-byte-offset@1.0.4: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + reflect.getprototypeof: 1.0.10 + + typed-array-length@1.0.7: + dependencies: + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + is-typed-array: 1.1.15 + possible-typed-array-names: 1.1.0 + reflect.getprototypeof: 1.0.10 + + typescript@4.9.5: {} + + uglify-js@2.8.29: + dependencies: + source-map: 0.5.7 + yargs: 3.10.0 + optionalDependencies: + uglify-to-browserify: 1.0.2 + + uglify-to-browserify@1.0.2: + optional: true + + unbox-primitive@1.1.0: + dependencies: + call-bound: 1.0.4 + has-bigints: 1.1.0 + has-symbols: 1.1.0 + which-boxed-primitive: 1.1.1 + + undici-types@7.12.0: {} + + unicode-canonical-property-names-ecmascript@2.0.1: {} + + unicode-match-property-ecmascript@2.0.0: + dependencies: + unicode-canonical-property-names-ecmascript: 2.0.1 + unicode-property-aliases-ecmascript: 2.2.0 + + unicode-match-property-value-ecmascript@2.2.1: {} + + unicode-property-aliases-ecmascript@2.2.0: {} + + universalify@2.0.1: {} + + update-browserslist-db@1.1.3(browserslist@4.26.2): + dependencies: + browserslist: 4.26.2 + escalade: 3.2.0 + picocolors: 1.1.1 + + which-boxed-primitive@1.1.1: + dependencies: + is-bigint: 1.1.0 + is-boolean-object: 1.2.2 + is-number-object: 1.1.1 + is-string: 1.1.1 + is-symbol: 1.1.1 + + which-builtin-type@1.2.1: + dependencies: + call-bound: 1.0.4 + function.prototype.name: 1.1.8 + has-tostringtag: 1.0.2 + is-async-function: 2.1.1 + is-date-object: 1.1.0 + is-finalizationregistry: 1.1.1 + is-generator-function: 1.1.0 + is-regex: 1.2.1 + is-weakref: 1.1.1 + isarray: 2.0.5 + which-boxed-primitive: 1.1.1 + which-collection: 1.0.2 + which-typed-array: 1.1.19 + + which-collection@1.0.2: + dependencies: + is-map: 2.0.3 + is-set: 2.0.3 + is-weakmap: 2.0.2 + is-weakset: 2.0.4 + + which-typed-array@1.1.19: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.4 + for-each: 0.3.5 + get-proto: 1.0.1 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + + window-size@0.1.0: {} + + wordwrap@0.0.2: {} + + wrappy@1.0.2: {} + + yallist@3.1.1: {} + + yargs@3.10.0: + dependencies: + camelcase: 1.2.1 + cliui: 2.1.0 + decamelize: 1.2.0 + window-size: 0.1.0 diff --git a/src/polynomial.ts b/src/polynomial.ts index fb3fc6c..68fdc94 100644 --- a/src/polynomial.ts +++ b/src/polynomial.ts @@ -20,7 +20,7 @@ export type PolynomialOutput = [DataPoint, DataPoint] & { }; -export interface PolynomialRegression { +export interface PolynomialRegression { (data: T[]): PolynomialOutput; domain(): Domain; @@ -38,9 +38,9 @@ export interface PolynomialRegression { export default function polynomial(): PolynomialRegression { let x: Accessor = (d: T) => (d as DataPoint)[0], - y: Accessor = (d: T) => (d as DataPoint)[1], - order = 3, - domain: Domain; + y: Accessor = (d: T) => (d as DataPoint)[1], + order = 3, + domain: Domain; const polynomialRegression = function polynomialRegression(data: T[]): PolynomialOutput { // Shortcut for lower-order polynomials: @@ -60,7 +60,7 @@ export default function polynomial(): PolynomialRegression { result.rSquared = o.rSquared; return result; } - + const [xv, yv, ux, uy] = points(data, x, y); const n = xv.length; const k = order + 1; @@ -71,7 +71,7 @@ export default function polynomial(): PolynomialRegression { n0 = 0, xmin = domain ? +domain[0] : Infinity, xmax = domain ? +domain[1] : -Infinity; - + visitPoints(data, x, y, (dx, dy) => { n0++; Y += (dy - Y) / n0; @@ -112,15 +112,15 @@ export default function polynomial(): PolynomialRegression { } return val; }; - + const out = interpose(xmin, xmax, fn); out.coefficients = uncenter(k, coef, -ux, uy); out.predict = fn; out.rSquared = determination(data, x, y, Y, fn); - + return out; } as PolynomialRegression; - + polynomialRegression.domain = function (arr?: [number, number]) { if (!arguments.length) return domain; domain = arr; @@ -190,7 +190,7 @@ function gaussianElimination(matrix: Float64Array[]): number[] { } } } - + for (let j = n - 1; j >= 0; j--) { let t = 0; for (let k = j + 1; k < n; k++) { @@ -198,6 +198,6 @@ function gaussianElimination(matrix: Float64Array[]): number[] { } coef[j] = (matrix[n][j] - t) / matrix[j][j]; } - + return coef; } From f106b70d2ba9b2afc6c6c6e35978d32769334096 Mon Sep 17 00:00:00 2001 From: gka Date: Sat, 20 Sep 2025 13:45:56 +0200 Subject: [PATCH 07/10] chore: replace uglifyjs with terser --- dist/d3-regression.min.js | 1 + package.json | 5 +- pnpm-lock.yaml | 128 -------------------------------------- 3 files changed, 3 insertions(+), 131 deletions(-) create mode 100644 dist/d3-regression.min.js diff --git a/dist/d3-regression.min.js b/dist/d3-regression.min.js new file mode 100644 index 0000000..46d8b1f --- /dev/null +++ b/dist/d3-regression.min.js @@ -0,0 +1 @@ +!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((t="undefined"!=typeof globalThis?globalThis:t||self).d3={})}(this,function(t){"use strict";function n(t,n,e,r){t=t.filter((t,r)=>{let o=n(t,r),u=e(t,r);return null!=o&&isFinite(o)&&null!=u&&isFinite(u)}),r&&t.sort((t,e)=>n(t)-n(e));const o=t.length,u=new Float64Array(o),l=new Float64Array(o);let i,c,f,a=0,s=0;for(let r=0;r{const e=n-u(t),r=n-o;l+=e*e,i+=r*r}),1-l/i}function o(t){return Math.atan2(t[1][1]-t[0][1],t[1][0]-t[0][0])*(180/Math.PI)}function u(t){return[(t[0][0]+t[1][0])/2,(t[0][1]+t[1][1])/2]}function l(t,n,e){const r=Math.log(n-t)*Math.LOG10E+1|0,l=Math.pow(10,-r/2-1);let i=[f(t),f(n)],c=0;for(;a(i)&&c<1e4;);return i;function f(t){return[t,e(t)]}function a(t){c++;const n=t.length;let e=!1;for(let r=0;rl&&(t.splice(r+1,0,c),e=!0)}return e}}function i(t,n,e,r){const o=r-t*t,u=Math.abs(o)<1e-24?0:(e-t*n)/o;return[n-u*t,u]}function c(){let t,n=t=>t[0],o=t=>t[1];const u=function(u){let l=0,c=0,f=0,a=0,s=0,h=t?+t[0]:1/0,g=t?+t[1]:-1/0;e(u,n,o,(n,e)=>{++l,c+=(n-c)/l,f+=(e-f)/l,a+=(n*e-a)/l,s+=(n*n-s)/l,t||(ng&&(g=n))});const[d,p]=i(c,f,a,s),M=t=>p*t+d,y=[[h,M(h)],[g,M(g)]];return y.a=p,y.b=d,y.predict=M,y.rSquared=r(u,n,o,f,M),y};return u.domain=function(n){return arguments.length?(t=n,u):t},u.x=function(t){return arguments.length?(n=t,u):n},u.y=function(t){return arguments.length?(o=t,u):o},u}function f(t){t.sort((t,n)=>t-n);var n=t.length/2;return n%1==0?(t[n-1]+t[n])/2:t[Math.floor(n)]}function a(t){return(t=1-t*t*t)*t*t}function s(t,n,e){let r=t[n],o=e[0],u=e[1]+1;if(!(u>=t.length))for(;n>o&&t[u]-r<=r-t[o];)e[0]=++o,e[1]=u,++u}function h(){let t,o=t=>t[0],u=t=>t[1];const i=function(i){const[c,f,a,s]=n(i,t=>o(t),t=>u(t)),h=c.length;let g,d,p,M,y=0,b=0,x=0,w=0,m=0;for(g=0;g{q++,S+=(e-S)/q,t||(nA&&(A=n))});const L=x-y*y,P=y*L-b*b,v=(m*y-w*b)/P,E=(w*L-m*b)/P,j=-v*y,k=t=>{const n=t-a;return v*n*n+E*n+j+s},O=l(F,A,k);return O.a=v,O.b=E-2*v*a,O.c=j-E*a+v*a*a+s,O.predict=k,O.rSquared=r(i,o,u,S,k),O};return i.domain=function(n){return arguments.length?(t=n,i):t},i.x=function(t){return arguments.length?(o=t,i):o},i.y=function(t){return arguments.length?(u=t,i):u},i}t.regressionExp=function(){let t,n=t=>t[1],o=t=>t[0];const u=function(u){let c=0,f=0,a=0,s=0,h=0,g=0,d=t?+t[0]:1/0,p=t?+t[1]:-1/0;e(u,o,n,(n,e)=>{const r=Math.log(e),o=n*e;++c,f+=(e-f)/c,s+=(o-s)/c,g+=(n*o-g)/c,a+=(e*r-a)/c,h+=(o*r-h)/c,t||(np&&(p=n))});let[M,y]=i(s/f,a/f,h/f,g/f);M=Math.exp(M);const b=t=>M*Math.exp(y*t),x=l(d,p,b);return x.a=M,x.b=y,x.predict=b,x.rSquared=r(u,o,n,f,b),x};return u.domain=function(n){return arguments.length?(t=n,u):t},u.x=function(t){return arguments.length?(o=t,u):o},u.y=function(t){return arguments.length?(n=t,u):n},u},t.regressionLinear=c,t.regressionLoess=function(){let t=t=>t[0],e=t=>t[1],r=.3;const o=function(o){const[u,l,c,h]=n(o,n=>t(n),t=>e(t),!0),g=u.length,d=Math.max(2,~~(r*g)),p=new Float64Array(g),M=new Float64Array(g),y=new Float64Array(g).fill(1);for(let t=-1;++t<=2;){const n=[0,d-1];for(let t=0;tu[o]-e?r:o;let f=0,h=0,g=0,d=0,b=0;const x=1/Math.abs(u[c]-e||1);for(let t=r;t<=o;++t){const n=u[t],r=l[t],o=a(Math.abs(e-n)*x)*y[t],i=n*o;f+=o,h+=i,g+=r*o,d+=r*i,b+=n*i}const[w,m]=i(h/f,g/f,d/f,b/f);p[t]=w+m*e,M[t]=Math.abs(l[t]-p[t]),s(u,t+1,n)}if(2===t)break;const e=f(M);if(Math.abs(e)<1e-12)break;for(let t,n,r=0;r=1?1e-12:(n=1-t*t)*n}return function(t,n,e,r){const o=t.length,u=[];let l,i=0,c=0,f=[];for(;it[0],o=t=>t[1],u=Math.E;const c=function(c){let f=0,a=0,s=0,h=0,g=0,d=t?+t[0]:1/0,p=t?+t[1]:-1/0,M=Math.log(u);e(c,n,o,(n,e)=>{const r=Math.log(n)/M;++f,a+=(r-a)/f,s+=(e-s)/f,h+=(r*e-h)/f,g+=(r*r-g)/f,t||(np&&(p=n))});const[y,b]=i(a,s,h,g),x=t=>b*Math.log(t)/M+y,w=l(d,p,x);return w.a=b,w.b=y,w.predict=x,w.rSquared=r(c,n,o,s,x),w};return c.domain=function(n){return arguments.length?(t=n,c):t},c.x=function(t){return arguments.length?(n=t,c):n},c.y=function(t){return arguments.length?(o=t,c):o},c.base=function(t){return arguments.length?(u=t,c):u},c},t.regressionPoly=function(){let t,o=t=>t[0],u=t=>t[1],i=3;const f=function(f){if(1===i){const n=c().x(o).y(u).domain(t)(f),e=[n[0],n[1]];return e.coefficients=[n.b,n.a],e.predict=n.predict,e.rSquared=n.rSquared,e}if(2===i){const n=h().x(o).y(u).domain(t)(f),e=[n[0],n[1]];return e.coefficients=[n.c,n.b,n.a],e.predict=n.predict,e.rSquared=n.rSquared,e}const[a,s,g,d]=n(f,o,u),p=a.length,M=i+1,y=[],b=[];let x=0,w=0,m=t?+t[0]:1/0,S=t?+t[1]:-1/0;e(f,o,u,(n,e)=>{w++,x+=(e-x)/w,t||(nS&&(S=n))});for(let t=0;tMath.abs(t[e][r])&&(r=o);for(let o=e;o=e;o--)t[o][r]-=t[o][e]*t[e][r]/t[e][e]}for(let r=n-1;r>=0;r--){let o=0;for(let u=r+1;u{let n=t-g,e=d+q[0];for(let t=1;t=0;--r){let t=n[r];o[r]+=t;let u=1;for(let n=1;n<=r;++n)u*=(r+1-n)/n,o[r-n]+=t*Math.pow(e,n)*u}return o[0]+=r,o}(M,q,-g,d),A.predict=F,A.rSquared=r(f,o,u,x,F),A};return f.domain=function(n){return arguments.length?(t=n,f):t},f.x=function(t){return arguments.length?(o=t,f):o},f.y=function(t){return arguments.length?(u=t,f):u},f.order=function(t){return arguments.length?(i=t,f):i},f},t.regressionPow=function(){let t,n=t=>t[0],o=t=>t[1];const u=function(u){let c=0,f=0,a=0,s=0,h=0,g=0,d=t?+t[0]:1/0,p=t?+t[1]:-1/0;e(u,n,o,(n,e)=>{const r=Math.log(n),o=Math.log(e);++c,f+=(r-f)/c,a+=(o-a)/c,s+=(r*o-s)/c,h+=(r*r-h)/c,g+=(e-g)/c,t||(np&&(p=n))});let[M,y]=i(f,a,s,h);M=Math.exp(M);const b=t=>M*Math.pow(t,y),x=l(d,p,b);return x.a=M,x.b=y,x.predict=b,x.rSquared=r(u,n,o,g,b),x};return u.domain=function(n){return arguments.length?(t=n,u):t},u.x=function(t){return arguments.length?(n=t,u):n},u.y=function(t){return arguments.length?(o=t,u):o},u},t.regressionQuad=h,t.regressionSigmoidal=function(){let t,n=t=>t[0],o=t=>t[1],u=1e-4;function i(i){let c=0,f=t?+t[0]:1/0,a=t?+t[1]:-1/0,s=1/0,h=-1/0,g=0;e(i,n,o,(n,e)=>{c++,g+=e,t||(na&&(a=n)),eh&&(h=e)}),t||f!==1/0&&a!==-1/0||(f=0,a=1);let d=h-s,p=1,M=s,y=(f+a)/2;for(let t=0;t<2e3;t++){let t=0,r=0,l=0,f=0;e(i,n,o,(n,e)=>{var o;const u=e-(o=n,M+d/(1+Math.exp(-p*(o-y)))),i=1/(1+Math.exp(-p*(n-y))),c=-2*u;t+=c*i,r+=c*(d*i*(1-i)*(n-y)),l+=1*c,f+=c*(-d*p*i*(1-i))}),d-=u*(t/c),p-=u*(r/c),M-=u*(l/c),y-=u*(f/c)}const b=t=>M+d/(1+Math.exp(-p*(t-y))),x=l(f,a,b);x.A=d,x.B=p,x.C=M,x.M=y,x.predict=b;const w=g/c;return x.rSquared=r(i,n,o,w,b),x}return i.domain=function(n){return arguments.length?(t=n,i):t},i.x=function(t){return arguments.length?(n=t,i):n},i.y=function(t){return arguments.length?(o=t,i):o},i},Object.defineProperty(t,"__esModule",{value:!0})}); \ No newline at end of file diff --git a/package.json b/package.json index 10d6ee3..0dcd13e 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "scripts": { "pretest": "rm -rf dist && mkdir dist && rollup -c --banner \"$(preamble)\"", "test": "tape 'test/**/*-test.js'", - "prepublishOnly": "npm run test && uglifyjs dist/d3-regression.js -c -m -o dist/d3-regression.min.js", + "prepublishOnly": "npm run test && terser dist/d3-regression.js --compress ecma=2025 -m -o dist/d3-regression.min.js", "postpublish": "zip -j dist/d3-regression.zip -- LICENSE README.md dist/d3-regression.js dist/d3-regression.min.js dist/d3-regression.cjs.js dist/d3-regression.esm.js dist/index.d.ts dist/src/*.d.ts" }, "repository": { @@ -42,7 +42,6 @@ "rollup-plugin-node-resolve": "^5.2.0", "rollup-plugin-typescript2": "^0.35.0", "tape": "^4.10.1", - "typescript": "^4.9.5", - "uglify-js": "^2.8.29" + "typescript": "^4.9.5" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d61d2eb..8f44259 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -41,9 +41,6 @@ importers: typescript: specifier: ^4.9.5 version: 4.9.5 - uglify-js: - specifier: ^2.8.29 - version: 2.8.29 packages: @@ -575,10 +572,6 @@ packages: '@types/resolve@0.0.8': resolution: {integrity: sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==} - align-text@0.1.4: - resolution: {integrity: sha512-GrTZLRpmp6wIC2ztrWW9MjjTgSKccffgFagbNDOX95/dcjEcYZibYTeaOntySQLcdw1ztBoFkviiUvTMbb9MYg==} - engines: {node: '>=0.10.0'} - array-buffer-byte-length@1.0.2: resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} engines: {node: '>= 0.4'} @@ -646,20 +639,9 @@ packages: resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} engines: {node: '>= 0.4'} - camelcase@1.2.1: - resolution: {integrity: sha512-wzLkDa4K/mzI1OSITC+DUyjgIl/ETNHE9QvYgy6J6Jvqyyz4C0Xfd+lQhb19sX2jMpZV4IssUn0VDVmglV+s4g==} - engines: {node: '>=0.10.0'} - caniuse-lite@1.0.30001743: resolution: {integrity: sha512-e6Ojr7RV14Un7dz6ASD0aZDmQPT/A+eZU+nuTNfjqmRrmkmQlnTNWH0SKmqagx9PeW87UVqapSurtAXifmtdmw==} - center-align@0.1.3: - resolution: {integrity: sha512-Baz3aNe2gd2LP2qk5U+sDk/m4oSuwSDcBfayTCTBoWpfIGO5XFxPmjILQII4NGiZjD6DoDI6kf7gKaxkf7s3VQ==} - engines: {node: '>=0.10.0'} - - cliui@2.1.0: - resolution: {integrity: sha512-GIOYRizG+TGoc7Wgc1LiOTLare95R3mzKgoln+Q/lE4ceiYH19gUpl0l0Ffq4lJDEf3FxujMe6IBfOCs7pfqNA==} - commondir@1.0.1: resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} @@ -693,10 +675,6 @@ packages: supports-color: optional: true - decamelize@1.2.0: - resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} - engines: {node: '>=0.10.0'} - deep-equal@1.1.2: resolution: {integrity: sha512-5tdhKF6DbU7iIzrIOa1AOUt39ZRm13cmL1cGEh//aqR8x9+tNfbywRf0n5FD/18OKMdo7DNEtrX2t22ZAkI+eg==} engines: {node: '>= 0.4'} @@ -884,9 +862,6 @@ packages: resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} engines: {node: '>= 0.4'} - is-buffer@1.1.6: - resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} - is-callable@1.2.7: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} engines: {node: '>= 0.4'} @@ -993,14 +968,6 @@ packages: jsonfile@6.2.0: resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} - kind-of@3.2.2: - resolution: {integrity: sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==} - engines: {node: '>=0.10.0'} - - lazy-cache@1.0.4: - resolution: {integrity: sha512-RE2g0b5VGZsOCFOCgP7omTRYFqydmZkBwl5oNnQ1lDYC57uyO9KqNnNVxT7COSHTxrRCWVcAVOcbjk+tvh/rgQ==} - engines: {node: '>=0.10.0'} - locate-path@5.0.0: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} engines: {node: '>=8'} @@ -1008,10 +975,6 @@ packages: lodash.debounce@4.0.8: resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} - longest@1.0.1: - resolution: {integrity: sha512-k+yt5n3l48JU4k8ftnKG6V7u32wyH2NfKzeMto9F/QRE0amxy/LayxwlvjjkZEIzqR+19IrtFO8p5kB9QaYUFg==} - engines: {node: '>=0.10.0'} - lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} @@ -1136,19 +1099,11 @@ packages: resolution: {integrity: sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==} hasBin: true - repeat-string@1.6.1: - resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} - engines: {node: '>=0.10'} - resolve@1.22.10: resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} engines: {node: '>= 0.4'} hasBin: true - right-align@0.1.3: - resolution: {integrity: sha512-yqINtL/G7vs2v+dFIZmFUDbnVyFUJFKd6gK22Kgo6R4jfJGFtisKyncWDDULgjfqf4ASQuIQyjJ7XZ+3aWpsAg==} - engines: {node: '>=0.10.0'} - rollup-plugin-babel@4.4.0: resolution: {integrity: sha512-Lek/TYp1+7g7I+uMfJnnSJ7YWoD58ajo6Oarhlex7lvUce+RCKRuGRSgztDO3/MF/PuGKmUL5iTHKf208UNszw==} deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-babel. @@ -1231,10 +1186,6 @@ packages: resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} engines: {node: '>= 0.4'} - source-map@0.5.7: - resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} - engines: {node: '>=0.10.0'} - sourcemap-codec@1.4.8: resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} deprecated: Please use @jridgewell/sourcemap-codec instead @@ -1287,14 +1238,6 @@ packages: engines: {node: '>=4.2.0'} hasBin: true - uglify-js@2.8.29: - resolution: {integrity: sha512-qLq/4y2pjcU3vhlhseXGGJ7VbFO4pBANu0kwl8VCa9KEI0V8VfZIx2Fy3w01iSTA/pGwKZSmu/+I4etLNDdt5w==} - engines: {node: '>=0.8.0'} - hasBin: true - - uglify-to-browserify@1.0.2: - resolution: {integrity: sha512-vb2s1lYx2xBtUgy+ta+b2J/GLVUR+wmpINwHePmPRhOsIVCG2wDzKJ0n14GslH1BifsqVzSOwQhRaCAsZ/nI4Q==} - unbox-primitive@1.1.0: resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} engines: {node: '>= 0.4'} @@ -1344,23 +1287,12 @@ packages: resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} engines: {node: '>= 0.4'} - window-size@0.1.0: - resolution: {integrity: sha512-1pTPQDKTdd61ozlKGNCjhNRd+KPmgLSGa3mZTHoOliaGcESD8G1PXhh7c1fgiPjVbNVfgy2Faw4BI8/m0cC8Mg==} - engines: {node: '>= 0.8.0'} - - wordwrap@0.0.2: - resolution: {integrity: sha512-xSBsCeh+g+dinoBv3GAOWM4LcVVO68wLXRanibtBSdUvkGWQRGeE9P7IwU9EmDDi4jA6L44lz15CGMwdw9N5+Q==} - engines: {node: '>=0.4.0'} - wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - yargs@3.10.0: - resolution: {integrity: sha512-QFzUah88GAGy9lyDKGBqZdkYApt63rCXYBGYnEP4xDJPXNqXXnBDACnbrXnViV6jRSqAePwrATi2i8mfYm4L1A==} - snapshots: '@babel/code-frame@7.27.1': @@ -2057,12 +1989,6 @@ snapshots: dependencies: '@types/node': 24.5.2 - align-text@0.1.4: - dependencies: - kind-of: 3.2.2 - longest: 1.0.1 - repeat-string: 1.6.1 - array-buffer-byte-length@1.0.2: dependencies: call-bound: 1.0.4 @@ -2146,21 +2072,8 @@ snapshots: call-bind-apply-helpers: 1.0.2 get-intrinsic: 1.3.0 - camelcase@1.2.1: {} - caniuse-lite@1.0.30001743: {} - center-align@0.1.3: - dependencies: - align-text: 0.1.4 - lazy-cache: 1.0.4 - - cliui@2.1.0: - dependencies: - center-align: 0.1.3 - right-align: 0.1.3 - wordwrap: 0.0.2 - commondir@1.0.1: {} concat-map@0.0.1: {} @@ -2193,8 +2106,6 @@ snapshots: dependencies: ms: 2.1.3 - decamelize@1.2.0: {} - deep-equal@1.1.2: dependencies: is-arguments: 1.2.0 @@ -2462,8 +2373,6 @@ snapshots: call-bound: 1.0.4 has-tostringtag: 1.0.2 - is-buffer@1.1.6: {} - is-callable@1.2.7: {} is-core-module@2.16.1: @@ -2567,20 +2476,12 @@ snapshots: optionalDependencies: graceful-fs: 4.2.11 - kind-of@3.2.2: - dependencies: - is-buffer: 1.1.6 - - lazy-cache@1.0.4: {} - locate-path@5.0.0: dependencies: p-locate: 4.1.0 lodash.debounce@4.0.8: {} - longest@1.0.1: {} - lru-cache@5.1.1: dependencies: yallist: 3.1.1 @@ -2713,18 +2614,12 @@ snapshots: dependencies: jsesc: 3.0.2 - repeat-string@1.6.1: {} - resolve@1.22.10: dependencies: is-core-module: 2.16.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 - right-align@0.1.3: - dependencies: - align-text: 0.1.4 - rollup-plugin-babel@4.4.0(@babel/core@7.28.4)(rollup@2.79.2): dependencies: '@babel/core': 7.28.4 @@ -2843,8 +2738,6 @@ snapshots: side-channel-map: 1.0.1 side-channel-weakmap: 1.0.2 - source-map@0.5.7: {} - sourcemap-codec@1.4.8: {} stop-iteration-iterator@1.1.0: @@ -2933,16 +2826,6 @@ snapshots: typescript@4.9.5: {} - uglify-js@2.8.29: - dependencies: - source-map: 0.5.7 - yargs: 3.10.0 - optionalDependencies: - uglify-to-browserify: 1.0.2 - - uglify-to-browserify@1.0.2: - optional: true - unbox-primitive@1.1.0: dependencies: call-bound: 1.0.4 @@ -3012,17 +2895,6 @@ snapshots: gopd: 1.2.0 has-tostringtag: 1.0.2 - window-size@0.1.0: {} - - wordwrap@0.0.2: {} - wrappy@1.0.2: {} yallist@3.1.1: {} - - yargs@3.10.0: - dependencies: - camelcase: 1.2.1 - cliui: 2.1.0 - decamelize: 1.2.0 - window-size: 0.1.0 From dc02515a506eac9fb27cb2d9e2c7d0b2ee8bbee7 Mon Sep 17 00:00:00 2001 From: gka Date: Thu, 25 Sep 2025 22:01:41 +0200 Subject: [PATCH 08/10] try to fix package.json --- package.json | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/package.json b/package.json index 0dcd13e..7ddec57 100644 --- a/package.json +++ b/package.json @@ -22,10 +22,23 @@ "name": "Harry Stevens", "url": "http://harryjstevens.com/" }, + "type": "module", + "files": [ + "dist/**/*.js", + "src/**/*.js", + "locale/*.json" + ], "browser": "dist/d3-regression.js", "module": "dist/d3-regression.esm.js", "main": "dist/d3-regression.cjs.js", + "unpkg": "dist/d3-regression.min.js", "types": "dist/types/index.d.ts", + "exports": { + ".": { + "umd": "./dist/d3-regression.js", + "default": "./dist/d3-regression.esm.js" + } + }, "license": "BSD-3-Clause", "bugs": { "url": "https://github.com/HarryStevens/d3-regression/issues" From 07e79d61c65816278ef8453866e5206ad77918a9 Mon Sep 17 00:00:00 2001 From: gka Date: Thu, 25 Sep 2025 22:02:55 +0200 Subject: [PATCH 09/10] bump prerelease version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7ddec57..c65433a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@gka/d3-regression", - "version": "1.3.10-pr48", + "version": "1.3.10-pr48.1", "description": "Calculate statistical regressions for two-dimensional data", "keywords": [ "d3", From 56221f40209db1774edc079fa138624992399760 Mon Sep 17 00:00:00 2001 From: gka Date: Thu, 25 Sep 2025 22:06:30 +0200 Subject: [PATCH 10/10] tests esm --- dist/d3-regression.cjs.js | 2 +- dist/d3-regression.esm.js | 2 +- dist/d3-regression.js | 2 +- dist/d3-regression.min.js | 1 - test/exponential-test.js | 5 +++-- test/linear-test.js | 4 ++-- test/loess-test.js | 4 ++-- test/logarithmic-test.js | 4 ++-- test/polynomial-test.js | 4 ++-- test/power-test.js | 4 ++-- test/quadratic-test.js | 4 ++-- 11 files changed, 18 insertions(+), 18 deletions(-) delete mode 100644 dist/d3-regression.min.js diff --git a/dist/d3-regression.cjs.js b/dist/d3-regression.cjs.js index b78907d..f3d3f69 100644 --- a/dist/d3-regression.cjs.js +++ b/dist/d3-regression.cjs.js @@ -1,4 +1,4 @@ -// https://github.com/HarryStevens/d3-regression#readme Version 1.3.10-pr48. Copyright 2025 Harry Stevens. +// https://github.com/HarryStevens/d3-regression#readme Version 1.3.10-pr48.1. Copyright 2025 Harry Stevens. 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); diff --git a/dist/d3-regression.esm.js b/dist/d3-regression.esm.js index d7ddd95..c23b86f 100644 --- a/dist/d3-regression.esm.js +++ b/dist/d3-regression.esm.js @@ -1,4 +1,4 @@ -// https://github.com/HarryStevens/d3-regression#readme Version 1.3.10-pr48. Copyright 2025 Harry Stevens. +// https://github.com/HarryStevens/d3-regression#readme Version 1.3.10-pr48.1. Copyright 2025 Harry Stevens. /** * Adapted from vega-statistics by Jeffrey Heer * License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE diff --git a/dist/d3-regression.js b/dist/d3-regression.js index 2c3d809..a962caf 100644 --- a/dist/d3-regression.js +++ b/dist/d3-regression.js @@ -1,4 +1,4 @@ -// https://github.com/HarryStevens/d3-regression#readme Version 1.3.10-pr48. Copyright 2025 Harry Stevens. +// https://github.com/HarryStevens/d3-regression#readme Version 1.3.10-pr48.1. Copyright 2025 Harry Stevens. (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : diff --git a/dist/d3-regression.min.js b/dist/d3-regression.min.js deleted file mode 100644 index 46d8b1f..0000000 --- a/dist/d3-regression.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((t="undefined"!=typeof globalThis?globalThis:t||self).d3={})}(this,function(t){"use strict";function n(t,n,e,r){t=t.filter((t,r)=>{let o=n(t,r),u=e(t,r);return null!=o&&isFinite(o)&&null!=u&&isFinite(u)}),r&&t.sort((t,e)=>n(t)-n(e));const o=t.length,u=new Float64Array(o),l=new Float64Array(o);let i,c,f,a=0,s=0;for(let r=0;r{const e=n-u(t),r=n-o;l+=e*e,i+=r*r}),1-l/i}function o(t){return Math.atan2(t[1][1]-t[0][1],t[1][0]-t[0][0])*(180/Math.PI)}function u(t){return[(t[0][0]+t[1][0])/2,(t[0][1]+t[1][1])/2]}function l(t,n,e){const r=Math.log(n-t)*Math.LOG10E+1|0,l=Math.pow(10,-r/2-1);let i=[f(t),f(n)],c=0;for(;a(i)&&c<1e4;);return i;function f(t){return[t,e(t)]}function a(t){c++;const n=t.length;let e=!1;for(let r=0;rl&&(t.splice(r+1,0,c),e=!0)}return e}}function i(t,n,e,r){const o=r-t*t,u=Math.abs(o)<1e-24?0:(e-t*n)/o;return[n-u*t,u]}function c(){let t,n=t=>t[0],o=t=>t[1];const u=function(u){let l=0,c=0,f=0,a=0,s=0,h=t?+t[0]:1/0,g=t?+t[1]:-1/0;e(u,n,o,(n,e)=>{++l,c+=(n-c)/l,f+=(e-f)/l,a+=(n*e-a)/l,s+=(n*n-s)/l,t||(ng&&(g=n))});const[d,p]=i(c,f,a,s),M=t=>p*t+d,y=[[h,M(h)],[g,M(g)]];return y.a=p,y.b=d,y.predict=M,y.rSquared=r(u,n,o,f,M),y};return u.domain=function(n){return arguments.length?(t=n,u):t},u.x=function(t){return arguments.length?(n=t,u):n},u.y=function(t){return arguments.length?(o=t,u):o},u}function f(t){t.sort((t,n)=>t-n);var n=t.length/2;return n%1==0?(t[n-1]+t[n])/2:t[Math.floor(n)]}function a(t){return(t=1-t*t*t)*t*t}function s(t,n,e){let r=t[n],o=e[0],u=e[1]+1;if(!(u>=t.length))for(;n>o&&t[u]-r<=r-t[o];)e[0]=++o,e[1]=u,++u}function h(){let t,o=t=>t[0],u=t=>t[1];const i=function(i){const[c,f,a,s]=n(i,t=>o(t),t=>u(t)),h=c.length;let g,d,p,M,y=0,b=0,x=0,w=0,m=0;for(g=0;g{q++,S+=(e-S)/q,t||(nA&&(A=n))});const L=x-y*y,P=y*L-b*b,v=(m*y-w*b)/P,E=(w*L-m*b)/P,j=-v*y,k=t=>{const n=t-a;return v*n*n+E*n+j+s},O=l(F,A,k);return O.a=v,O.b=E-2*v*a,O.c=j-E*a+v*a*a+s,O.predict=k,O.rSquared=r(i,o,u,S,k),O};return i.domain=function(n){return arguments.length?(t=n,i):t},i.x=function(t){return arguments.length?(o=t,i):o},i.y=function(t){return arguments.length?(u=t,i):u},i}t.regressionExp=function(){let t,n=t=>t[1],o=t=>t[0];const u=function(u){let c=0,f=0,a=0,s=0,h=0,g=0,d=t?+t[0]:1/0,p=t?+t[1]:-1/0;e(u,o,n,(n,e)=>{const r=Math.log(e),o=n*e;++c,f+=(e-f)/c,s+=(o-s)/c,g+=(n*o-g)/c,a+=(e*r-a)/c,h+=(o*r-h)/c,t||(np&&(p=n))});let[M,y]=i(s/f,a/f,h/f,g/f);M=Math.exp(M);const b=t=>M*Math.exp(y*t),x=l(d,p,b);return x.a=M,x.b=y,x.predict=b,x.rSquared=r(u,o,n,f,b),x};return u.domain=function(n){return arguments.length?(t=n,u):t},u.x=function(t){return arguments.length?(o=t,u):o},u.y=function(t){return arguments.length?(n=t,u):n},u},t.regressionLinear=c,t.regressionLoess=function(){let t=t=>t[0],e=t=>t[1],r=.3;const o=function(o){const[u,l,c,h]=n(o,n=>t(n),t=>e(t),!0),g=u.length,d=Math.max(2,~~(r*g)),p=new Float64Array(g),M=new Float64Array(g),y=new Float64Array(g).fill(1);for(let t=-1;++t<=2;){const n=[0,d-1];for(let t=0;tu[o]-e?r:o;let f=0,h=0,g=0,d=0,b=0;const x=1/Math.abs(u[c]-e||1);for(let t=r;t<=o;++t){const n=u[t],r=l[t],o=a(Math.abs(e-n)*x)*y[t],i=n*o;f+=o,h+=i,g+=r*o,d+=r*i,b+=n*i}const[w,m]=i(h/f,g/f,d/f,b/f);p[t]=w+m*e,M[t]=Math.abs(l[t]-p[t]),s(u,t+1,n)}if(2===t)break;const e=f(M);if(Math.abs(e)<1e-12)break;for(let t,n,r=0;r=1?1e-12:(n=1-t*t)*n}return function(t,n,e,r){const o=t.length,u=[];let l,i=0,c=0,f=[];for(;it[0],o=t=>t[1],u=Math.E;const c=function(c){let f=0,a=0,s=0,h=0,g=0,d=t?+t[0]:1/0,p=t?+t[1]:-1/0,M=Math.log(u);e(c,n,o,(n,e)=>{const r=Math.log(n)/M;++f,a+=(r-a)/f,s+=(e-s)/f,h+=(r*e-h)/f,g+=(r*r-g)/f,t||(np&&(p=n))});const[y,b]=i(a,s,h,g),x=t=>b*Math.log(t)/M+y,w=l(d,p,x);return w.a=b,w.b=y,w.predict=x,w.rSquared=r(c,n,o,s,x),w};return c.domain=function(n){return arguments.length?(t=n,c):t},c.x=function(t){return arguments.length?(n=t,c):n},c.y=function(t){return arguments.length?(o=t,c):o},c.base=function(t){return arguments.length?(u=t,c):u},c},t.regressionPoly=function(){let t,o=t=>t[0],u=t=>t[1],i=3;const f=function(f){if(1===i){const n=c().x(o).y(u).domain(t)(f),e=[n[0],n[1]];return e.coefficients=[n.b,n.a],e.predict=n.predict,e.rSquared=n.rSquared,e}if(2===i){const n=h().x(o).y(u).domain(t)(f),e=[n[0],n[1]];return e.coefficients=[n.c,n.b,n.a],e.predict=n.predict,e.rSquared=n.rSquared,e}const[a,s,g,d]=n(f,o,u),p=a.length,M=i+1,y=[],b=[];let x=0,w=0,m=t?+t[0]:1/0,S=t?+t[1]:-1/0;e(f,o,u,(n,e)=>{w++,x+=(e-x)/w,t||(nS&&(S=n))});for(let t=0;tMath.abs(t[e][r])&&(r=o);for(let o=e;o=e;o--)t[o][r]-=t[o][e]*t[e][r]/t[e][e]}for(let r=n-1;r>=0;r--){let o=0;for(let u=r+1;u{let n=t-g,e=d+q[0];for(let t=1;t=0;--r){let t=n[r];o[r]+=t;let u=1;for(let n=1;n<=r;++n)u*=(r+1-n)/n,o[r-n]+=t*Math.pow(e,n)*u}return o[0]+=r,o}(M,q,-g,d),A.predict=F,A.rSquared=r(f,o,u,x,F),A};return f.domain=function(n){return arguments.length?(t=n,f):t},f.x=function(t){return arguments.length?(o=t,f):o},f.y=function(t){return arguments.length?(u=t,f):u},f.order=function(t){return arguments.length?(i=t,f):i},f},t.regressionPow=function(){let t,n=t=>t[0],o=t=>t[1];const u=function(u){let c=0,f=0,a=0,s=0,h=0,g=0,d=t?+t[0]:1/0,p=t?+t[1]:-1/0;e(u,n,o,(n,e)=>{const r=Math.log(n),o=Math.log(e);++c,f+=(r-f)/c,a+=(o-a)/c,s+=(r*o-s)/c,h+=(r*r-h)/c,g+=(e-g)/c,t||(np&&(p=n))});let[M,y]=i(f,a,s,h);M=Math.exp(M);const b=t=>M*Math.pow(t,y),x=l(d,p,b);return x.a=M,x.b=y,x.predict=b,x.rSquared=r(u,n,o,g,b),x};return u.domain=function(n){return arguments.length?(t=n,u):t},u.x=function(t){return arguments.length?(n=t,u):n},u.y=function(t){return arguments.length?(o=t,u):o},u},t.regressionQuad=h,t.regressionSigmoidal=function(){let t,n=t=>t[0],o=t=>t[1],u=1e-4;function i(i){let c=0,f=t?+t[0]:1/0,a=t?+t[1]:-1/0,s=1/0,h=-1/0,g=0;e(i,n,o,(n,e)=>{c++,g+=e,t||(na&&(a=n)),eh&&(h=e)}),t||f!==1/0&&a!==-1/0||(f=0,a=1);let d=h-s,p=1,M=s,y=(f+a)/2;for(let t=0;t<2e3;t++){let t=0,r=0,l=0,f=0;e(i,n,o,(n,e)=>{var o;const u=e-(o=n,M+d/(1+Math.exp(-p*(o-y)))),i=1/(1+Math.exp(-p*(n-y))),c=-2*u;t+=c*i,r+=c*(d*i*(1-i)*(n-y)),l+=1*c,f+=c*(-d*p*i*(1-i))}),d-=u*(t/c),p-=u*(r/c),M-=u*(l/c),y-=u*(f/c)}const b=t=>M+d/(1+Math.exp(-p*(t-y))),x=l(f,a,b);x.A=d,x.B=p,x.C=M,x.M=y,x.predict=b;const w=g/c;return x.rSquared=r(i,n,o,w,b),x}return i.domain=function(n){return arguments.length?(t=n,i):t},i.x=function(t){return arguments.length?(n=t,i):n},i.y=function(t){return arguments.length?(o=t,i):o},i},Object.defineProperty(t,"__esModule",{value:!0})}); \ No newline at end of file diff --git a/test/exponential-test.js b/test/exponential-test.js index 9350598..9d6babf 100644 --- a/test/exponential-test.js +++ b/test/exponential-test.js @@ -1,5 +1,6 @@ -const tape = require("tape"), - d3 = require("../"); + +import tape from "tape"; +import * as d3 from "../dist/d3-regression.esm.js"; function shuffle(arr){ var m = arr.length, t, i; diff --git a/test/linear-test.js b/test/linear-test.js index 2b17d7f..86a1712 100644 --- a/test/linear-test.js +++ b/test/linear-test.js @@ -1,5 +1,5 @@ -const tape = require("tape"), - d3 = require("../"); +import tape from "tape"; +import * as d3 from "../dist/d3-regression.esm.js"; function shuffle(arr){ var m = arr.length, t, i; diff --git a/test/loess-test.js b/test/loess-test.js index 13c965c..a53cb40 100644 --- a/test/loess-test.js +++ b/test/loess-test.js @@ -1,5 +1,5 @@ -const tape = require("tape"), - d3 = require("../"); +import tape from "tape"; +import * as d3 from "../dist/d3-regression.esm.js"; function shuffle(arr){ var m = arr.length, t, i; diff --git a/test/logarithmic-test.js b/test/logarithmic-test.js index 4f5842c..649fccd 100644 --- a/test/logarithmic-test.js +++ b/test/logarithmic-test.js @@ -1,5 +1,5 @@ -const tape = require("tape"), - d3 = require("../"); +import tape from "tape"; +import * as d3 from "../dist/d3-regression.esm.js"; function shuffle(arr){ var m = arr.length, t, i; diff --git a/test/polynomial-test.js b/test/polynomial-test.js index 7b1d759..06f42da 100644 --- a/test/polynomial-test.js +++ b/test/polynomial-test.js @@ -1,5 +1,5 @@ -const tape = require("tape"), - d3 = require("../"); +import tape from "tape"; +import * as d3 from "../dist/d3-regression.esm.js"; function shuffle(arr){ var m = arr.length, t, i; diff --git a/test/power-test.js b/test/power-test.js index badb642..f5c7396 100644 --- a/test/power-test.js +++ b/test/power-test.js @@ -1,5 +1,5 @@ -const tape = require("tape"), - d3 = require("../"); +import tape from "tape"; +import * as d3 from "../dist/d3-regression.esm.js"; function shuffle(arr){ var m = arr.length, t, i; diff --git a/test/quadratic-test.js b/test/quadratic-test.js index 2a0c6fd..d407d81 100644 --- a/test/quadratic-test.js +++ b/test/quadratic-test.js @@ -1,5 +1,5 @@ -const tape = require("tape"), - d3 = require("../"); +import tape from "tape"; +import * as d3 from "../dist/d3-regression.esm.js"; function shuffle(arr){ var m = arr.length, t, i;