@odoo/o-spreadsheet 17.0.71 → 17.0.72

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,9 +2,9 @@
2
2
  /**
3
3
  * This file is generated by o-spreadsheet build tools. Do not edit it.
4
4
  * @see https://github.com/odoo/o-spreadsheet
5
- * @version 17.0.71
6
- * @date 2025-08-21T06:37:34.192Z
7
- * @hash 1592964
5
+ * @version 17.0.72
6
+ * @date 2025-09-05T07:33:34.433Z
7
+ * @hash 8c68f3d
8
8
  */
9
9
 
10
10
  'use strict';
@@ -11422,8 +11422,11 @@ function invertMatrix(M) {
11422
11422
  // (a) Swap 2 rows. This multiply the determinant by -1.
11423
11423
  // (b) Multiply a row by a scalar. This multiply the determinant by that scalar.
11424
11424
  // (c) Add to a row a multiple of another row. This does not change the determinant.
11425
+ if (M.length < 1 || M[0].length < 1) {
11426
+ throw new Error("invertMatrix: an empty matrix cannot be inverted.");
11427
+ }
11425
11428
  if (M.length !== M[0].length) {
11426
- throw new Error(`Function [[FUNCTION_NAME]] invert matrix error, only square matrices are invertible`);
11429
+ throw new Error("invertMatrix: only square matrices are invertible");
11427
11430
  }
11428
11431
  let determinant = 1;
11429
11432
  const dim = M.length;
@@ -11492,8 +11495,11 @@ function swapMatrixRows(matrix, row1, row2) {
11492
11495
  * Note: we use indexing [col][row] instead of the standard mathematical notation [row][col]
11493
11496
  */
11494
11497
  function multiplyMatrices(matrix1, matrix2) {
11498
+ if (matrix1.length < 1 || matrix2.length < 1) {
11499
+ throw new Error("multiplyMatrices: empty matrices cannot be multiplied.");
11500
+ }
11495
11501
  if (matrix1.length !== matrix2[0].length) {
11496
- throw new Error(_t("Cannot multiply matrices : incompatible matrices size."));
11502
+ throw new Error("multiplyMatrices: incompatible matrices size.");
11497
11503
  }
11498
11504
  const rowsM1 = matrix1[0].length;
11499
11505
  const colsM2 = matrix2.length;
@@ -11761,6 +11767,7 @@ const MMULT = {
11761
11767
  compute: function (matrix1, matrix2) {
11762
11768
  const _matrix1 = toMatrix(matrix1);
11763
11769
  const _matrix2 = toMatrix(matrix2);
11770
+ assert(() => _matrix1.length > 0 && _matrix2.length > 0, _t("The first and second arguments of [[FUNCTION_NAME]] must be non-empty matrices."));
11764
11771
  assert(() => _matrix1.length === _matrix2[0].length, _t("In [[FUNCTION_NAME]], the number of columns of the first matrix (%s) must be equal to the \
11765
11772
  number of rows of the second matrix (%s).", _matrix1.length.toString(), _matrix2[0].length.toString()));
11766
11773
  if (!isNumberMatrix(_matrix1) || !isNumberMatrix(_matrix2)) {
@@ -13250,6 +13257,16 @@ function assertSameNumberOfElements(...args) {
13250
13257
  const dims = args[0].length;
13251
13258
  args.forEach((arg, i) => assert(() => arg.length === dims, _t("[[FUNCTION_NAME]] has mismatched dimensions for argument %s (%s vs %s).", i.toString(), dims.toString(), arg.length.toString())));
13252
13259
  }
13260
+ function assertNonEmptyMatrix(matrix, argName) {
13261
+ assert(() => matrix.length > 0 && matrix[0].length > 0, _t("[[FUNCTION_NAME]] expects the provided values of %(argName)s to be a non-empty matrix.", {
13262
+ argName,
13263
+ }));
13264
+ }
13265
+ function assertNonEmpty(...data) {
13266
+ if (data.length === 0 || data.some((arg) => arg.length === 0)) {
13267
+ throw new NotAvailableError(_t("[[FUNCTION_NAME]] has no valid input data."));
13268
+ }
13269
+ }
13253
13270
 
13254
13271
  function filterAndFlatData(dataY, dataX) {
13255
13272
  const _flatDataY = [];
@@ -13780,6 +13797,7 @@ const FORECAST = {
13780
13797
  returns: ["NUMBER"],
13781
13798
  compute: function (x, dataY, dataX) {
13782
13799
  const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
13800
+ assertNonEmpty(flatDataX, flatDataY);
13783
13801
  return predictLinearValues([flatDataY], [flatDataX], matrixMap(toMatrix(x), (value) => toNumber(value, this.locale)), true);
13784
13802
  },
13785
13803
  isExported: true,
@@ -13797,6 +13815,7 @@ const GROWTH = {
13797
13815
  ],
13798
13816
  returns: ["NUMBER"],
13799
13817
  compute: function (knownDataY, knownDataX = [], newDataX = [], b = true) {
13818
+ assertNonEmptyMatrix(knownDataY, "known_data_y");
13800
13819
  return expM(predictLinearValues(logM(tryCastAsNumberMatrix(knownDataY, "the first argument (known_data_y)")), tryCastAsNumberMatrix(knownDataX, "the second argument (known_data_x)"), tryCastAsNumberMatrix(newDataX, "the third argument (new_data_y)"), toBoolean(b)));
13801
13820
  },
13802
13821
  };
@@ -13812,6 +13831,7 @@ const INTERCEPT = {
13812
13831
  returns: ["NUMBER"],
13813
13832
  compute: function (dataY, dataX) {
13814
13833
  const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
13834
+ assertNonEmpty(flatDataX, flatDataY);
13815
13835
  const [[], [intercept]] = fullLinearRegression([flatDataX], [flatDataY]);
13816
13836
  return intercept;
13817
13837
  },
@@ -13863,6 +13883,7 @@ const LINEST = {
13863
13883
  ],
13864
13884
  returns: ["NUMBER"],
13865
13885
  compute: function (dataY, dataX = [], calculateB = true, verbose = false) {
13886
+ assertNonEmptyMatrix(dataY, "data_y");
13866
13887
  return fullLinearRegression(tryCastAsNumberMatrix(dataX, "the first argument (data_y)"), tryCastAsNumberMatrix(dataY, "the second argument (data_x)"), toBoolean(calculateB), toBoolean(verbose));
13867
13888
  },
13868
13889
  isExported: true,
@@ -13880,6 +13901,7 @@ const LOGEST = {
13880
13901
  ],
13881
13902
  returns: ["NUMBER"],
13882
13903
  compute: function (dataY, dataX = [], calculateB = true, verbose = false) {
13904
+ assertNonEmptyMatrix(dataY, "data_y");
13883
13905
  const coeffs = fullLinearRegression(tryCastAsNumberMatrix(dataX, "the second argument (data_x)"), logM(tryCastAsNumberMatrix(dataY, "the first argument (data_y)")), toBoolean(calculateB), toBoolean(verbose));
13884
13906
  for (let i = 0; i < coeffs.length; i++) {
13885
13907
  coeffs[i][0] = Math.exp(coeffs[i][0]);
@@ -13902,9 +13924,7 @@ const MATTHEWS = {
13902
13924
  const flatX = dataX.flat();
13903
13925
  const flatY = dataY.flat();
13904
13926
  assertSameNumberOfElements(flatX, flatY);
13905
- if (flatX.length === 0) {
13906
- throw new Error(_t("[[FUNCTION_NAME]] expects non-empty ranges for both parameters."));
13907
- }
13927
+ assertNonEmpty(flatX, flatY);
13908
13928
  const n = flatX.length;
13909
13929
  let trueN = 0, trueP = 0, falseP = 0, falseN = 0;
13910
13930
  for (let i = 0; i < n; ++i) {
@@ -14098,12 +14118,7 @@ const PEARSON = {
14098
14118
  returns: ["NUMBER"],
14099
14119
  compute: function (dataY, dataX) {
14100
14120
  const { flatDataX, flatDataY } = filterAndFlatData(dataX, dataY);
14101
- if (flatDataX.length === 0) {
14102
- throw new Error(_t("[[FUNCTION_NAME]] expects non-empty ranges for both parameters."));
14103
- }
14104
- if (flatDataX.length < 2) {
14105
- throw new Error(_t("[[FUNCTION_NAME]] needs at least two values for both parameters"));
14106
- }
14121
+ assertNonEmpty(flatDataX, flatDataY);
14107
14122
  const n = flatDataX.length;
14108
14123
  let sumX = 0, sumY = 0, sumXY = 0, sumXX = 0, sumYY = 0;
14109
14124
  for (let i = 0; i < n; i++) {
@@ -14189,6 +14204,7 @@ const POLYFIT_COEFFS = {
14189
14204
  returns: ["RANGE<NUMBER>"],
14190
14205
  compute: function (dataY, dataX, order, intercept = true) {
14191
14206
  const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
14207
+ assertNonEmpty(flatDataX, flatDataY);
14192
14208
  return polynomialRegression(flatDataY, flatDataX, toNumber(order, this.locale), toBoolean(intercept));
14193
14209
  },
14194
14210
  isExported: false,
@@ -14209,6 +14225,7 @@ const POLYFIT_FORECAST = {
14209
14225
  compute: function (x, dataY, dataX, order, intercept = true) {
14210
14226
  const _order = toNumber(order, this.locale);
14211
14227
  const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
14228
+ assertNonEmpty(flatDataX, flatDataY);
14212
14229
  const coeffs = polynomialRegression(flatDataY, flatDataX, _order, toBoolean(intercept)).flat();
14213
14230
  return matrixMap(toMatrix(x), (xij) => evaluatePolynomial(coeffs, toNumber(xij, this.locale), _order));
14214
14231
  },
@@ -14334,6 +14351,7 @@ const SLOPE = {
14334
14351
  returns: ["NUMBER"],
14335
14352
  compute: function (dataY, dataX) {
14336
14353
  const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
14354
+ assertNonEmpty(flatDataX, flatDataY);
14337
14355
  const [[slope]] = fullLinearRegression([flatDataX], [flatDataY]);
14338
14356
  return slope;
14339
14357
  },
@@ -14384,6 +14402,7 @@ const SPEARMAN = {
14384
14402
  returns: ["NUMBER"],
14385
14403
  compute: function (dataX, dataY) {
14386
14404
  const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
14405
+ assertNonEmpty(flatDataX, flatDataY);
14387
14406
  const n = flatDataX.length;
14388
14407
  const order = flatDataX.map((e, i) => [e, flatDataY[i]]);
14389
14408
  order.sort((a, b) => a[0] - b[0]);
@@ -14501,6 +14520,7 @@ const STEYX = {
14501
14520
  returns: ["NUMBER"],
14502
14521
  compute: function (dataY, dataX) {
14503
14522
  const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
14523
+ assertNonEmpty(flatDataX, flatDataY);
14504
14524
  const data = fullLinearRegression([flatDataX], [flatDataY], true, true);
14505
14525
  return data[1][2];
14506
14526
  },
@@ -14519,6 +14539,7 @@ const TREND = {
14519
14539
  ],
14520
14540
  returns: ["NUMBER"],
14521
14541
  compute: function (knownDataY, knownDataX = [], newDataX = [], b = true) {
14542
+ assertNonEmptyMatrix(knownDataY, "known_data_y");
14522
14543
  return predictLinearValues(tryCastAsNumberMatrix(knownDataY, "the first argument (known_data_y)"), tryCastAsNumberMatrix(knownDataX, "the second argument (known_data_x)"), tryCastAsNumberMatrix(newDataX, "the third argument (new_data_y)"), toBoolean(b));
14523
14544
  },
14524
14545
  };
@@ -58454,6 +58475,6 @@ exports.setTranslationMethod = setTranslationMethod;
58454
58475
  exports.tokenize = tokenize;
58455
58476
 
58456
58477
 
58457
- __info__.version = "17.0.71";
58458
- __info__.date = "2025-08-21T06:37:34.192Z";
58459
- __info__.hash = "1592964";
58478
+ __info__.version = "17.0.72";
58479
+ __info__.date = "2025-09-05T07:33:34.433Z";
58480
+ __info__.hash = "8c68f3d";
@@ -2,9 +2,9 @@
2
2
  /**
3
3
  * This file is generated by o-spreadsheet build tools. Do not edit it.
4
4
  * @see https://github.com/odoo/o-spreadsheet
5
- * @version 17.0.71
6
- * @date 2025-08-21T06:37:34.192Z
7
- * @hash 1592964
5
+ * @version 17.0.72
6
+ * @date 2025-09-05T07:33:34.433Z
7
+ * @hash 8c68f3d
8
8
  */
9
9
 
10
10
  import { Component, useRef, onMounted, useEffect, onWillPatch, useState, onWillUpdateProps, onPatched, useComponent, useExternalListener, onWillUnmount, onWillStart, xml, useChildSubEnv, useSubEnv, markRaw } from '@odoo/owl';
@@ -11420,8 +11420,11 @@ function invertMatrix(M) {
11420
11420
  // (a) Swap 2 rows. This multiply the determinant by -1.
11421
11421
  // (b) Multiply a row by a scalar. This multiply the determinant by that scalar.
11422
11422
  // (c) Add to a row a multiple of another row. This does not change the determinant.
11423
+ if (M.length < 1 || M[0].length < 1) {
11424
+ throw new Error("invertMatrix: an empty matrix cannot be inverted.");
11425
+ }
11423
11426
  if (M.length !== M[0].length) {
11424
- throw new Error(`Function [[FUNCTION_NAME]] invert matrix error, only square matrices are invertible`);
11427
+ throw new Error("invertMatrix: only square matrices are invertible");
11425
11428
  }
11426
11429
  let determinant = 1;
11427
11430
  const dim = M.length;
@@ -11490,8 +11493,11 @@ function swapMatrixRows(matrix, row1, row2) {
11490
11493
  * Note: we use indexing [col][row] instead of the standard mathematical notation [row][col]
11491
11494
  */
11492
11495
  function multiplyMatrices(matrix1, matrix2) {
11496
+ if (matrix1.length < 1 || matrix2.length < 1) {
11497
+ throw new Error("multiplyMatrices: empty matrices cannot be multiplied.");
11498
+ }
11493
11499
  if (matrix1.length !== matrix2[0].length) {
11494
- throw new Error(_t("Cannot multiply matrices : incompatible matrices size."));
11500
+ throw new Error("multiplyMatrices: incompatible matrices size.");
11495
11501
  }
11496
11502
  const rowsM1 = matrix1[0].length;
11497
11503
  const colsM2 = matrix2.length;
@@ -11759,6 +11765,7 @@ const MMULT = {
11759
11765
  compute: function (matrix1, matrix2) {
11760
11766
  const _matrix1 = toMatrix(matrix1);
11761
11767
  const _matrix2 = toMatrix(matrix2);
11768
+ assert(() => _matrix1.length > 0 && _matrix2.length > 0, _t("The first and second arguments of [[FUNCTION_NAME]] must be non-empty matrices."));
11762
11769
  assert(() => _matrix1.length === _matrix2[0].length, _t("In [[FUNCTION_NAME]], the number of columns of the first matrix (%s) must be equal to the \
11763
11770
  number of rows of the second matrix (%s).", _matrix1.length.toString(), _matrix2[0].length.toString()));
11764
11771
  if (!isNumberMatrix(_matrix1) || !isNumberMatrix(_matrix2)) {
@@ -13248,6 +13255,16 @@ function assertSameNumberOfElements(...args) {
13248
13255
  const dims = args[0].length;
13249
13256
  args.forEach((arg, i) => assert(() => arg.length === dims, _t("[[FUNCTION_NAME]] has mismatched dimensions for argument %s (%s vs %s).", i.toString(), dims.toString(), arg.length.toString())));
13250
13257
  }
13258
+ function assertNonEmptyMatrix(matrix, argName) {
13259
+ assert(() => matrix.length > 0 && matrix[0].length > 0, _t("[[FUNCTION_NAME]] expects the provided values of %(argName)s to be a non-empty matrix.", {
13260
+ argName,
13261
+ }));
13262
+ }
13263
+ function assertNonEmpty(...data) {
13264
+ if (data.length === 0 || data.some((arg) => arg.length === 0)) {
13265
+ throw new NotAvailableError(_t("[[FUNCTION_NAME]] has no valid input data."));
13266
+ }
13267
+ }
13251
13268
 
13252
13269
  function filterAndFlatData(dataY, dataX) {
13253
13270
  const _flatDataY = [];
@@ -13778,6 +13795,7 @@ const FORECAST = {
13778
13795
  returns: ["NUMBER"],
13779
13796
  compute: function (x, dataY, dataX) {
13780
13797
  const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
13798
+ assertNonEmpty(flatDataX, flatDataY);
13781
13799
  return predictLinearValues([flatDataY], [flatDataX], matrixMap(toMatrix(x), (value) => toNumber(value, this.locale)), true);
13782
13800
  },
13783
13801
  isExported: true,
@@ -13795,6 +13813,7 @@ const GROWTH = {
13795
13813
  ],
13796
13814
  returns: ["NUMBER"],
13797
13815
  compute: function (knownDataY, knownDataX = [], newDataX = [], b = true) {
13816
+ assertNonEmptyMatrix(knownDataY, "known_data_y");
13798
13817
  return expM(predictLinearValues(logM(tryCastAsNumberMatrix(knownDataY, "the first argument (known_data_y)")), tryCastAsNumberMatrix(knownDataX, "the second argument (known_data_x)"), tryCastAsNumberMatrix(newDataX, "the third argument (new_data_y)"), toBoolean(b)));
13799
13818
  },
13800
13819
  };
@@ -13810,6 +13829,7 @@ const INTERCEPT = {
13810
13829
  returns: ["NUMBER"],
13811
13830
  compute: function (dataY, dataX) {
13812
13831
  const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
13832
+ assertNonEmpty(flatDataX, flatDataY);
13813
13833
  const [[], [intercept]] = fullLinearRegression([flatDataX], [flatDataY]);
13814
13834
  return intercept;
13815
13835
  },
@@ -13861,6 +13881,7 @@ const LINEST = {
13861
13881
  ],
13862
13882
  returns: ["NUMBER"],
13863
13883
  compute: function (dataY, dataX = [], calculateB = true, verbose = false) {
13884
+ assertNonEmptyMatrix(dataY, "data_y");
13864
13885
  return fullLinearRegression(tryCastAsNumberMatrix(dataX, "the first argument (data_y)"), tryCastAsNumberMatrix(dataY, "the second argument (data_x)"), toBoolean(calculateB), toBoolean(verbose));
13865
13886
  },
13866
13887
  isExported: true,
@@ -13878,6 +13899,7 @@ const LOGEST = {
13878
13899
  ],
13879
13900
  returns: ["NUMBER"],
13880
13901
  compute: function (dataY, dataX = [], calculateB = true, verbose = false) {
13902
+ assertNonEmptyMatrix(dataY, "data_y");
13881
13903
  const coeffs = fullLinearRegression(tryCastAsNumberMatrix(dataX, "the second argument (data_x)"), logM(tryCastAsNumberMatrix(dataY, "the first argument (data_y)")), toBoolean(calculateB), toBoolean(verbose));
13882
13904
  for (let i = 0; i < coeffs.length; i++) {
13883
13905
  coeffs[i][0] = Math.exp(coeffs[i][0]);
@@ -13900,9 +13922,7 @@ const MATTHEWS = {
13900
13922
  const flatX = dataX.flat();
13901
13923
  const flatY = dataY.flat();
13902
13924
  assertSameNumberOfElements(flatX, flatY);
13903
- if (flatX.length === 0) {
13904
- throw new Error(_t("[[FUNCTION_NAME]] expects non-empty ranges for both parameters."));
13905
- }
13925
+ assertNonEmpty(flatX, flatY);
13906
13926
  const n = flatX.length;
13907
13927
  let trueN = 0, trueP = 0, falseP = 0, falseN = 0;
13908
13928
  for (let i = 0; i < n; ++i) {
@@ -14096,12 +14116,7 @@ const PEARSON = {
14096
14116
  returns: ["NUMBER"],
14097
14117
  compute: function (dataY, dataX) {
14098
14118
  const { flatDataX, flatDataY } = filterAndFlatData(dataX, dataY);
14099
- if (flatDataX.length === 0) {
14100
- throw new Error(_t("[[FUNCTION_NAME]] expects non-empty ranges for both parameters."));
14101
- }
14102
- if (flatDataX.length < 2) {
14103
- throw new Error(_t("[[FUNCTION_NAME]] needs at least two values for both parameters"));
14104
- }
14119
+ assertNonEmpty(flatDataX, flatDataY);
14105
14120
  const n = flatDataX.length;
14106
14121
  let sumX = 0, sumY = 0, sumXY = 0, sumXX = 0, sumYY = 0;
14107
14122
  for (let i = 0; i < n; i++) {
@@ -14187,6 +14202,7 @@ const POLYFIT_COEFFS = {
14187
14202
  returns: ["RANGE<NUMBER>"],
14188
14203
  compute: function (dataY, dataX, order, intercept = true) {
14189
14204
  const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
14205
+ assertNonEmpty(flatDataX, flatDataY);
14190
14206
  return polynomialRegression(flatDataY, flatDataX, toNumber(order, this.locale), toBoolean(intercept));
14191
14207
  },
14192
14208
  isExported: false,
@@ -14207,6 +14223,7 @@ const POLYFIT_FORECAST = {
14207
14223
  compute: function (x, dataY, dataX, order, intercept = true) {
14208
14224
  const _order = toNumber(order, this.locale);
14209
14225
  const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
14226
+ assertNonEmpty(flatDataX, flatDataY);
14210
14227
  const coeffs = polynomialRegression(flatDataY, flatDataX, _order, toBoolean(intercept)).flat();
14211
14228
  return matrixMap(toMatrix(x), (xij) => evaluatePolynomial(coeffs, toNumber(xij, this.locale), _order));
14212
14229
  },
@@ -14332,6 +14349,7 @@ const SLOPE = {
14332
14349
  returns: ["NUMBER"],
14333
14350
  compute: function (dataY, dataX) {
14334
14351
  const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
14352
+ assertNonEmpty(flatDataX, flatDataY);
14335
14353
  const [[slope]] = fullLinearRegression([flatDataX], [flatDataY]);
14336
14354
  return slope;
14337
14355
  },
@@ -14382,6 +14400,7 @@ const SPEARMAN = {
14382
14400
  returns: ["NUMBER"],
14383
14401
  compute: function (dataX, dataY) {
14384
14402
  const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
14403
+ assertNonEmpty(flatDataX, flatDataY);
14385
14404
  const n = flatDataX.length;
14386
14405
  const order = flatDataX.map((e, i) => [e, flatDataY[i]]);
14387
14406
  order.sort((a, b) => a[0] - b[0]);
@@ -14499,6 +14518,7 @@ const STEYX = {
14499
14518
  returns: ["NUMBER"],
14500
14519
  compute: function (dataY, dataX) {
14501
14520
  const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
14521
+ assertNonEmpty(flatDataX, flatDataY);
14502
14522
  const data = fullLinearRegression([flatDataX], [flatDataY], true, true);
14503
14523
  return data[1][2];
14504
14524
  },
@@ -14517,6 +14537,7 @@ const TREND = {
14517
14537
  ],
14518
14538
  returns: ["NUMBER"],
14519
14539
  compute: function (knownDataY, knownDataX = [], newDataX = [], b = true) {
14540
+ assertNonEmptyMatrix(knownDataY, "known_data_y");
14520
14541
  return predictLinearValues(tryCastAsNumberMatrix(knownDataY, "the first argument (known_data_y)"), tryCastAsNumberMatrix(knownDataX, "the second argument (known_data_x)"), tryCastAsNumberMatrix(newDataX, "the third argument (new_data_y)"), toBoolean(b));
14521
14542
  },
14522
14543
  };
@@ -58417,6 +58438,6 @@ const constants = {
58417
58438
  export { AbstractChart, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, astToFormula, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, tokenize };
58418
58439
 
58419
58440
 
58420
- __info__.version = "17.0.71";
58421
- __info__.date = "2025-08-21T06:37:34.192Z";
58422
- __info__.hash = "1592964";
58441
+ __info__.version = "17.0.72";
58442
+ __info__.date = "2025-09-05T07:33:34.433Z";
58443
+ __info__.hash = "8c68f3d";
@@ -2,9 +2,9 @@
2
2
  /**
3
3
  * This file is generated by o-spreadsheet build tools. Do not edit it.
4
4
  * @see https://github.com/odoo/o-spreadsheet
5
- * @version 17.0.71
6
- * @date 2025-08-21T06:37:34.192Z
7
- * @hash 1592964
5
+ * @version 17.0.72
6
+ * @date 2025-09-05T07:33:34.433Z
7
+ * @hash 8c68f3d
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -11421,8 +11421,11 @@
11421
11421
  // (a) Swap 2 rows. This multiply the determinant by -1.
11422
11422
  // (b) Multiply a row by a scalar. This multiply the determinant by that scalar.
11423
11423
  // (c) Add to a row a multiple of another row. This does not change the determinant.
11424
+ if (M.length < 1 || M[0].length < 1) {
11425
+ throw new Error("invertMatrix: an empty matrix cannot be inverted.");
11426
+ }
11424
11427
  if (M.length !== M[0].length) {
11425
- throw new Error(`Function [[FUNCTION_NAME]] invert matrix error, only square matrices are invertible`);
11428
+ throw new Error("invertMatrix: only square matrices are invertible");
11426
11429
  }
11427
11430
  let determinant = 1;
11428
11431
  const dim = M.length;
@@ -11491,8 +11494,11 @@
11491
11494
  * Note: we use indexing [col][row] instead of the standard mathematical notation [row][col]
11492
11495
  */
11493
11496
  function multiplyMatrices(matrix1, matrix2) {
11497
+ if (matrix1.length < 1 || matrix2.length < 1) {
11498
+ throw new Error("multiplyMatrices: empty matrices cannot be multiplied.");
11499
+ }
11494
11500
  if (matrix1.length !== matrix2[0].length) {
11495
- throw new Error(_t("Cannot multiply matrices : incompatible matrices size."));
11501
+ throw new Error("multiplyMatrices: incompatible matrices size.");
11496
11502
  }
11497
11503
  const rowsM1 = matrix1[0].length;
11498
11504
  const colsM2 = matrix2.length;
@@ -11760,6 +11766,7 @@
11760
11766
  compute: function (matrix1, matrix2) {
11761
11767
  const _matrix1 = toMatrix(matrix1);
11762
11768
  const _matrix2 = toMatrix(matrix2);
11769
+ assert(() => _matrix1.length > 0 && _matrix2.length > 0, _t("The first and second arguments of [[FUNCTION_NAME]] must be non-empty matrices."));
11763
11770
  assert(() => _matrix1.length === _matrix2[0].length, _t("In [[FUNCTION_NAME]], the number of columns of the first matrix (%s) must be equal to the \
11764
11771
  number of rows of the second matrix (%s).", _matrix1.length.toString(), _matrix2[0].length.toString()));
11765
11772
  if (!isNumberMatrix(_matrix1) || !isNumberMatrix(_matrix2)) {
@@ -13249,6 +13256,16 @@
13249
13256
  const dims = args[0].length;
13250
13257
  args.forEach((arg, i) => assert(() => arg.length === dims, _t("[[FUNCTION_NAME]] has mismatched dimensions for argument %s (%s vs %s).", i.toString(), dims.toString(), arg.length.toString())));
13251
13258
  }
13259
+ function assertNonEmptyMatrix(matrix, argName) {
13260
+ assert(() => matrix.length > 0 && matrix[0].length > 0, _t("[[FUNCTION_NAME]] expects the provided values of %(argName)s to be a non-empty matrix.", {
13261
+ argName,
13262
+ }));
13263
+ }
13264
+ function assertNonEmpty(...data) {
13265
+ if (data.length === 0 || data.some((arg) => arg.length === 0)) {
13266
+ throw new NotAvailableError(_t("[[FUNCTION_NAME]] has no valid input data."));
13267
+ }
13268
+ }
13252
13269
 
13253
13270
  function filterAndFlatData(dataY, dataX) {
13254
13271
  const _flatDataY = [];
@@ -13779,6 +13796,7 @@
13779
13796
  returns: ["NUMBER"],
13780
13797
  compute: function (x, dataY, dataX) {
13781
13798
  const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
13799
+ assertNonEmpty(flatDataX, flatDataY);
13782
13800
  return predictLinearValues([flatDataY], [flatDataX], matrixMap(toMatrix(x), (value) => toNumber(value, this.locale)), true);
13783
13801
  },
13784
13802
  isExported: true,
@@ -13796,6 +13814,7 @@
13796
13814
  ],
13797
13815
  returns: ["NUMBER"],
13798
13816
  compute: function (knownDataY, knownDataX = [], newDataX = [], b = true) {
13817
+ assertNonEmptyMatrix(knownDataY, "known_data_y");
13799
13818
  return expM(predictLinearValues(logM(tryCastAsNumberMatrix(knownDataY, "the first argument (known_data_y)")), tryCastAsNumberMatrix(knownDataX, "the second argument (known_data_x)"), tryCastAsNumberMatrix(newDataX, "the third argument (new_data_y)"), toBoolean(b)));
13800
13819
  },
13801
13820
  };
@@ -13811,6 +13830,7 @@
13811
13830
  returns: ["NUMBER"],
13812
13831
  compute: function (dataY, dataX) {
13813
13832
  const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
13833
+ assertNonEmpty(flatDataX, flatDataY);
13814
13834
  const [[], [intercept]] = fullLinearRegression([flatDataX], [flatDataY]);
13815
13835
  return intercept;
13816
13836
  },
@@ -13862,6 +13882,7 @@
13862
13882
  ],
13863
13883
  returns: ["NUMBER"],
13864
13884
  compute: function (dataY, dataX = [], calculateB = true, verbose = false) {
13885
+ assertNonEmptyMatrix(dataY, "data_y");
13865
13886
  return fullLinearRegression(tryCastAsNumberMatrix(dataX, "the first argument (data_y)"), tryCastAsNumberMatrix(dataY, "the second argument (data_x)"), toBoolean(calculateB), toBoolean(verbose));
13866
13887
  },
13867
13888
  isExported: true,
@@ -13879,6 +13900,7 @@
13879
13900
  ],
13880
13901
  returns: ["NUMBER"],
13881
13902
  compute: function (dataY, dataX = [], calculateB = true, verbose = false) {
13903
+ assertNonEmptyMatrix(dataY, "data_y");
13882
13904
  const coeffs = fullLinearRegression(tryCastAsNumberMatrix(dataX, "the second argument (data_x)"), logM(tryCastAsNumberMatrix(dataY, "the first argument (data_y)")), toBoolean(calculateB), toBoolean(verbose));
13883
13905
  for (let i = 0; i < coeffs.length; i++) {
13884
13906
  coeffs[i][0] = Math.exp(coeffs[i][0]);
@@ -13901,9 +13923,7 @@
13901
13923
  const flatX = dataX.flat();
13902
13924
  const flatY = dataY.flat();
13903
13925
  assertSameNumberOfElements(flatX, flatY);
13904
- if (flatX.length === 0) {
13905
- throw new Error(_t("[[FUNCTION_NAME]] expects non-empty ranges for both parameters."));
13906
- }
13926
+ assertNonEmpty(flatX, flatY);
13907
13927
  const n = flatX.length;
13908
13928
  let trueN = 0, trueP = 0, falseP = 0, falseN = 0;
13909
13929
  for (let i = 0; i < n; ++i) {
@@ -14097,12 +14117,7 @@
14097
14117
  returns: ["NUMBER"],
14098
14118
  compute: function (dataY, dataX) {
14099
14119
  const { flatDataX, flatDataY } = filterAndFlatData(dataX, dataY);
14100
- if (flatDataX.length === 0) {
14101
- throw new Error(_t("[[FUNCTION_NAME]] expects non-empty ranges for both parameters."));
14102
- }
14103
- if (flatDataX.length < 2) {
14104
- throw new Error(_t("[[FUNCTION_NAME]] needs at least two values for both parameters"));
14105
- }
14120
+ assertNonEmpty(flatDataX, flatDataY);
14106
14121
  const n = flatDataX.length;
14107
14122
  let sumX = 0, sumY = 0, sumXY = 0, sumXX = 0, sumYY = 0;
14108
14123
  for (let i = 0; i < n; i++) {
@@ -14188,6 +14203,7 @@
14188
14203
  returns: ["RANGE<NUMBER>"],
14189
14204
  compute: function (dataY, dataX, order, intercept = true) {
14190
14205
  const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
14206
+ assertNonEmpty(flatDataX, flatDataY);
14191
14207
  return polynomialRegression(flatDataY, flatDataX, toNumber(order, this.locale), toBoolean(intercept));
14192
14208
  },
14193
14209
  isExported: false,
@@ -14208,6 +14224,7 @@
14208
14224
  compute: function (x, dataY, dataX, order, intercept = true) {
14209
14225
  const _order = toNumber(order, this.locale);
14210
14226
  const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
14227
+ assertNonEmpty(flatDataX, flatDataY);
14211
14228
  const coeffs = polynomialRegression(flatDataY, flatDataX, _order, toBoolean(intercept)).flat();
14212
14229
  return matrixMap(toMatrix(x), (xij) => evaluatePolynomial(coeffs, toNumber(xij, this.locale), _order));
14213
14230
  },
@@ -14333,6 +14350,7 @@
14333
14350
  returns: ["NUMBER"],
14334
14351
  compute: function (dataY, dataX) {
14335
14352
  const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
14353
+ assertNonEmpty(flatDataX, flatDataY);
14336
14354
  const [[slope]] = fullLinearRegression([flatDataX], [flatDataY]);
14337
14355
  return slope;
14338
14356
  },
@@ -14383,6 +14401,7 @@
14383
14401
  returns: ["NUMBER"],
14384
14402
  compute: function (dataX, dataY) {
14385
14403
  const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
14404
+ assertNonEmpty(flatDataX, flatDataY);
14386
14405
  const n = flatDataX.length;
14387
14406
  const order = flatDataX.map((e, i) => [e, flatDataY[i]]);
14388
14407
  order.sort((a, b) => a[0] - b[0]);
@@ -14500,6 +14519,7 @@
14500
14519
  returns: ["NUMBER"],
14501
14520
  compute: function (dataY, dataX) {
14502
14521
  const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
14522
+ assertNonEmpty(flatDataX, flatDataY);
14503
14523
  const data = fullLinearRegression([flatDataX], [flatDataY], true, true);
14504
14524
  return data[1][2];
14505
14525
  },
@@ -14518,6 +14538,7 @@
14518
14538
  ],
14519
14539
  returns: ["NUMBER"],
14520
14540
  compute: function (knownDataY, knownDataX = [], newDataX = [], b = true) {
14541
+ assertNonEmptyMatrix(knownDataY, "known_data_y");
14521
14542
  return predictLinearValues(tryCastAsNumberMatrix(knownDataY, "the first argument (known_data_y)"), tryCastAsNumberMatrix(knownDataX, "the second argument (known_data_x)"), tryCastAsNumberMatrix(newDataX, "the third argument (new_data_y)"), toBoolean(b));
14522
14543
  },
14523
14544
  };
@@ -58453,9 +58474,9 @@
58453
58474
  exports.tokenize = tokenize;
58454
58475
 
58455
58476
 
58456
- __info__.version = "17.0.71";
58457
- __info__.date = "2025-08-21T06:37:34.192Z";
58458
- __info__.hash = "1592964";
58477
+ __info__.version = "17.0.72";
58478
+ __info__.date = "2025-09-05T07:33:34.433Z";
58479
+ __info__.hash = "8c68f3d";
58459
58480
 
58460
58481
 
58461
58482
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);