@devmm/puredocs-excel-formula 1.0.1 → 1.0.2

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.
package/dist/index.cjs CHANGED
@@ -2358,6 +2358,7 @@ function datedif(a, c) {
2358
2358
  function registerLookup(r) {
2359
2359
  r.register("VLOOKUP", vlookup, 3, 4);
2360
2360
  r.register("HLOOKUP", hlookup, 3, 4);
2361
+ r.register("XLOOKUP", xlookup, 3, 6);
2361
2362
  r.register("LOOKUP", lookup, 2, 3);
2362
2363
  r.register("INDEX", index_, 2, 3);
2363
2364
  r.register("MATCH", match, 2, 3);
@@ -2434,6 +2435,104 @@ function hlookup(a, c) {
2434
2435
  }
2435
2436
  return best >= 0 ? tbl.get(rowIdx, best) : FormulaValue.errorNA;
2436
2437
  }
2438
+ function wildcardRegex(pattern) {
2439
+ let out = "";
2440
+ for (let i = 0; i < pattern.length; i++) {
2441
+ const ch = pattern[i];
2442
+ if (ch === "~" && i + 1 < pattern.length) {
2443
+ const next = pattern[++i];
2444
+ out += next.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2445
+ } else if (ch === "*") out += ".*";
2446
+ else if (ch === "?") out += ".";
2447
+ else out += ch.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2448
+ }
2449
+ return new RegExp(`^${out}$`, "i");
2450
+ }
2451
+ function findMatch(n, get, lookupVal, matchMode, searchMode) {
2452
+ if ((searchMode === 2 || searchMode === -2) && matchMode !== 2) {
2453
+ const at = searchMode === 2 ? get : (j) => get(n - 1 - j);
2454
+ let lo = 0, hi = n - 1, lastLE = -1, firstGE = -1;
2455
+ while (lo <= hi) {
2456
+ const mid2 = lo + hi >>> 1;
2457
+ const cmp = FormulaValue.compare(at(mid2), lookupVal);
2458
+ if (cmp === 0) return searchMode === 2 ? mid2 : n - 1 - mid2;
2459
+ if (cmp < 0) {
2460
+ lastLE = mid2;
2461
+ lo = mid2 + 1;
2462
+ } else {
2463
+ firstGE = mid2;
2464
+ hi = mid2 - 1;
2465
+ }
2466
+ }
2467
+ const idx = matchMode === -1 ? lastLE : matchMode === 1 ? firstGE : -1;
2468
+ return idx < 0 ? -1 : searchMode === 2 ? idx : n - 1 - idx;
2469
+ }
2470
+ const reverse = searchMode === -1;
2471
+ const order = reverse ? Array.from({ length: n }, (_, k) => n - 1 - k) : Array.from({ length: n }, (_, k) => k);
2472
+ if (matchMode === 2) {
2473
+ const re = wildcardRegex(lookupVal.asText());
2474
+ for (const i of order) if (re.test(get(i).asText())) return i;
2475
+ return -1;
2476
+ }
2477
+ if (matchMode === 0) {
2478
+ for (const i of order) if (FormulaValue.areEqual(get(i), lookupVal)) return i;
2479
+ return -1;
2480
+ }
2481
+ let best = -1;
2482
+ let bestVal = null;
2483
+ for (const i of order) {
2484
+ const v = get(i);
2485
+ const cmp = FormulaValue.compare(v, lookupVal);
2486
+ if (cmp === 0) return i;
2487
+ if (matchMode === -1 && cmp < 0) {
2488
+ if (bestVal === null || FormulaValue.compare(v, bestVal) > 0) {
2489
+ best = i;
2490
+ bestVal = v;
2491
+ }
2492
+ } else if (matchMode === 1 && cmp > 0) {
2493
+ if (bestVal === null || FormulaValue.compare(v, bestVal) < 0) {
2494
+ best = i;
2495
+ bestVal = v;
2496
+ }
2497
+ }
2498
+ }
2499
+ return best;
2500
+ }
2501
+ function xlookup(a, c) {
2502
+ const lookupVal = a[0].evaluate(c);
2503
+ if (lookupVal.isError) return lookupVal;
2504
+ const lookupRaw = a[1].evaluate(c);
2505
+ if (lookupRaw.isError) return lookupRaw;
2506
+ const returnRaw = a[2].evaluate(c);
2507
+ if (returnRaw.isError) return returnRaw;
2508
+ const matchMode = a.length > 4 ? num2(a, c, 4) : { ok: true, n: 0 };
2509
+ if (!matchMode.ok) return matchMode.e;
2510
+ const searchMode = a.length > 5 ? num2(a, c, 5) : { ok: true, n: 1 };
2511
+ if (!searchMode.ok) return searchMode.e;
2512
+ const mm = Math.trunc(matchMode.n), sm = Math.trunc(searchMode.n);
2513
+ const la = lookupRaw.isArray ? lookupRaw.arrayVal : ArrayValue.fromScalar(lookupRaw);
2514
+ if (la.rows > 1 && la.columns > 1) return FormulaValue.errorValue;
2515
+ const vertical = !(la.rows === 1 && la.columns > 1);
2516
+ const n = vertical ? la.rows : la.columns;
2517
+ const get = vertical ? (i) => la.get(i, 0) : (i) => la.get(0, i);
2518
+ const idx = findMatch(n, get, lookupVal, mm, sm);
2519
+ if (idx < 0) {
2520
+ return a.length > 3 ? a[3].evaluate(c) : FormulaValue.errorNA;
2521
+ }
2522
+ const ret = returnRaw.isArray ? returnRaw.arrayVal : ArrayValue.fromScalar(returnRaw);
2523
+ if (vertical) {
2524
+ if (ret.rows !== n) return FormulaValue.errorValue;
2525
+ if (ret.columns === 1) return ret.get(idx, 0);
2526
+ const out2 = new ArrayValue(1, ret.columns);
2527
+ for (let col = 0; col < ret.columns; col++) out2.set(0, col, ret.get(idx, col));
2528
+ return FormulaValue.array(out2);
2529
+ }
2530
+ if (ret.columns !== n) return FormulaValue.errorValue;
2531
+ if (ret.rows === 1) return ret.get(0, idx);
2532
+ const out = new ArrayValue(ret.rows, 1);
2533
+ for (let r = 0; r < ret.rows; r++) out.set(r, 0, ret.get(r, idx));
2534
+ return FormulaValue.array(out);
2535
+ }
2437
2536
  function index_(a, c) {
2438
2537
  const arrVal = a[0].evaluate(c);
2439
2538
  if (arrVal.isError) return arrVal;
@@ -2967,6 +3066,10 @@ function registerFinance(r) {
2967
3066
  r.register("PV", pv, 3, 5);
2968
3067
  r.register("NPV", npv, 2);
2969
3068
  r.register("IRR", irr, 1, 2);
3069
+ r.register("RATE", rate, 3, 6);
3070
+ r.register("NPER", nper, 3, 5);
3071
+ r.register("XNPV", xnpv, 3, 3);
3072
+ r.register("XIRR", xirr, 2, 3);
2970
3073
  }
2971
3074
  function arg(a, c, idx, dflt) {
2972
3075
  if (idx >= a.length) return { ok: true, n: dflt };
@@ -2974,17 +3077,17 @@ function arg(a, c, idx, dflt) {
2974
3077
  return r.ok ? { ok: true, n: r.value } : { ok: false, e: r.error };
2975
3078
  }
2976
3079
  function pmt(a, c) {
2977
- const rate = arg(a, c, 0, 0);
2978
- if (!rate.ok) return rate.e;
2979
- const nper = arg(a, c, 1, 0);
2980
- if (!nper.ok) return nper.e;
3080
+ const rate2 = arg(a, c, 0, 0);
3081
+ if (!rate2.ok) return rate2.e;
3082
+ const nper2 = arg(a, c, 1, 0);
3083
+ if (!nper2.ok) return nper2.e;
2981
3084
  const pvv = arg(a, c, 2, 0);
2982
3085
  if (!pvv.ok) return pvv.e;
2983
3086
  const fvv = arg(a, c, 3, 0);
2984
3087
  if (!fvv.ok) return fvv.e;
2985
3088
  const type = arg(a, c, 4, 0);
2986
3089
  if (!type.ok) return type.e;
2987
- const r = rate.n, n = nper.n, present = pvv.n, future = fvv.n, t = type.n;
3090
+ const r = rate2.n, n = nper2.n, present = pvv.n, future = fvv.n, t = type.n;
2988
3091
  if (n === 0) return FormulaValue.errorNum;
2989
3092
  if (r === 0) return FormulaValue.number(-(present + future) / n);
2990
3093
  const pow = Math.pow(1 + r, n);
@@ -2993,46 +3096,46 @@ function pmt(a, c) {
2993
3096
  return FormulaValue.number(payment);
2994
3097
  }
2995
3098
  function fv(a, c) {
2996
- const rate = arg(a, c, 0, 0);
2997
- if (!rate.ok) return rate.e;
2998
- const nper = arg(a, c, 1, 0);
2999
- if (!nper.ok) return nper.e;
3099
+ const rate2 = arg(a, c, 0, 0);
3100
+ if (!rate2.ok) return rate2.e;
3101
+ const nper2 = arg(a, c, 1, 0);
3102
+ if (!nper2.ok) return nper2.e;
3000
3103
  const pmtv = arg(a, c, 2, 0);
3001
3104
  if (!pmtv.ok) return pmtv.e;
3002
3105
  const pvv = arg(a, c, 3, 0);
3003
3106
  if (!pvv.ok) return pvv.e;
3004
3107
  const type = arg(a, c, 4, 0);
3005
3108
  if (!type.ok) return type.e;
3006
- const r = rate.n, n = nper.n, payment = pmtv.n, present = pvv.n, t = type.n;
3109
+ const r = rate2.n, n = nper2.n, payment = pmtv.n, present = pvv.n, t = type.n;
3007
3110
  if (r === 0) return FormulaValue.number(-(present + payment * n));
3008
3111
  const pow = Math.pow(1 + r, n);
3009
3112
  return FormulaValue.number(-(present * pow + payment * (1 + r * t) * (pow - 1) / r));
3010
3113
  }
3011
3114
  function pv(a, c) {
3012
- const rate = arg(a, c, 0, 0);
3013
- if (!rate.ok) return rate.e;
3014
- const nper = arg(a, c, 1, 0);
3015
- if (!nper.ok) return nper.e;
3115
+ const rate2 = arg(a, c, 0, 0);
3116
+ if (!rate2.ok) return rate2.e;
3117
+ const nper2 = arg(a, c, 1, 0);
3118
+ if (!nper2.ok) return nper2.e;
3016
3119
  const pmtv = arg(a, c, 2, 0);
3017
3120
  if (!pmtv.ok) return pmtv.e;
3018
3121
  const fvv = arg(a, c, 3, 0);
3019
3122
  if (!fvv.ok) return fvv.e;
3020
3123
  const type = arg(a, c, 4, 0);
3021
3124
  if (!type.ok) return type.e;
3022
- const r = rate.n, n = nper.n, payment = pmtv.n, future = fvv.n, t = type.n;
3125
+ const r = rate2.n, n = nper2.n, payment = pmtv.n, future = fvv.n, t = type.n;
3023
3126
  if (r === 0) return FormulaValue.number(-(future + payment * n));
3024
3127
  const pow = Math.pow(1 + r, n);
3025
3128
  return FormulaValue.number(-(future + payment * (1 + r * t) * (pow - 1) / r) / pow);
3026
3129
  }
3027
3130
  function npv(a, c) {
3028
- const rate = exports.FormulaHelper.evalDouble(a[0], c);
3029
- if (!rate.ok) return rate.error;
3030
- if (rate.value === -1) return FormulaValue.errorDiv0;
3131
+ const rate2 = exports.FormulaHelper.evalDouble(a[0], c);
3132
+ if (!rate2.ok) return rate2.error;
3133
+ if (rate2.value === -1) return FormulaValue.errorDiv0;
3031
3134
  const flows = exports.FormulaHelper.collectNumbers(a.slice(1), c);
3032
3135
  if (!flows.ok) return flows.error;
3033
3136
  let total = 0;
3034
3137
  for (let i = 0; i < flows.values.length; i++) {
3035
- total += flows.values[i] / Math.pow(1 + rate.value, i + 1);
3138
+ total += flows.values[i] / Math.pow(1 + rate2.value, i + 1);
3036
3139
  }
3037
3140
  return FormulaValue.number(total);
3038
3141
  }
@@ -3047,27 +3150,177 @@ function irr(a, c) {
3047
3150
  if (!g.ok) return g.error;
3048
3151
  guess = g.value;
3049
3152
  }
3050
- const npvAt = (rate2) => {
3153
+ const npvAt = (rate3) => {
3051
3154
  let sum2 = 0;
3052
- for (let i = 0; i < flows.length; i++) sum2 += flows[i] / Math.pow(1 + rate2, i);
3155
+ for (let i = 0; i < flows.length; i++) sum2 += flows[i] / Math.pow(1 + rate3, i);
3053
3156
  return sum2;
3054
3157
  };
3055
- let rate = guess;
3158
+ let rate2 = guess;
3159
+ for (let iter = 0; iter < 100; iter++) {
3160
+ const f = npvAt(rate2);
3161
+ if (Math.abs(f) < 1e-7) return FormulaValue.number(rate2);
3162
+ const h = 1e-6;
3163
+ const deriv = (npvAt(rate2 + h) - f) / h;
3164
+ if (deriv === 0) break;
3165
+ const next = rate2 - f / deriv;
3166
+ if (!isFinite(next) || next <= -1) break;
3167
+ if (Math.abs(next - rate2) < 1e-9) {
3168
+ rate2 = next;
3169
+ break;
3170
+ }
3171
+ rate2 = next;
3172
+ }
3173
+ if (Math.abs(npvAt(rate2)) < 1e-6) return FormulaValue.number(rate2);
3174
+ return FormulaValue.errorNum;
3175
+ }
3176
+ function tvm(r, n, pmt2, pv2, fv2, type) {
3177
+ if (r === 0) return pv2 + pmt2 * n + fv2;
3178
+ const pow = Math.pow(1 + r, n);
3179
+ return pv2 * pow + pmt2 * (1 + r * type) * (pow - 1) / r + fv2;
3180
+ }
3181
+ function rate(a, c) {
3182
+ const nper2 = arg(a, c, 0, 0);
3183
+ if (!nper2.ok) return nper2.e;
3184
+ const pmtv = arg(a, c, 1, 0);
3185
+ if (!pmtv.ok) return pmtv.e;
3186
+ const pvv = arg(a, c, 2, 0);
3187
+ if (!pvv.ok) return pvv.e;
3188
+ const fvv = arg(a, c, 3, 0);
3189
+ if (!fvv.ok) return fvv.e;
3190
+ const type = arg(a, c, 4, 0);
3191
+ if (!type.ok) return type.e;
3192
+ const gs = arg(a, c, 5, 0.1);
3193
+ if (!gs.ok) return gs.e;
3194
+ const n = nper2.n, pmt2 = pmtv.n, pv2 = pvv.n, fv2 = fvv.n, t = type.n;
3195
+ if (n === 0) return FormulaValue.errorNum;
3196
+ let r = gs.n;
3056
3197
  for (let iter = 0; iter < 100; iter++) {
3057
- const f = npvAt(rate);
3058
- if (Math.abs(f) < 1e-7) return FormulaValue.number(rate);
3198
+ const f = tvm(r, n, pmt2, pv2, fv2, t);
3199
+ if (Math.abs(f) < 1e-8) return FormulaValue.number(r);
3059
3200
  const h = 1e-6;
3060
- const deriv = (npvAt(rate + h) - f) / h;
3201
+ const deriv = (tvm(r + h, n, pmt2, pv2, fv2, t) - f) / h;
3061
3202
  if (deriv === 0) break;
3062
- const next = rate - f / deriv;
3203
+ const next = r - f / deriv;
3063
3204
  if (!isFinite(next) || next <= -1) break;
3064
- if (Math.abs(next - rate) < 1e-9) {
3065
- rate = next;
3205
+ if (Math.abs(next - r) < 1e-10) {
3206
+ r = next;
3066
3207
  break;
3067
3208
  }
3068
- rate = next;
3209
+ r = next;
3069
3210
  }
3070
- if (Math.abs(npvAt(rate)) < 1e-6) return FormulaValue.number(rate);
3211
+ if (Math.abs(tvm(r, n, pmt2, pv2, fv2, t)) < 1e-6) return FormulaValue.number(r);
3212
+ return FormulaValue.errorNum;
3213
+ }
3214
+ function nper(a, c) {
3215
+ const rate2 = arg(a, c, 0, 0);
3216
+ if (!rate2.ok) return rate2.e;
3217
+ const pmtv = arg(a, c, 1, 0);
3218
+ if (!pmtv.ok) return pmtv.e;
3219
+ const pvv = arg(a, c, 2, 0);
3220
+ if (!pvv.ok) return pvv.e;
3221
+ const fvv = arg(a, c, 3, 0);
3222
+ if (!fvv.ok) return fvv.e;
3223
+ const type = arg(a, c, 4, 0);
3224
+ if (!type.ok) return type.e;
3225
+ const r = rate2.n, pmt2 = pmtv.n, pv2 = pvv.n, fv2 = fvv.n, t = type.n;
3226
+ if (r === 0) {
3227
+ if (pmt2 === 0) return FormulaValue.errorNum;
3228
+ return FormulaValue.number(-(pv2 + fv2) / pmt2);
3229
+ }
3230
+ const adj = pmt2 * (1 + r * t);
3231
+ const num5 = adj - fv2 * r;
3232
+ const den = adj + pv2 * r;
3233
+ if (den === 0 || num5 / den <= 0) return FormulaValue.errorNum;
3234
+ const result = Math.log(num5 / den) / Math.log(1 + r);
3235
+ if (!isFinite(result)) return FormulaValue.errorNum;
3236
+ return FormulaValue.number(result);
3237
+ }
3238
+ function flatNumbers(node, c) {
3239
+ const v = node.evaluate(c);
3240
+ if (v.isError) return { ok: false, e: v };
3241
+ const out = [];
3242
+ const push = (item) => {
3243
+ if (item.isError) return item;
3244
+ const d = item.tryAsDouble();
3245
+ if (!d.ok) return FormulaValue.errorValue;
3246
+ out.push(d.value);
3247
+ return null;
3248
+ };
3249
+ if (v.isArray) {
3250
+ for (const item of v.arrayVal.values()) {
3251
+ const err = push(item);
3252
+ if (err) return { ok: false, e: err };
3253
+ }
3254
+ } else {
3255
+ const err = push(v);
3256
+ if (err) return { ok: false, e: err };
3257
+ }
3258
+ return { ok: true, values: out };
3259
+ }
3260
+ function xnpvAt(rate2, values, days2) {
3261
+ let sum2 = 0;
3262
+ for (let i = 0; i < values.length; i++) {
3263
+ sum2 += values[i] / Math.pow(1 + rate2, days2[i] / 365);
3264
+ }
3265
+ return sum2;
3266
+ }
3267
+ function xnpv(a, c) {
3268
+ const rateRes = exports.FormulaHelper.evalDouble(a[0], c);
3269
+ if (!rateRes.ok) return rateRes.error;
3270
+ const rate2 = rateRes.value;
3271
+ if (rate2 <= -1) return FormulaValue.errorNum;
3272
+ const valsRes = flatNumbers(a[1], c);
3273
+ if (!valsRes.ok) return valsRes.e;
3274
+ const datesRes = flatNumbers(a[2], c);
3275
+ if (!datesRes.ok) return datesRes.e;
3276
+ const values = valsRes.values;
3277
+ const dates = datesRes.values;
3278
+ if (values.length === 0 || values.length !== dates.length) return FormulaValue.errorNum;
3279
+ const base = Math.trunc(dates[0]);
3280
+ const days2 = dates.map((d) => Math.trunc(d) - base);
3281
+ if (days2.some((d) => d < 0)) return FormulaValue.errorNum;
3282
+ return FormulaValue.number(xnpvAt(rate2, values, days2));
3283
+ }
3284
+ function xirr(a, c) {
3285
+ const valsRes = flatNumbers(a[0], c);
3286
+ if (!valsRes.ok) return valsRes.e;
3287
+ const datesRes = flatNumbers(a[1], c);
3288
+ if (!datesRes.ok) return datesRes.e;
3289
+ const values = valsRes.values;
3290
+ const dates = datesRes.values;
3291
+ if (values.length < 2 || values.length !== dates.length) return FormulaValue.errorNum;
3292
+ let guess = 0.1;
3293
+ if (a.length > 2) {
3294
+ const g = exports.FormulaHelper.evalDouble(a[2], c);
3295
+ if (!g.ok) return g.error;
3296
+ guess = g.value;
3297
+ }
3298
+ const base = Math.trunc(dates[0]);
3299
+ const days2 = dates.map((d) => Math.trunc(d) - base);
3300
+ if (days2.some((d) => d < 0)) return FormulaValue.errorNum;
3301
+ const derivAt = (rate3) => {
3302
+ let sum2 = 0;
3303
+ for (let i = 0; i < values.length; i++) {
3304
+ const e = days2[i] / 365;
3305
+ sum2 += -e * values[i] / Math.pow(1 + rate3, e + 1);
3306
+ }
3307
+ return sum2;
3308
+ };
3309
+ let rate2 = guess;
3310
+ for (let iter = 0; iter < 100; iter++) {
3311
+ const f = xnpvAt(rate2, values, days2);
3312
+ if (Math.abs(f) < 1e-7) return FormulaValue.number(rate2);
3313
+ const deriv = derivAt(rate2);
3314
+ if (deriv === 0) break;
3315
+ const next = rate2 - f / deriv;
3316
+ if (!isFinite(next) || next <= -1) break;
3317
+ if (Math.abs(next - rate2) < 1e-9) {
3318
+ rate2 = next;
3319
+ break;
3320
+ }
3321
+ rate2 = next;
3322
+ }
3323
+ if (Math.abs(xnpvAt(rate2, values, days2)) < 1e-6) return FormulaValue.number(rate2);
3071
3324
  return FormulaValue.errorNum;
3072
3325
  }
3073
3326
 
@@ -3405,6 +3658,7 @@ function registerArray(r) {
3405
3658
  r.register("SEQUENCE", sequence, 1, 4);
3406
3659
  r.register("UNIQUE", unique, 1, 3);
3407
3660
  r.register("SORT", sort, 1, 4);
3661
+ r.register("SORTBY", sortBy, 2);
3408
3662
  r.register("FILTER", filter, 2, 3);
3409
3663
  r.register("MMULT", mmult, 2, 2);
3410
3664
  r.register("TEXTSPLIT", textSplit, 2, 6);
@@ -3499,6 +3753,58 @@ function sort(a, c) {
3499
3753
  const out = fromRows(sorted);
3500
3754
  return byCol2 ? FormulaValue.array(out.arrayVal.transpose()) : out;
3501
3755
  }
3756
+ function sortBy(a, c) {
3757
+ const v = a[0].evaluate(c);
3758
+ if (v.isError) return v;
3759
+ const data = asArray2(v);
3760
+ const keys = [];
3761
+ let i = 1;
3762
+ while (i < a.length) {
3763
+ const byVal = a[i].evaluate(c);
3764
+ if (byVal.isError) return byVal;
3765
+ i++;
3766
+ let dir = 1;
3767
+ if (i < a.length) {
3768
+ const maybeOrder = a[i].evaluate(c);
3769
+ if (maybeOrder.isError) return maybeOrder;
3770
+ if (!maybeOrder.isArray && maybeOrder.isNumeric) {
3771
+ const d = maybeOrder.tryAsDouble();
3772
+ if (d.ok) {
3773
+ dir = d.value < 0 ? -1 : 1;
3774
+ i++;
3775
+ }
3776
+ }
3777
+ }
3778
+ keys.push({ vals: [...asArray2(byVal).values()], dir });
3779
+ }
3780
+ if (keys.length === 0) return FormulaValue.errorValue;
3781
+ const n = keys[0].vals.length;
3782
+ if (keys.some((k) => k.vals.length !== n)) return FormulaValue.errorValue;
3783
+ const byRow2 = n === data.rows;
3784
+ const byColumn = !byRow2 && n === data.columns;
3785
+ if (!byRow2 && !byColumn) return FormulaValue.errorValue;
3786
+ const perm = Array.from({ length: n }, (_, k) => k);
3787
+ perm.sort((x, y) => {
3788
+ for (const key of keys) {
3789
+ const cmp = FormulaValue.compare(key.vals[x], key.vals[y]) * key.dir;
3790
+ if (cmp !== 0) return cmp;
3791
+ }
3792
+ return x - y;
3793
+ });
3794
+ const out = new ArrayValue(data.rows, data.columns);
3795
+ if (byRow2) {
3796
+ for (let r = 0; r < data.rows; r++) {
3797
+ const src = perm[r];
3798
+ for (let col = 0; col < data.columns; col++) out.set(r, col, data.get(src, col));
3799
+ }
3800
+ } else {
3801
+ for (let col = 0; col < data.columns; col++) {
3802
+ const src = perm[col];
3803
+ for (let r = 0; r < data.rows; r++) out.set(r, col, data.get(r, src));
3804
+ }
3805
+ }
3806
+ return FormulaValue.array(out);
3807
+ }
3502
3808
  function filter(a, c) {
3503
3809
  const v = a[0].evaluate(c);
3504
3810
  if (v.isError) return v;