@odoo/o-spreadsheet 16.4.0-alpha.1 → 16.4.0-alpha.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/o-spreadsheet.cjs.js +379 -277
- package/dist/o-spreadsheet.d.ts +26 -6
- package/dist/o-spreadsheet.esm.js +378 -278
- package/dist/o-spreadsheet.iife.js +379 -277
- package/dist/o-spreadsheet.iife.min.js +35 -34
- package/package.json +1 -1
|
@@ -2218,249 +2218,6 @@ function splitReference(ref) {
|
|
|
2218
2218
|
return { sheetName, xc };
|
|
2219
2219
|
}
|
|
2220
2220
|
|
|
2221
|
-
class RangeImpl {
|
|
2222
|
-
getSheetSize;
|
|
2223
|
-
_zone;
|
|
2224
|
-
parts;
|
|
2225
|
-
invalidXc;
|
|
2226
|
-
prefixSheet = false;
|
|
2227
|
-
sheetId; // the sheet on which the range is defined
|
|
2228
|
-
invalidSheetName; // the name of any sheet that is invalid
|
|
2229
|
-
constructor(args, getSheetSize) {
|
|
2230
|
-
this.getSheetSize = getSheetSize;
|
|
2231
|
-
this._zone = args.zone;
|
|
2232
|
-
this.parts = args.parts;
|
|
2233
|
-
this.prefixSheet = args.prefixSheet;
|
|
2234
|
-
this.invalidXc = args.invalidXc;
|
|
2235
|
-
this.sheetId = args.sheetId;
|
|
2236
|
-
this.invalidSheetName = args.invalidSheetName;
|
|
2237
|
-
}
|
|
2238
|
-
static fromRange(range, getters) {
|
|
2239
|
-
if (range instanceof RangeImpl) {
|
|
2240
|
-
return range;
|
|
2241
|
-
}
|
|
2242
|
-
return new RangeImpl(range, getters.getSheetSize);
|
|
2243
|
-
}
|
|
2244
|
-
get unboundedZone() {
|
|
2245
|
-
return this._zone;
|
|
2246
|
-
}
|
|
2247
|
-
get zone() {
|
|
2248
|
-
const { left, top, bottom, right } = this._zone;
|
|
2249
|
-
if (right !== undefined && bottom !== undefined)
|
|
2250
|
-
return { left, top, right, bottom };
|
|
2251
|
-
else if (bottom === undefined && right !== undefined) {
|
|
2252
|
-
return { right, top, left, bottom: this.getSheetSize(this.sheetId).numberOfRows - 1 };
|
|
2253
|
-
}
|
|
2254
|
-
else if (right === undefined && bottom !== undefined) {
|
|
2255
|
-
return { bottom, left, top, right: this.getSheetSize(this.sheetId).numberOfCols - 1 };
|
|
2256
|
-
}
|
|
2257
|
-
throw new Error(_lt("Bad zone format"));
|
|
2258
|
-
}
|
|
2259
|
-
static getRangeParts(xc, zone) {
|
|
2260
|
-
const parts = xc.split(":").map((p) => {
|
|
2261
|
-
const isFullRow = isRowReference(p);
|
|
2262
|
-
return {
|
|
2263
|
-
colFixed: isFullRow ? false : p.startsWith("$"),
|
|
2264
|
-
rowFixed: isFullRow ? p.startsWith("$") : p.includes("$", 1),
|
|
2265
|
-
};
|
|
2266
|
-
});
|
|
2267
|
-
const isFullCol = zone.bottom === undefined;
|
|
2268
|
-
const isFullRow = zone.right === undefined;
|
|
2269
|
-
if (isFullCol) {
|
|
2270
|
-
parts[0].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
2271
|
-
parts[1].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
2272
|
-
if (zone.left === zone.right) {
|
|
2273
|
-
parts[0].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
2274
|
-
parts[1].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
2275
|
-
}
|
|
2276
|
-
}
|
|
2277
|
-
if (isFullRow) {
|
|
2278
|
-
parts[0].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
2279
|
-
parts[1].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
2280
|
-
if (zone.top === zone.bottom) {
|
|
2281
|
-
parts[0].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
2282
|
-
parts[1].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
2283
|
-
}
|
|
2284
|
-
}
|
|
2285
|
-
return parts;
|
|
2286
|
-
}
|
|
2287
|
-
get isFullCol() {
|
|
2288
|
-
return this._zone.bottom === undefined;
|
|
2289
|
-
}
|
|
2290
|
-
get isFullRow() {
|
|
2291
|
-
return this._zone.right === undefined;
|
|
2292
|
-
}
|
|
2293
|
-
get rangeData() {
|
|
2294
|
-
return {
|
|
2295
|
-
_zone: this._zone,
|
|
2296
|
-
_sheetId: this.sheetId,
|
|
2297
|
-
};
|
|
2298
|
-
}
|
|
2299
|
-
/**
|
|
2300
|
-
* Check that a zone is valid regarding the order of top-bottom and left-right.
|
|
2301
|
-
* Left should be smaller than right, top should be smaller than bottom.
|
|
2302
|
-
* If it's not the case, simply invert them, and invert the linked parts
|
|
2303
|
-
*/
|
|
2304
|
-
orderZone() {
|
|
2305
|
-
const zone = { ...this._zone };
|
|
2306
|
-
let parts = this.parts;
|
|
2307
|
-
if (zone.right !== undefined && zone.right < zone.left) {
|
|
2308
|
-
let right = zone.right;
|
|
2309
|
-
zone.right = zone.left;
|
|
2310
|
-
zone.left = right;
|
|
2311
|
-
parts = [
|
|
2312
|
-
{
|
|
2313
|
-
colFixed: parts[1]?.colFixed || false,
|
|
2314
|
-
rowFixed: parts[0]?.rowFixed || false,
|
|
2315
|
-
},
|
|
2316
|
-
{
|
|
2317
|
-
colFixed: parts[0]?.colFixed || false,
|
|
2318
|
-
rowFixed: parts[1]?.rowFixed || false,
|
|
2319
|
-
},
|
|
2320
|
-
];
|
|
2321
|
-
}
|
|
2322
|
-
if (zone.bottom !== undefined && zone.bottom < zone.top) {
|
|
2323
|
-
let bottom = zone.bottom;
|
|
2324
|
-
zone.bottom = zone.top;
|
|
2325
|
-
zone.top = bottom;
|
|
2326
|
-
parts = [
|
|
2327
|
-
{
|
|
2328
|
-
colFixed: parts[0]?.colFixed || false,
|
|
2329
|
-
rowFixed: parts[1]?.rowFixed || false,
|
|
2330
|
-
},
|
|
2331
|
-
{
|
|
2332
|
-
colFixed: parts[1]?.colFixed || false,
|
|
2333
|
-
rowFixed: parts[0]?.rowFixed || false,
|
|
2334
|
-
},
|
|
2335
|
-
];
|
|
2336
|
-
}
|
|
2337
|
-
return this.clone({ zone, parts });
|
|
2338
|
-
}
|
|
2339
|
-
/**
|
|
2340
|
-
*
|
|
2341
|
-
* @param rangeParams optional, values to put in the cloned range instead of the current values of the range
|
|
2342
|
-
*/
|
|
2343
|
-
clone(rangeParams) {
|
|
2344
|
-
return new RangeImpl({
|
|
2345
|
-
zone: rangeParams?.zone ? rangeParams.zone : { ...this._zone },
|
|
2346
|
-
sheetId: rangeParams?.sheetId ? rangeParams.sheetId : this.sheetId,
|
|
2347
|
-
invalidSheetName: rangeParams && "invalidSheetName" in rangeParams // 'attr in obj' instead of just 'obj.attr' because we accept undefined values
|
|
2348
|
-
? rangeParams.invalidSheetName
|
|
2349
|
-
: this.invalidSheetName,
|
|
2350
|
-
invalidXc: rangeParams && "invalidXc" in rangeParams ? rangeParams.invalidXc : this.invalidXc,
|
|
2351
|
-
parts: rangeParams?.parts
|
|
2352
|
-
? rangeParams.parts
|
|
2353
|
-
: this.parts.map((part) => {
|
|
2354
|
-
return { rowFixed: part.rowFixed, colFixed: part.colFixed };
|
|
2355
|
-
}),
|
|
2356
|
-
prefixSheet: rangeParams?.prefixSheet ? rangeParams.prefixSheet : this.prefixSheet,
|
|
2357
|
-
}, this.getSheetSize);
|
|
2358
|
-
}
|
|
2359
|
-
}
|
|
2360
|
-
/**
|
|
2361
|
-
* Copy a range. If the range is on the sheetIdFrom, the range will target
|
|
2362
|
-
* sheetIdTo.
|
|
2363
|
-
*/
|
|
2364
|
-
function copyRangeWithNewSheetId(sheetIdFrom, sheetIdTo, range) {
|
|
2365
|
-
const sheetId = range.sheetId === sheetIdFrom ? sheetIdTo : range.sheetId;
|
|
2366
|
-
return range.clone({ sheetId });
|
|
2367
|
-
}
|
|
2368
|
-
/**
|
|
2369
|
-
* Create a range from a xc. If the xc is empty, this function returns undefined.
|
|
2370
|
-
*/
|
|
2371
|
-
function createRange(getters, sheetId, range) {
|
|
2372
|
-
return range ? getters.getRangeFromSheetXC(sheetId, range) : undefined;
|
|
2373
|
-
}
|
|
2374
|
-
|
|
2375
|
-
/** Methods from Odoo Web Utils */
|
|
2376
|
-
/**
|
|
2377
|
-
* This function computes a score that represent the fact that the
|
|
2378
|
-
* string contains the pattern, or not
|
|
2379
|
-
*
|
|
2380
|
-
* - If the score is 0, the string does not contain the letters of the pattern in
|
|
2381
|
-
* the correct order.
|
|
2382
|
-
* - if the score is > 0, it actually contains the letters.
|
|
2383
|
-
*
|
|
2384
|
-
* Better matches will get a higher score: consecutive letters are better,
|
|
2385
|
-
* and a match closer to the beginning of the string is also scored higher.
|
|
2386
|
-
*/
|
|
2387
|
-
function fuzzyMatch(pattern, str) {
|
|
2388
|
-
pattern = pattern.toLocaleLowerCase();
|
|
2389
|
-
str = str.toLocaleLowerCase();
|
|
2390
|
-
let totalScore = 0;
|
|
2391
|
-
let currentScore = 0;
|
|
2392
|
-
let len = str.length;
|
|
2393
|
-
let patternIndex = 0;
|
|
2394
|
-
for (let i = 0; i < len; i++) {
|
|
2395
|
-
if (str[i] === pattern[patternIndex]) {
|
|
2396
|
-
patternIndex++;
|
|
2397
|
-
currentScore += 100 + currentScore - i / 200;
|
|
2398
|
-
}
|
|
2399
|
-
else {
|
|
2400
|
-
currentScore = 0;
|
|
2401
|
-
}
|
|
2402
|
-
totalScore = totalScore + currentScore;
|
|
2403
|
-
}
|
|
2404
|
-
return patternIndex === pattern.length ? totalScore : 0;
|
|
2405
|
-
}
|
|
2406
|
-
/**
|
|
2407
|
-
* Return a list of things that matches a pattern, ordered by their 'score' (
|
|
2408
|
-
* higher score first). An higher score means that the match is better. For
|
|
2409
|
-
* example, consecutive letters are considered a better match.
|
|
2410
|
-
*/
|
|
2411
|
-
function fuzzyLookup(pattern, list, fn) {
|
|
2412
|
-
const results = [];
|
|
2413
|
-
list.forEach((data) => {
|
|
2414
|
-
const score = fuzzyMatch(pattern, fn(data));
|
|
2415
|
-
if (score > 0) {
|
|
2416
|
-
results.push({ score, elem: data });
|
|
2417
|
-
}
|
|
2418
|
-
});
|
|
2419
|
-
// we want better matches first
|
|
2420
|
-
results.sort((a, b) => b.score - a.score);
|
|
2421
|
-
return results.map((r) => r.elem);
|
|
2422
|
-
}
|
|
2423
|
-
|
|
2424
|
-
function createDefaultRows(rowNumber) {
|
|
2425
|
-
const rows = [];
|
|
2426
|
-
for (let i = 0; i < rowNumber; i++) {
|
|
2427
|
-
const row = {
|
|
2428
|
-
cells: {},
|
|
2429
|
-
};
|
|
2430
|
-
rows.push(row);
|
|
2431
|
-
}
|
|
2432
|
-
return rows;
|
|
2433
|
-
}
|
|
2434
|
-
|
|
2435
|
-
/*
|
|
2436
|
-
* https://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript
|
|
2437
|
-
* */
|
|
2438
|
-
class UuidGenerator {
|
|
2439
|
-
isFastIdStrategy = false;
|
|
2440
|
-
fastIdStart = 0;
|
|
2441
|
-
setIsFastStrategy(isFast) {
|
|
2442
|
-
this.isFastIdStrategy = isFast;
|
|
2443
|
-
}
|
|
2444
|
-
uuidv4() {
|
|
2445
|
-
if (this.isFastIdStrategy) {
|
|
2446
|
-
this.fastIdStart++;
|
|
2447
|
-
return String(this.fastIdStart);
|
|
2448
|
-
//@ts-ignore
|
|
2449
|
-
}
|
|
2450
|
-
else if (window.crypto && window.crypto.getRandomValues) {
|
|
2451
|
-
//@ts-ignore
|
|
2452
|
-
return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, (c) => (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16));
|
|
2453
|
-
}
|
|
2454
|
-
else {
|
|
2455
|
-
// mainly for jest and other browsers that do not have the crypto functionality
|
|
2456
|
-
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
|
|
2457
|
-
var r = (Math.random() * 16) | 0, v = c == "x" ? r : (r & 0x3) | 0x8;
|
|
2458
|
-
return v.toString(16);
|
|
2459
|
-
});
|
|
2460
|
-
}
|
|
2461
|
-
}
|
|
2462
|
-
}
|
|
2463
|
-
|
|
2464
2221
|
/**
|
|
2465
2222
|
* Convert from a cartesian reference to a Zone
|
|
2466
2223
|
* The range boundaries will be kept in the same order as the
|
|
@@ -3067,6 +2824,287 @@ function getZonesRows(zones) {
|
|
|
3067
2824
|
return set;
|
|
3068
2825
|
}
|
|
3069
2826
|
|
|
2827
|
+
class RangeImpl {
|
|
2828
|
+
getSheetSize;
|
|
2829
|
+
_zone;
|
|
2830
|
+
parts;
|
|
2831
|
+
invalidXc;
|
|
2832
|
+
prefixSheet = false;
|
|
2833
|
+
sheetId; // the sheet on which the range is defined
|
|
2834
|
+
invalidSheetName; // the name of any sheet that is invalid
|
|
2835
|
+
constructor(args, getSheetSize) {
|
|
2836
|
+
this.getSheetSize = getSheetSize;
|
|
2837
|
+
this._zone = args.zone;
|
|
2838
|
+
this.parts = args.parts;
|
|
2839
|
+
this.prefixSheet = args.prefixSheet;
|
|
2840
|
+
this.invalidXc = args.invalidXc;
|
|
2841
|
+
this.sheetId = args.sheetId;
|
|
2842
|
+
this.invalidSheetName = args.invalidSheetName;
|
|
2843
|
+
}
|
|
2844
|
+
static fromRange(range, getters) {
|
|
2845
|
+
if (range instanceof RangeImpl) {
|
|
2846
|
+
return range;
|
|
2847
|
+
}
|
|
2848
|
+
return new RangeImpl(range, getters.getSheetSize);
|
|
2849
|
+
}
|
|
2850
|
+
get unboundedZone() {
|
|
2851
|
+
return this._zone;
|
|
2852
|
+
}
|
|
2853
|
+
get zone() {
|
|
2854
|
+
const { left, top, bottom, right } = this._zone;
|
|
2855
|
+
if (right !== undefined && bottom !== undefined)
|
|
2856
|
+
return { left, top, right, bottom };
|
|
2857
|
+
else if (bottom === undefined && right !== undefined) {
|
|
2858
|
+
return { right, top, left, bottom: this.getSheetSize(this.sheetId).numberOfRows - 1 };
|
|
2859
|
+
}
|
|
2860
|
+
else if (right === undefined && bottom !== undefined) {
|
|
2861
|
+
return { bottom, left, top, right: this.getSheetSize(this.sheetId).numberOfCols - 1 };
|
|
2862
|
+
}
|
|
2863
|
+
throw new Error(_lt("Bad zone format"));
|
|
2864
|
+
}
|
|
2865
|
+
static getRangeParts(xc, zone) {
|
|
2866
|
+
const parts = xc.split(":").map((p) => {
|
|
2867
|
+
const isFullRow = isRowReference(p);
|
|
2868
|
+
return {
|
|
2869
|
+
colFixed: isFullRow ? false : p.startsWith("$"),
|
|
2870
|
+
rowFixed: isFullRow ? p.startsWith("$") : p.includes("$", 1),
|
|
2871
|
+
};
|
|
2872
|
+
});
|
|
2873
|
+
const isFullCol = zone.bottom === undefined;
|
|
2874
|
+
const isFullRow = zone.right === undefined;
|
|
2875
|
+
if (isFullCol) {
|
|
2876
|
+
parts[0].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
2877
|
+
parts[1].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
2878
|
+
if (zone.left === zone.right) {
|
|
2879
|
+
parts[0].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
2880
|
+
parts[1].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
2881
|
+
}
|
|
2882
|
+
}
|
|
2883
|
+
if (isFullRow) {
|
|
2884
|
+
parts[0].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
2885
|
+
parts[1].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
2886
|
+
if (zone.top === zone.bottom) {
|
|
2887
|
+
parts[0].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
2888
|
+
parts[1].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
2889
|
+
}
|
|
2890
|
+
}
|
|
2891
|
+
return parts;
|
|
2892
|
+
}
|
|
2893
|
+
get isFullCol() {
|
|
2894
|
+
return this._zone.bottom === undefined;
|
|
2895
|
+
}
|
|
2896
|
+
get isFullRow() {
|
|
2897
|
+
return this._zone.right === undefined;
|
|
2898
|
+
}
|
|
2899
|
+
get rangeData() {
|
|
2900
|
+
return {
|
|
2901
|
+
_zone: this._zone,
|
|
2902
|
+
_sheetId: this.sheetId,
|
|
2903
|
+
};
|
|
2904
|
+
}
|
|
2905
|
+
/**
|
|
2906
|
+
* Check that a zone is valid regarding the order of top-bottom and left-right.
|
|
2907
|
+
* Left should be smaller than right, top should be smaller than bottom.
|
|
2908
|
+
* If it's not the case, simply invert them, and invert the linked parts
|
|
2909
|
+
*/
|
|
2910
|
+
orderZone() {
|
|
2911
|
+
const zone = { ...this._zone };
|
|
2912
|
+
let parts = this.parts;
|
|
2913
|
+
if (zone.right !== undefined && zone.right < zone.left) {
|
|
2914
|
+
let right = zone.right;
|
|
2915
|
+
zone.right = zone.left;
|
|
2916
|
+
zone.left = right;
|
|
2917
|
+
parts = [
|
|
2918
|
+
{
|
|
2919
|
+
colFixed: parts[1]?.colFixed || false,
|
|
2920
|
+
rowFixed: parts[0]?.rowFixed || false,
|
|
2921
|
+
},
|
|
2922
|
+
{
|
|
2923
|
+
colFixed: parts[0]?.colFixed || false,
|
|
2924
|
+
rowFixed: parts[1]?.rowFixed || false,
|
|
2925
|
+
},
|
|
2926
|
+
];
|
|
2927
|
+
}
|
|
2928
|
+
if (zone.bottom !== undefined && zone.bottom < zone.top) {
|
|
2929
|
+
let bottom = zone.bottom;
|
|
2930
|
+
zone.bottom = zone.top;
|
|
2931
|
+
zone.top = bottom;
|
|
2932
|
+
parts = [
|
|
2933
|
+
{
|
|
2934
|
+
colFixed: parts[0]?.colFixed || false,
|
|
2935
|
+
rowFixed: parts[1]?.rowFixed || false,
|
|
2936
|
+
},
|
|
2937
|
+
{
|
|
2938
|
+
colFixed: parts[1]?.colFixed || false,
|
|
2939
|
+
rowFixed: parts[0]?.rowFixed || false,
|
|
2940
|
+
},
|
|
2941
|
+
];
|
|
2942
|
+
}
|
|
2943
|
+
return this.clone({ zone, parts });
|
|
2944
|
+
}
|
|
2945
|
+
/**
|
|
2946
|
+
*
|
|
2947
|
+
* @param rangeParams optional, values to put in the cloned range instead of the current values of the range
|
|
2948
|
+
*/
|
|
2949
|
+
clone(rangeParams) {
|
|
2950
|
+
return new RangeImpl({
|
|
2951
|
+
zone: rangeParams?.zone ? rangeParams.zone : { ...this._zone },
|
|
2952
|
+
sheetId: rangeParams?.sheetId ? rangeParams.sheetId : this.sheetId,
|
|
2953
|
+
invalidSheetName: rangeParams && "invalidSheetName" in rangeParams // 'attr in obj' instead of just 'obj.attr' because we accept undefined values
|
|
2954
|
+
? rangeParams.invalidSheetName
|
|
2955
|
+
: this.invalidSheetName,
|
|
2956
|
+
invalidXc: rangeParams && "invalidXc" in rangeParams ? rangeParams.invalidXc : this.invalidXc,
|
|
2957
|
+
parts: rangeParams?.parts
|
|
2958
|
+
? rangeParams.parts
|
|
2959
|
+
: this.parts.map((part) => {
|
|
2960
|
+
return { rowFixed: part.rowFixed, colFixed: part.colFixed };
|
|
2961
|
+
}),
|
|
2962
|
+
prefixSheet: rangeParams?.prefixSheet ? rangeParams.prefixSheet : this.prefixSheet,
|
|
2963
|
+
}, this.getSheetSize);
|
|
2964
|
+
}
|
|
2965
|
+
}
|
|
2966
|
+
/**
|
|
2967
|
+
* Copy a range. If the range is on the sheetIdFrom, the range will target
|
|
2968
|
+
* sheetIdTo.
|
|
2969
|
+
*/
|
|
2970
|
+
function copyRangeWithNewSheetId(sheetIdFrom, sheetIdTo, range) {
|
|
2971
|
+
const sheetId = range.sheetId === sheetIdFrom ? sheetIdTo : range.sheetId;
|
|
2972
|
+
return range.clone({ sheetId });
|
|
2973
|
+
}
|
|
2974
|
+
/**
|
|
2975
|
+
* Create a range from a xc. If the xc is empty, this function returns undefined.
|
|
2976
|
+
*/
|
|
2977
|
+
function createRange(getters, sheetId, range) {
|
|
2978
|
+
return range ? getters.getRangeFromSheetXC(sheetId, range) : undefined;
|
|
2979
|
+
}
|
|
2980
|
+
/**
|
|
2981
|
+
* Spread multiple colrows zone to one row/col zone and add a many new input range as needed.
|
|
2982
|
+
* For example, A1:B4 will become [A1:A4, B1:B4]
|
|
2983
|
+
*/
|
|
2984
|
+
function spreadRange(ranges) {
|
|
2985
|
+
const postProcessedRanges = [];
|
|
2986
|
+
for (const range of ranges) {
|
|
2987
|
+
const { sheetName } = splitReference(range);
|
|
2988
|
+
const sheetPrefix = sheetName ? `${sheetName}!` : "";
|
|
2989
|
+
const zone = toUnboundedZone(range);
|
|
2990
|
+
if (zone.bottom !== zone.top && zone.left != zone.right) {
|
|
2991
|
+
if (zone.right) {
|
|
2992
|
+
for (let j = zone.left; j <= zone.right; ++j) {
|
|
2993
|
+
postProcessedRanges.push(`${sheetPrefix}${zoneToXc({
|
|
2994
|
+
left: j,
|
|
2995
|
+
right: j,
|
|
2996
|
+
top: zone.top,
|
|
2997
|
+
bottom: zone.bottom,
|
|
2998
|
+
})}`);
|
|
2999
|
+
}
|
|
3000
|
+
}
|
|
3001
|
+
else {
|
|
3002
|
+
for (let j = zone.top; j <= zone.bottom; ++j) {
|
|
3003
|
+
postProcessedRanges.push(`${sheetPrefix}${zoneToXc({
|
|
3004
|
+
left: zone.left,
|
|
3005
|
+
right: zone.right,
|
|
3006
|
+
top: j,
|
|
3007
|
+
bottom: j,
|
|
3008
|
+
})}`);
|
|
3009
|
+
}
|
|
3010
|
+
}
|
|
3011
|
+
}
|
|
3012
|
+
else {
|
|
3013
|
+
postProcessedRanges.push(range);
|
|
3014
|
+
}
|
|
3015
|
+
}
|
|
3016
|
+
return postProcessedRanges;
|
|
3017
|
+
}
|
|
3018
|
+
|
|
3019
|
+
/** Methods from Odoo Web Utils */
|
|
3020
|
+
/**
|
|
3021
|
+
* This function computes a score that represent the fact that the
|
|
3022
|
+
* string contains the pattern, or not
|
|
3023
|
+
*
|
|
3024
|
+
* - If the score is 0, the string does not contain the letters of the pattern in
|
|
3025
|
+
* the correct order.
|
|
3026
|
+
* - if the score is > 0, it actually contains the letters.
|
|
3027
|
+
*
|
|
3028
|
+
* Better matches will get a higher score: consecutive letters are better,
|
|
3029
|
+
* and a match closer to the beginning of the string is also scored higher.
|
|
3030
|
+
*/
|
|
3031
|
+
function fuzzyMatch(pattern, str) {
|
|
3032
|
+
pattern = pattern.toLocaleLowerCase();
|
|
3033
|
+
str = str.toLocaleLowerCase();
|
|
3034
|
+
let totalScore = 0;
|
|
3035
|
+
let currentScore = 0;
|
|
3036
|
+
let len = str.length;
|
|
3037
|
+
let patternIndex = 0;
|
|
3038
|
+
for (let i = 0; i < len; i++) {
|
|
3039
|
+
if (str[i] === pattern[patternIndex]) {
|
|
3040
|
+
patternIndex++;
|
|
3041
|
+
currentScore += 100 + currentScore - i / 200;
|
|
3042
|
+
}
|
|
3043
|
+
else {
|
|
3044
|
+
currentScore = 0;
|
|
3045
|
+
}
|
|
3046
|
+
totalScore = totalScore + currentScore;
|
|
3047
|
+
}
|
|
3048
|
+
return patternIndex === pattern.length ? totalScore : 0;
|
|
3049
|
+
}
|
|
3050
|
+
/**
|
|
3051
|
+
* Return a list of things that matches a pattern, ordered by their 'score' (
|
|
3052
|
+
* higher score first). An higher score means that the match is better. For
|
|
3053
|
+
* example, consecutive letters are considered a better match.
|
|
3054
|
+
*/
|
|
3055
|
+
function fuzzyLookup(pattern, list, fn) {
|
|
3056
|
+
const results = [];
|
|
3057
|
+
list.forEach((data) => {
|
|
3058
|
+
const score = fuzzyMatch(pattern, fn(data));
|
|
3059
|
+
if (score > 0) {
|
|
3060
|
+
results.push({ score, elem: data });
|
|
3061
|
+
}
|
|
3062
|
+
});
|
|
3063
|
+
// we want better matches first
|
|
3064
|
+
results.sort((a, b) => b.score - a.score);
|
|
3065
|
+
return results.map((r) => r.elem);
|
|
3066
|
+
}
|
|
3067
|
+
|
|
3068
|
+
function createDefaultRows(rowNumber) {
|
|
3069
|
+
const rows = [];
|
|
3070
|
+
for (let i = 0; i < rowNumber; i++) {
|
|
3071
|
+
const row = {
|
|
3072
|
+
cells: {},
|
|
3073
|
+
};
|
|
3074
|
+
rows.push(row);
|
|
3075
|
+
}
|
|
3076
|
+
return rows;
|
|
3077
|
+
}
|
|
3078
|
+
|
|
3079
|
+
/*
|
|
3080
|
+
* https://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript
|
|
3081
|
+
* */
|
|
3082
|
+
class UuidGenerator {
|
|
3083
|
+
isFastIdStrategy = false;
|
|
3084
|
+
fastIdStart = 0;
|
|
3085
|
+
setIsFastStrategy(isFast) {
|
|
3086
|
+
this.isFastIdStrategy = isFast;
|
|
3087
|
+
}
|
|
3088
|
+
uuidv4() {
|
|
3089
|
+
if (this.isFastIdStrategy) {
|
|
3090
|
+
this.fastIdStart++;
|
|
3091
|
+
return String(this.fastIdStart);
|
|
3092
|
+
//@ts-ignore
|
|
3093
|
+
}
|
|
3094
|
+
else if (window.crypto && window.crypto.getRandomValues) {
|
|
3095
|
+
//@ts-ignore
|
|
3096
|
+
return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, (c) => (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16));
|
|
3097
|
+
}
|
|
3098
|
+
else {
|
|
3099
|
+
// mainly for jest and other browsers that do not have the crypto functionality
|
|
3100
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
|
|
3101
|
+
var r = (Math.random() * 16) | 0, v = c == "x" ? r : (r & 0x3) | 0x8;
|
|
3102
|
+
return v.toString(16);
|
|
3103
|
+
});
|
|
3104
|
+
}
|
|
3105
|
+
}
|
|
3106
|
+
}
|
|
3107
|
+
|
|
3070
3108
|
class ChartJsComponent extends owl.Component {
|
|
3071
3109
|
static template = "o-spreadsheet-ChartJsComponent";
|
|
3072
3110
|
canvas = owl.useRef("graphContainer");
|
|
@@ -17646,50 +17684,51 @@ const uuidGenerator$1 = new UuidGenerator();
|
|
|
17646
17684
|
css /* scss */ `
|
|
17647
17685
|
.o-selection {
|
|
17648
17686
|
.o-selection-input {
|
|
17649
|
-
|
|
17650
|
-
flex-direction: row;
|
|
17687
|
+
padding: 2px 0px;
|
|
17651
17688
|
|
|
17652
17689
|
input {
|
|
17653
17690
|
padding: 4px 6px;
|
|
17654
17691
|
border-radius: 4px;
|
|
17655
17692
|
box-sizing: border-box;
|
|
17656
|
-
flex-grow: 2;
|
|
17657
17693
|
}
|
|
17658
17694
|
input:focus {
|
|
17659
17695
|
outline: none;
|
|
17660
17696
|
}
|
|
17661
17697
|
input.o-required,
|
|
17662
17698
|
input.o-focused {
|
|
17663
|
-
border
|
|
17664
|
-
padding: 3px 5px;
|
|
17699
|
+
border: 1px solid;
|
|
17665
17700
|
}
|
|
17666
17701
|
input.o-focused {
|
|
17667
|
-
border-
|
|
17702
|
+
border-width: 2px;
|
|
17703
|
+
padding: 3px 5px;
|
|
17668
17704
|
}
|
|
17669
17705
|
input.o-invalid {
|
|
17670
|
-
|
|
17706
|
+
/* The background-color is similar to the bootstrap alert-danger class but, because of the commit 0358a76d,
|
|
17707
|
+
* which avoids being parasitized by the dark-mode in spreadsheet, we cannot use this class.
|
|
17708
|
+
* TODO: Replace with the bootstrap alert-danger class when we support dark mode
|
|
17709
|
+
*/
|
|
17710
|
+
background-color: #ffdddd;
|
|
17711
|
+
border-width: 2px;
|
|
17671
17712
|
}
|
|
17672
17713
|
button.o-btn {
|
|
17673
|
-
background: transparent;
|
|
17674
|
-
border: none;
|
|
17675
17714
|
color: #333;
|
|
17676
|
-
cursor: pointer;
|
|
17677
17715
|
}
|
|
17678
17716
|
button.o-btn-action {
|
|
17679
17717
|
margin: 8px 1px;
|
|
17680
17718
|
border-radius: 4px;
|
|
17681
|
-
background: transparent;
|
|
17682
17719
|
border: 1px solid #dadce0;
|
|
17683
17720
|
color: #188038;
|
|
17684
|
-
font-weight: bold;
|
|
17685
17721
|
font-size: 14px;
|
|
17686
17722
|
height: 25px;
|
|
17687
17723
|
}
|
|
17724
|
+
.error-icon {
|
|
17725
|
+
right: 7px;
|
|
17726
|
+
top: 7px;
|
|
17727
|
+
}
|
|
17688
17728
|
}
|
|
17689
17729
|
/** Make the character a bit bigger
|
|
17690
17730
|
compared to its neighbor INPUT box */
|
|
17691
17731
|
.o-remove-selection {
|
|
17692
|
-
font-weight: bold;
|
|
17693
17732
|
font-size: calc(100% + 4px);
|
|
17694
17733
|
}
|
|
17695
17734
|
}
|
|
@@ -17705,7 +17744,7 @@ css /* scss */ `
|
|
|
17705
17744
|
class SelectionInput extends owl.Component {
|
|
17706
17745
|
static template = "o-spreadsheet-SelectionInput";
|
|
17707
17746
|
id = uuidGenerator$1.uuidv4();
|
|
17708
|
-
previousRanges = this.props.ranges || [];
|
|
17747
|
+
previousRanges = this.props.ranges() || [];
|
|
17709
17748
|
originSheet = this.env.model.getters.getActiveSheetId();
|
|
17710
17749
|
state = owl.useState({
|
|
17711
17750
|
isMissing: false,
|
|
@@ -17713,11 +17752,11 @@ class SelectionInput extends owl.Component {
|
|
|
17713
17752
|
});
|
|
17714
17753
|
focusedInput = owl.useRef("focusedInput");
|
|
17715
17754
|
get ranges() {
|
|
17716
|
-
const
|
|
17717
|
-
const ranges =
|
|
17718
|
-
?
|
|
17719
|
-
: this.props.ranges
|
|
17720
|
-
? this.props.ranges.map((xc, id) => ({
|
|
17755
|
+
const existingSelectionRanges = this.env.model.getters.getSelectionInput(this.id);
|
|
17756
|
+
const ranges = existingSelectionRanges.length
|
|
17757
|
+
? existingSelectionRanges
|
|
17758
|
+
: this.props.ranges()
|
|
17759
|
+
? this.props.ranges().map((xc, id) => ({
|
|
17721
17760
|
xc,
|
|
17722
17761
|
id,
|
|
17723
17762
|
isFocused: false,
|
|
@@ -17737,6 +17776,12 @@ class SelectionInput extends owl.Component {
|
|
|
17737
17776
|
get isInvalid() {
|
|
17738
17777
|
return this.props.isInvalid || this.state.isMissing;
|
|
17739
17778
|
}
|
|
17779
|
+
get isConfirmable() {
|
|
17780
|
+
return this.hasFocus && this.ranges.every((range) => range.isValidRange);
|
|
17781
|
+
}
|
|
17782
|
+
get isResettable() {
|
|
17783
|
+
return this.previousRanges.join() !== this.ranges.map((r) => r.xc).join();
|
|
17784
|
+
}
|
|
17740
17785
|
setup() {
|
|
17741
17786
|
owl.useEffect(() => this.focusedInput.el?.focus(), () => [this.focusedInput.el]);
|
|
17742
17787
|
owl.onMounted(() => this.enableNewSelectionInput());
|
|
@@ -17746,7 +17791,7 @@ class SelectionInput extends owl.Component {
|
|
|
17746
17791
|
enableNewSelectionInput() {
|
|
17747
17792
|
this.env.model.dispatch("ENABLE_NEW_SELECTION_INPUT", {
|
|
17748
17793
|
id: this.id,
|
|
17749
|
-
initialRanges: this.props.ranges,
|
|
17794
|
+
initialRanges: this.props.ranges(),
|
|
17750
17795
|
hasSingleRange: this.props.hasSingleRange,
|
|
17751
17796
|
});
|
|
17752
17797
|
}
|
|
@@ -17755,7 +17800,8 @@ class SelectionInput extends owl.Component {
|
|
|
17755
17800
|
}
|
|
17756
17801
|
checkChange() {
|
|
17757
17802
|
const value = this.env.model.getters.getSelectionInputValue(this.id);
|
|
17758
|
-
|
|
17803
|
+
const valid = !this.isInvalid && this.ranges.every((range) => range.isValidRange);
|
|
17804
|
+
if (valid && this.previousRanges.join() !== value.join()) {
|
|
17759
17805
|
this.triggerChange();
|
|
17760
17806
|
}
|
|
17761
17807
|
}
|
|
@@ -17766,7 +17812,6 @@ class SelectionInput extends owl.Component {
|
|
|
17766
17812
|
triggerChange() {
|
|
17767
17813
|
const ranges = this.env.model.getters.getSelectionInputValue(this.id);
|
|
17768
17814
|
this.props.onSelectionChanged?.(ranges);
|
|
17769
|
-
this.previousRanges = ranges;
|
|
17770
17815
|
}
|
|
17771
17816
|
onKeydown(ev) {
|
|
17772
17817
|
if (ev.key === "F2") {
|
|
@@ -17816,10 +17861,37 @@ class SelectionInput extends owl.Component {
|
|
|
17816
17861
|
});
|
|
17817
17862
|
this.triggerChange();
|
|
17818
17863
|
}
|
|
17864
|
+
reset() {
|
|
17865
|
+
const existingSelectionRanges = this.env.model.getters.getSelectionInput(this.id);
|
|
17866
|
+
for (const range of existingSelectionRanges) {
|
|
17867
|
+
this.env.model.dispatch("REMOVE_RANGE", {
|
|
17868
|
+
id: this.id,
|
|
17869
|
+
rangeId: range.id,
|
|
17870
|
+
});
|
|
17871
|
+
}
|
|
17872
|
+
for (const range of this.previousRanges) {
|
|
17873
|
+
this.env.model.dispatch("ADD_RANGE", { id: this.id, value: range });
|
|
17874
|
+
}
|
|
17875
|
+
this.confirm();
|
|
17876
|
+
}
|
|
17819
17877
|
confirm() {
|
|
17820
|
-
|
|
17821
|
-
const
|
|
17822
|
-
|
|
17878
|
+
let anyValidInput = false;
|
|
17879
|
+
const existingSelectionRanges = this.env.model.getters.getSelectionInput(this.id);
|
|
17880
|
+
const existingSelectionXcs = [];
|
|
17881
|
+
for (const range of existingSelectionRanges) {
|
|
17882
|
+
if (range.xc === "") {
|
|
17883
|
+
this.env.model.dispatch("REMOVE_RANGE", {
|
|
17884
|
+
id: this.id,
|
|
17885
|
+
rangeId: range.id,
|
|
17886
|
+
});
|
|
17887
|
+
continue;
|
|
17888
|
+
}
|
|
17889
|
+
existingSelectionXcs.push(range.xc);
|
|
17890
|
+
if (this.env.model.getters.isRangeValid(range.xc)) {
|
|
17891
|
+
anyValidInput = true;
|
|
17892
|
+
}
|
|
17893
|
+
}
|
|
17894
|
+
if (this.props.required && !anyValidInput) {
|
|
17823
17895
|
this.state.isMissing = true;
|
|
17824
17896
|
}
|
|
17825
17897
|
const activeSheetId = this.env.model.getters.getActiveSheetId();
|
|
@@ -17829,11 +17901,17 @@ class SelectionInput extends owl.Component {
|
|
|
17829
17901
|
sheetIdTo: this.originSheet,
|
|
17830
17902
|
});
|
|
17831
17903
|
}
|
|
17904
|
+
this.props.onSelectionChanged?.(existingSelectionXcs);
|
|
17832
17905
|
this.props.onSelectionConfirmed?.();
|
|
17906
|
+
this.previousRanges = this.props.ranges();
|
|
17907
|
+
if (existingSelectionXcs.join() !== this.previousRanges.join()) {
|
|
17908
|
+
this.enableNewSelectionInput();
|
|
17909
|
+
}
|
|
17910
|
+
this.env.model.dispatch("UNFOCUS_SELECTION_INPUT");
|
|
17833
17911
|
}
|
|
17834
17912
|
}
|
|
17835
17913
|
SelectionInput.props = {
|
|
17836
|
-
ranges:
|
|
17914
|
+
ranges: Function,
|
|
17837
17915
|
hasSingleRange: { type: Boolean, optional: true },
|
|
17838
17916
|
required: { type: Boolean, optional: true },
|
|
17839
17917
|
isInvalid: { type: Boolean, optional: true },
|
|
@@ -17881,10 +17959,14 @@ class LineBarPieConfigPanel extends owl.Component {
|
|
|
17881
17959
|
this.dataSeriesRanges = ranges;
|
|
17882
17960
|
}
|
|
17883
17961
|
onDataSeriesConfirmed() {
|
|
17962
|
+
this.dataSeriesRanges = spreadRange(this.dataSeriesRanges);
|
|
17884
17963
|
this.state.datasetDispatchResult = this.props.updateChart({
|
|
17885
17964
|
dataSets: this.dataSeriesRanges,
|
|
17886
17965
|
});
|
|
17887
17966
|
}
|
|
17967
|
+
getDataSeriesRanges() {
|
|
17968
|
+
return this.dataSeriesRanges;
|
|
17969
|
+
}
|
|
17888
17970
|
/**
|
|
17889
17971
|
* Change the local labelRange. The model should be updated when the
|
|
17890
17972
|
* button "confirm" is clicked
|
|
@@ -17897,6 +17979,9 @@ class LineBarPieConfigPanel extends owl.Component {
|
|
|
17897
17979
|
labelRange: this.labelRange,
|
|
17898
17980
|
});
|
|
17899
17981
|
}
|
|
17982
|
+
getLabelRange() {
|
|
17983
|
+
return this.labelRange || "";
|
|
17984
|
+
}
|
|
17900
17985
|
onUpdateAggregated(ev) {
|
|
17901
17986
|
this.props.updateChart({
|
|
17902
17987
|
aggregated: ev.target.checked,
|
|
@@ -18317,6 +18402,9 @@ class GaugeChartConfigPanel extends owl.Component {
|
|
|
18317
18402
|
dataRange: this.dataRange,
|
|
18318
18403
|
});
|
|
18319
18404
|
}
|
|
18405
|
+
getDataRange() {
|
|
18406
|
+
return this.dataRange || "";
|
|
18407
|
+
}
|
|
18320
18408
|
}
|
|
18321
18409
|
GaugeChartConfigPanel.props = {
|
|
18322
18410
|
figureId: String,
|
|
@@ -18515,6 +18603,9 @@ class ScorecardChartConfigPanel extends owl.Component {
|
|
|
18515
18603
|
keyValue: this.keyValue,
|
|
18516
18604
|
});
|
|
18517
18605
|
}
|
|
18606
|
+
getKeyValueRange() {
|
|
18607
|
+
return this.keyValue || "";
|
|
18608
|
+
}
|
|
18518
18609
|
onBaselineRangeChanged(ranges) {
|
|
18519
18610
|
this.baseline = ranges[0];
|
|
18520
18611
|
}
|
|
@@ -18523,6 +18614,9 @@ class ScorecardChartConfigPanel extends owl.Component {
|
|
|
18523
18614
|
baseline: this.baseline,
|
|
18524
18615
|
});
|
|
18525
18616
|
}
|
|
18617
|
+
getBaselineRange() {
|
|
18618
|
+
return this.baseline || "";
|
|
18619
|
+
}
|
|
18526
18620
|
updateBaselineMode(ev) {
|
|
18527
18621
|
this.props.updateChart({ baselineMode: ev.target.value });
|
|
18528
18622
|
}
|
|
@@ -28855,11 +28949,9 @@ class BasePlugin {
|
|
|
28855
28949
|
*/
|
|
28856
28950
|
class CorePlugin extends BasePlugin {
|
|
28857
28951
|
getters;
|
|
28858
|
-
range;
|
|
28859
28952
|
uuidGenerator;
|
|
28860
28953
|
constructor({ getters, stateObserver, range, dispatch, uuidGenerator }) {
|
|
28861
28954
|
super(stateObserver, dispatch);
|
|
28862
|
-
this.range = range;
|
|
28863
28955
|
range.addRangeProvider(this.adaptRanges.bind(this));
|
|
28864
28956
|
this.getters = getters;
|
|
28865
28957
|
this.uuidGenerator = uuidGenerator;
|
|
@@ -38622,6 +38714,7 @@ class SelectionInputPlugin extends UIPlugin {
|
|
|
38622
38714
|
// ---------------------------------------------------------------------------
|
|
38623
38715
|
allowDispatch(cmd) {
|
|
38624
38716
|
switch (cmd.type) {
|
|
38717
|
+
case "ADD_RANGE":
|
|
38625
38718
|
case "ADD_EMPTY_RANGE":
|
|
38626
38719
|
if (this.inputHasSingleRange && this.ranges.length === 1) {
|
|
38627
38720
|
return 30 /* CommandResult.MaximumRangesReached */;
|
|
@@ -38666,6 +38759,10 @@ class SelectionInputPlugin extends UIPlugin {
|
|
|
38666
38759
|
this.insertNewRange(this.ranges.length, [""]);
|
|
38667
38760
|
this.focusLast();
|
|
38668
38761
|
break;
|
|
38762
|
+
case "ADD_RANGE":
|
|
38763
|
+
this.insertNewRange(this.ranges.length, [cmd.value]);
|
|
38764
|
+
this.focusLast();
|
|
38765
|
+
break;
|
|
38669
38766
|
case "REMOVE_RANGE":
|
|
38670
38767
|
const index = this.getIndex(cmd.rangeId);
|
|
38671
38768
|
if (index !== null) {
|
|
@@ -38877,6 +38974,7 @@ class SelectionInputsManagerPlugin extends UIPlugin {
|
|
|
38877
38974
|
case "UNFOCUS_SELECTION_INPUT":
|
|
38878
38975
|
this.unfocus();
|
|
38879
38976
|
break;
|
|
38977
|
+
case "ADD_RANGE":
|
|
38880
38978
|
case "ADD_EMPTY_RANGE":
|
|
38881
38979
|
case "REMOVE_RANGE":
|
|
38882
38980
|
if (cmd.id !== this.focusedInputId) {
|
|
@@ -38890,9 +38988,11 @@ class SelectionInputsManagerPlugin extends UIPlugin {
|
|
|
38890
38988
|
if (cmd.id !== this.focusedInputId) {
|
|
38891
38989
|
const input = this.inputs[cmd.id];
|
|
38892
38990
|
const range = input.ranges.find((range) => range.id === cmd.rangeId);
|
|
38893
|
-
|
|
38894
|
-
|
|
38895
|
-
|
|
38991
|
+
if (this.isRangeValid(range?.xc || "A1")) {
|
|
38992
|
+
const sheetId = this.getters.getActiveSheetId();
|
|
38993
|
+
const zone = this.getters.getRangeFromSheetXC(sheetId, range?.xc || "A1").zone;
|
|
38994
|
+
this.selection.capture(input, { cell: { col: zone.left, row: zone.top }, zone }, { handleEvent: input.handleEvent.bind(input) });
|
|
38995
|
+
}
|
|
38896
38996
|
this.focusedInputId = cmd.id;
|
|
38897
38997
|
}
|
|
38898
38998
|
break;
|
|
@@ -48191,6 +48291,8 @@ exports.coreTypes = coreTypes;
|
|
|
48191
48291
|
exports.findCellInNewZone = findCellInNewZone;
|
|
48192
48292
|
exports.functionCache = functionCache;
|
|
48193
48293
|
exports.helpers = helpers;
|
|
48294
|
+
exports.invalidateCFEvaluationCommands = invalidateCFEvaluationCommands;
|
|
48295
|
+
exports.invalidateDependenciesCommands = invalidateDependenciesCommands;
|
|
48194
48296
|
exports.invalidateEvaluationCommands = invalidateEvaluationCommands;
|
|
48195
48297
|
exports.links = links;
|
|
48196
48298
|
exports.load = load;
|
|
@@ -48202,6 +48304,6 @@ exports.setTranslationMethod = setTranslationMethod;
|
|
|
48202
48304
|
exports.tokenize = tokenize;
|
|
48203
48305
|
|
|
48204
48306
|
|
|
48205
|
-
__info__.version = '16.4.0-alpha.
|
|
48206
|
-
__info__.date = '2023-05-
|
|
48207
|
-
__info__.hash = '
|
|
48307
|
+
__info__.version = '16.4.0-alpha.2';
|
|
48308
|
+
__info__.date = '2023-05-26T13:40:49.561Z';
|
|
48309
|
+
__info__.hash = '82328ad';
|