@odoo/o-spreadsheet 16.2.24 → 16.2.27
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 +172 -99
- package/dist/o-spreadsheet.d.ts +37 -10
- package/dist/o-spreadsheet.esm.js +172 -99
- package/dist/o-spreadsheet.iife.js +172 -99
- package/dist/o-spreadsheet.iife.min.js +243 -243
- package/dist/o_spreadsheet.xml +3 -3
- package/package.json +1 -1
|
@@ -286,15 +286,76 @@ const FONT_SIZES = [6, 7, 8, 9, 10, 11, 12, 14, 18, 24, 36];
|
|
|
286
286
|
// -----------------------------------------------------------------------------
|
|
287
287
|
// Date Type
|
|
288
288
|
// -----------------------------------------------------------------------------
|
|
289
|
+
/**
|
|
290
|
+
* A DateTime object that can be used to manipulate spreadsheet dates.
|
|
291
|
+
* Conceptually, a spreadsheet date is simply a number with a date format,
|
|
292
|
+
* and it is timezone-agnostic.
|
|
293
|
+
* This DateTime object consistently uses UTC time to represent a naive date and time.
|
|
294
|
+
*/
|
|
295
|
+
class DateTime {
|
|
296
|
+
constructor(year, month, day, hours = 0, minutes = 0, seconds = 0) {
|
|
297
|
+
this.jsDate = new Date(Date.UTC(year, month, day, hours, minutes, seconds, 0));
|
|
298
|
+
}
|
|
299
|
+
static fromTimestamp(timestamp) {
|
|
300
|
+
const date = new Date(timestamp);
|
|
301
|
+
return new DateTime(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds());
|
|
302
|
+
}
|
|
303
|
+
static now() {
|
|
304
|
+
const now = new Date();
|
|
305
|
+
return new DateTime(now.getFullYear(), now.getMonth(), now.getDate(), now.getHours(), now.getMinutes(), now.getSeconds());
|
|
306
|
+
}
|
|
307
|
+
toString() {
|
|
308
|
+
return this.jsDate.toString();
|
|
309
|
+
}
|
|
310
|
+
getTime() {
|
|
311
|
+
return this.jsDate.getTime();
|
|
312
|
+
}
|
|
313
|
+
getFullYear() {
|
|
314
|
+
return this.jsDate.getUTCFullYear();
|
|
315
|
+
}
|
|
316
|
+
getMonth() {
|
|
317
|
+
return this.jsDate.getUTCMonth();
|
|
318
|
+
}
|
|
319
|
+
getDate() {
|
|
320
|
+
return this.jsDate.getUTCDate();
|
|
321
|
+
}
|
|
322
|
+
getDay() {
|
|
323
|
+
return this.jsDate.getUTCDay();
|
|
324
|
+
}
|
|
325
|
+
getHours() {
|
|
326
|
+
return this.jsDate.getUTCHours();
|
|
327
|
+
}
|
|
328
|
+
getMinutes() {
|
|
329
|
+
return this.jsDate.getUTCMinutes();
|
|
330
|
+
}
|
|
331
|
+
getSeconds() {
|
|
332
|
+
return this.jsDate.getUTCSeconds();
|
|
333
|
+
}
|
|
334
|
+
setFullYear(year) {
|
|
335
|
+
this.jsDate.setFullYear(year);
|
|
336
|
+
}
|
|
337
|
+
setDate(date) {
|
|
338
|
+
this.jsDate.setUTCDate(date);
|
|
339
|
+
}
|
|
340
|
+
setHours(hours) {
|
|
341
|
+
this.jsDate.setUTCHours(hours);
|
|
342
|
+
}
|
|
343
|
+
setMinutes(minutes) {
|
|
344
|
+
this.jsDate.setUTCMinutes(minutes);
|
|
345
|
+
}
|
|
346
|
+
setSeconds(seconds) {
|
|
347
|
+
this.jsDate.setUTCSeconds(seconds);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
289
350
|
// -----------------------------------------------------------------------------
|
|
290
351
|
// Parsing
|
|
291
352
|
// -----------------------------------------------------------------------------
|
|
292
|
-
const INITIAL_1900_DAY = new
|
|
353
|
+
const INITIAL_1900_DAY = new DateTime(1899, 11, 30);
|
|
293
354
|
const MS_PER_DAY = 24 * 60 * 60 * 1000;
|
|
294
355
|
const CURRENT_MILLENIAL = 2000; // note: don't forget to update this in 2999
|
|
295
|
-
const CURRENT_YEAR =
|
|
296
|
-
const INITIAL_JS_DAY =
|
|
297
|
-
const DATE_JS_1900_OFFSET = INITIAL_JS_DAY - INITIAL_1900_DAY;
|
|
356
|
+
const CURRENT_YEAR = DateTime.now().getFullYear();
|
|
357
|
+
const INITIAL_JS_DAY = DateTime.fromTimestamp(0);
|
|
358
|
+
const DATE_JS_1900_OFFSET = INITIAL_JS_DAY.getTime() - INITIAL_1900_DAY.getTime();
|
|
298
359
|
const mdyDateRegexp = /^\d{1,2}(\/|-|\s)\d{1,2}((\/|-|\s)\d{1,4})?$/;
|
|
299
360
|
const ymdDateRegexp = /^\d{3,4}(\/|-|\s)\d{1,2}(\/|-|\s)\d{1,2}$/;
|
|
300
361
|
const timeRegexp = /((\d+(:\d+)?(:\d+)?\s*(AM|PM))|(\d+:\d+(:\d+)?))$/;
|
|
@@ -343,7 +404,7 @@ function _parseDateTime(str) {
|
|
|
343
404
|
return {
|
|
344
405
|
value: date.value + time.value,
|
|
345
406
|
format: date.format + " " + (time.format === "hhhh:mm:ss" ? "hh:mm:ss" : time.format),
|
|
346
|
-
jsDate: new
|
|
407
|
+
jsDate: new DateTime(date.jsDate.getFullYear() + time.jsDate.getFullYear() - 1899, date.jsDate.getMonth() + time.jsDate.getMonth() - 11, date.jsDate.getDate() + time.jsDate.getDate() - 30, date.jsDate.getHours() + time.jsDate.getHours(), date.jsDate.getMinutes() + time.jsDate.getMinutes(), date.jsDate.getSeconds() + time.jsDate.getSeconds()),
|
|
347
408
|
};
|
|
348
409
|
}
|
|
349
410
|
return date || time;
|
|
@@ -360,13 +421,13 @@ function parseDate(str, dateFormat) {
|
|
|
360
421
|
const day = Number(parts[dayIndex]);
|
|
361
422
|
const leadingZero = (parts[monthIndex].length === 2 && month < 10) || (parts[dayIndex].length === 2 && day < 10);
|
|
362
423
|
const year = parts[yearIndex] ? inferYear(parts[yearIndex]) : CURRENT_YEAR;
|
|
363
|
-
const jsDate = new
|
|
424
|
+
const jsDate = new DateTime(year, month - 1, day);
|
|
364
425
|
const sep = str.match(/\/|-|\s/)[0];
|
|
365
426
|
if (jsDate.getMonth() !== month - 1 || jsDate.getDate() !== day) {
|
|
366
427
|
// invalid date
|
|
367
428
|
return null;
|
|
368
429
|
}
|
|
369
|
-
const delta = jsDate - INITIAL_1900_DAY;
|
|
430
|
+
const delta = jsDate.getTime() - INITIAL_1900_DAY.getTime();
|
|
370
431
|
let format = leadingZero ? `mm${sep}dd` : `m${sep}d`;
|
|
371
432
|
if (parts[yearIndex]) {
|
|
372
433
|
format = isMDY ? format + sep + "yyyy" : "yyyy" + sep + format;
|
|
@@ -426,7 +487,7 @@ function parseTime(str) {
|
|
|
426
487
|
if (hours >= 24) {
|
|
427
488
|
format = "hhhh:mm:ss";
|
|
428
489
|
}
|
|
429
|
-
const jsDate = new
|
|
490
|
+
const jsDate = new DateTime(1899, 11, 30, hours, minutes, seconds);
|
|
430
491
|
return {
|
|
431
492
|
value: hours / 24 + minutes / 1440 + seconds / 86400,
|
|
432
493
|
format: format,
|
|
@@ -440,7 +501,7 @@ function parseTime(str) {
|
|
|
440
501
|
// -----------------------------------------------------------------------------
|
|
441
502
|
function numberToJsDate(value) {
|
|
442
503
|
const truncValue = Math.trunc(value);
|
|
443
|
-
let date =
|
|
504
|
+
let date = DateTime.fromTimestamp(truncValue * MS_PER_DAY - DATE_JS_1900_OFFSET);
|
|
444
505
|
let time = value - truncValue;
|
|
445
506
|
time = time < 0 ? 1 + time : time;
|
|
446
507
|
const hours = Math.round(time * 24);
|
|
@@ -457,7 +518,7 @@ function jsDateToRoundNumber(date) {
|
|
|
457
518
|
}
|
|
458
519
|
/** Return the number of days in the current month of the given date */
|
|
459
520
|
function getDaysInMonth(date) {
|
|
460
|
-
return new
|
|
521
|
+
return new DateTime(date.getFullYear(), date.getMonth() + 1, 0).getDate();
|
|
461
522
|
}
|
|
462
523
|
function isLastDayOfMonth(date) {
|
|
463
524
|
return getDaysInMonth(date) === date.getDate();
|
|
@@ -475,7 +536,7 @@ function addMonthsToDate(date, months, keepEndOfMonth) {
|
|
|
475
536
|
const yStart = date.getFullYear();
|
|
476
537
|
const mStart = date.getMonth();
|
|
477
538
|
const dStart = date.getDate();
|
|
478
|
-
const jsDate = new
|
|
539
|
+
const jsDate = new DateTime(yStart, mStart + months, 1);
|
|
479
540
|
if (keepEndOfMonth && dStart === getDaysInMonth(date)) {
|
|
480
541
|
jsDate.setDate(getDaysInMonth(jsDate));
|
|
481
542
|
}
|
|
@@ -1896,7 +1957,7 @@ function formatJSTime(jsDate, format) {
|
|
|
1896
1957
|
.map((p) => {
|
|
1897
1958
|
switch (p) {
|
|
1898
1959
|
case "hhhh":
|
|
1899
|
-
const helapsedHours = Math.floor((jsDate.getTime() - INITIAL_1900_DAY) / (60 * 60 * 1000));
|
|
1960
|
+
const helapsedHours = Math.floor((jsDate.getTime() - INITIAL_1900_DAY.getTime()) / (60 * 60 * 1000));
|
|
1900
1961
|
return helapsedHours.toString();
|
|
1901
1962
|
case "hh":
|
|
1902
1963
|
return hours.toString().padStart(2, "0");
|
|
@@ -5044,6 +5105,7 @@ const FilterMenuPopoverBuilder = {
|
|
|
5044
5105
|
},
|
|
5045
5106
|
};
|
|
5046
5107
|
|
|
5108
|
+
const macRegex = /Mac/i;
|
|
5047
5109
|
/**
|
|
5048
5110
|
* Return true if the event was triggered from
|
|
5049
5111
|
* a child element.
|
|
@@ -5091,7 +5153,15 @@ function getOpenedMenus() {
|
|
|
5091
5153
|
return Array.from(document.querySelectorAll(".o-spreadsheet .o-menu"));
|
|
5092
5154
|
}
|
|
5093
5155
|
function isMacOS() {
|
|
5094
|
-
return navigator.userAgent
|
|
5156
|
+
return Boolean(macRegex.test(navigator.userAgent));
|
|
5157
|
+
}
|
|
5158
|
+
/**
|
|
5159
|
+
* @param {KeyboardEvent | MouseEvent} ev
|
|
5160
|
+
* @returns Returns true if the event was triggered with the "ctrl" modifier pressed.
|
|
5161
|
+
* On Mac, this is the "meta" or "command" key.
|
|
5162
|
+
*/
|
|
5163
|
+
function isCtrlKey(ev) {
|
|
5164
|
+
return isMacOS() ? ev.metaKey : ev.ctrlKey;
|
|
5095
5165
|
}
|
|
5096
5166
|
|
|
5097
5167
|
/**
|
|
@@ -9483,6 +9553,9 @@ function arg(definition, description = "") {
|
|
|
9483
9553
|
function makeArg(str) {
|
|
9484
9554
|
let parts = str.match(ARG_REGEXP);
|
|
9485
9555
|
let name = parts[1].trim();
|
|
9556
|
+
if (!name) {
|
|
9557
|
+
throw new Error(`Function argument definition is missing a name: '${str}'.`);
|
|
9558
|
+
}
|
|
9486
9559
|
let types = [];
|
|
9487
9560
|
let isOptional = false;
|
|
9488
9561
|
let isRepeating = false;
|
|
@@ -11946,7 +12019,7 @@ const DATE = {
|
|
|
11946
12019
|
if (_year < 1900) {
|
|
11947
12020
|
_year += 1900;
|
|
11948
12021
|
}
|
|
11949
|
-
const jsDate = new
|
|
12022
|
+
const jsDate = new DateTime(_year, _month - 1, _day);
|
|
11950
12023
|
const result = jsDateToRoundNumber(jsDate);
|
|
11951
12024
|
assert(() => result >= 0, _lt(`The function [[FUNCTION_NAME]] result must be greater than or equal 01/01/1900.`));
|
|
11952
12025
|
return result;
|
|
@@ -12054,7 +12127,7 @@ const EOMONTH = {
|
|
|
12054
12127
|
const _months = Math.trunc(toNumber(months));
|
|
12055
12128
|
const yStart = _startDate.getFullYear();
|
|
12056
12129
|
const mStart = _startDate.getMonth();
|
|
12057
|
-
const jsDate = new
|
|
12130
|
+
const jsDate = new DateTime(yStart, mStart + _months + 1, 0);
|
|
12058
12131
|
return jsDateToRoundNumber(jsDate);
|
|
12059
12132
|
},
|
|
12060
12133
|
isExported: true,
|
|
@@ -12091,17 +12164,17 @@ const ISOWEEKNUM = {
|
|
|
12091
12164
|
// The first week of the year is the week that contains the first
|
|
12092
12165
|
// Thursday of the year.
|
|
12093
12166
|
let firstThursday = 1;
|
|
12094
|
-
while (new
|
|
12167
|
+
while (new DateTime(y, 0, firstThursday).getDay() !== 4) {
|
|
12095
12168
|
firstThursday += 1;
|
|
12096
12169
|
}
|
|
12097
|
-
const firstDayOfFirstWeek = new
|
|
12170
|
+
const firstDayOfFirstWeek = new DateTime(y, 0, firstThursday - 3);
|
|
12098
12171
|
// The last week of the year is the week that contains the last Thursday of
|
|
12099
12172
|
// the year.
|
|
12100
12173
|
let lastThursday = 31;
|
|
12101
|
-
while (new
|
|
12174
|
+
while (new DateTime(y, 11, lastThursday).getDay() !== 4) {
|
|
12102
12175
|
lastThursday -= 1;
|
|
12103
12176
|
}
|
|
12104
|
-
const lastDayOfLastWeek = new
|
|
12177
|
+
const lastDayOfLastWeek = new DateTime(y, 11, lastThursday + 3);
|
|
12105
12178
|
// B - If our date > lastDayOfLastWeek then it's in the weeks of the year after
|
|
12106
12179
|
// If our date < firstDayOfFirstWeek then it's in the weeks of the year before
|
|
12107
12180
|
let offsetYear;
|
|
@@ -12127,17 +12200,17 @@ const ISOWEEKNUM = {
|
|
|
12127
12200
|
case 1:
|
|
12128
12201
|
// firstDay is the 1st day of the 1st week of the year after
|
|
12129
12202
|
// firstDay = lastDayOfLastWeek + 1 Day
|
|
12130
|
-
firstDay = new
|
|
12203
|
+
firstDay = new DateTime(y, 11, lastThursday + 3 + 1);
|
|
12131
12204
|
break;
|
|
12132
12205
|
case -1:
|
|
12133
12206
|
// firstDay is the 1st day of the 1st week of the previous year.
|
|
12134
12207
|
// The first week of the previous year is the week that contains the
|
|
12135
12208
|
// first Thursday of the previous year.
|
|
12136
12209
|
let firstThursdayPreviousYear = 1;
|
|
12137
|
-
while (new
|
|
12210
|
+
while (new DateTime(y - 1, 0, firstThursdayPreviousYear).getDay() !== 4) {
|
|
12138
12211
|
firstThursdayPreviousYear += 1;
|
|
12139
12212
|
}
|
|
12140
|
-
firstDay = new
|
|
12213
|
+
firstDay = new DateTime(y - 1, 0, firstThursdayPreviousYear - 3);
|
|
12141
12214
|
break;
|
|
12142
12215
|
}
|
|
12143
12216
|
const diff = (_date.getTime() - firstDay.getTime()) / MS_PER_DAY;
|
|
@@ -12272,8 +12345,8 @@ const NETWORKDAYS_INTL = {
|
|
|
12272
12345
|
});
|
|
12273
12346
|
}
|
|
12274
12347
|
const invertDate = _startDate.getTime() > _endDate.getTime();
|
|
12275
|
-
const stopDate =
|
|
12276
|
-
let stepDate =
|
|
12348
|
+
const stopDate = DateTime.fromTimestamp((invertDate ? _startDate : _endDate).getTime());
|
|
12349
|
+
let stepDate = DateTime.fromTimestamp((invertDate ? _endDate : _startDate).getTime());
|
|
12277
12350
|
const timeStopDate = stopDate.getTime();
|
|
12278
12351
|
let timeStepDate = stepDate.getTime();
|
|
12279
12352
|
let netWorkingDay = 0;
|
|
@@ -12297,8 +12370,7 @@ const NOW = {
|
|
|
12297
12370
|
returns: ["DATE"],
|
|
12298
12371
|
computeFormat: () => "m/d/yyyy hh:mm:ss",
|
|
12299
12372
|
compute: function () {
|
|
12300
|
-
let today =
|
|
12301
|
-
today.setMilliseconds(0);
|
|
12373
|
+
let today = DateTime.now();
|
|
12302
12374
|
const delta = today.getTime() - INITIAL_1900_DAY.getTime();
|
|
12303
12375
|
const time = today.getHours() / 24 + today.getMinutes() / 1440 + today.getSeconds() / 86400;
|
|
12304
12376
|
return Math.floor(delta / MS_PER_DAY) + time;
|
|
@@ -12368,8 +12440,8 @@ const TODAY = {
|
|
|
12368
12440
|
returns: ["DATE"],
|
|
12369
12441
|
computeFormat: () => "m/d/yyyy",
|
|
12370
12442
|
compute: function () {
|
|
12371
|
-
const today =
|
|
12372
|
-
const jsDate = new
|
|
12443
|
+
const today = DateTime.now();
|
|
12444
|
+
const jsDate = new DateTime(today.getFullYear(), today.getMonth(), today.getDate());
|
|
12373
12445
|
return jsDateToRoundNumber(jsDate);
|
|
12374
12446
|
},
|
|
12375
12447
|
isExported: true,
|
|
@@ -12424,10 +12496,10 @@ const WEEKNUM = {
|
|
|
12424
12496
|
}
|
|
12425
12497
|
const y = _date.getFullYear();
|
|
12426
12498
|
let dayStart = 1;
|
|
12427
|
-
let startDayOfFirstWeek = new
|
|
12499
|
+
let startDayOfFirstWeek = new DateTime(y, 0, dayStart);
|
|
12428
12500
|
while (startDayOfFirstWeek.getDay() !== startDayOfWeek) {
|
|
12429
12501
|
dayStart += 1;
|
|
12430
|
-
startDayOfFirstWeek = new
|
|
12502
|
+
startDayOfFirstWeek = new DateTime(y, 0, dayStart);
|
|
12431
12503
|
}
|
|
12432
12504
|
const dif = (_date.getTime() - startDayOfFirstWeek.getTime()) / MS_PER_DAY;
|
|
12433
12505
|
if (dif < 0) {
|
|
@@ -12481,7 +12553,7 @@ const WORKDAY_INTL = {
|
|
|
12481
12553
|
timesHoliday.add(holiday.getTime());
|
|
12482
12554
|
});
|
|
12483
12555
|
}
|
|
12484
|
-
let stepDate =
|
|
12556
|
+
let stepDate = DateTime.fromTimestamp(_startDate.getTime());
|
|
12485
12557
|
let timeStepDate = stepDate.getTime();
|
|
12486
12558
|
const unitDay = Math.sign(_numDays);
|
|
12487
12559
|
let stepDay = Math.abs(_numDays);
|
|
@@ -12543,7 +12615,7 @@ const MONTH_START = {
|
|
|
12543
12615
|
const _startDate = toJsDate(date);
|
|
12544
12616
|
const yStart = _startDate.getFullYear();
|
|
12545
12617
|
const mStart = _startDate.getMonth();
|
|
12546
|
-
const jsDate = new
|
|
12618
|
+
const jsDate = new DateTime(yStart, mStart, 1);
|
|
12547
12619
|
return jsDateToRoundNumber(jsDate);
|
|
12548
12620
|
},
|
|
12549
12621
|
};
|
|
@@ -12581,7 +12653,7 @@ const QUARTER_START = {
|
|
|
12581
12653
|
compute: function (date) {
|
|
12582
12654
|
const quarter = QUARTER.compute(date);
|
|
12583
12655
|
const year = YEAR.compute(date);
|
|
12584
|
-
const jsDate = new
|
|
12656
|
+
const jsDate = new DateTime(year, (quarter - 1) * 3, 1);
|
|
12585
12657
|
return jsDateToRoundNumber(jsDate);
|
|
12586
12658
|
},
|
|
12587
12659
|
};
|
|
@@ -12596,7 +12668,7 @@ const QUARTER_END = {
|
|
|
12596
12668
|
compute: function (date) {
|
|
12597
12669
|
const quarter = QUARTER.compute(date);
|
|
12598
12670
|
const year = YEAR.compute(date);
|
|
12599
|
-
const jsDate = new
|
|
12671
|
+
const jsDate = new DateTime(year, quarter * 3, 0);
|
|
12600
12672
|
return jsDateToRoundNumber(jsDate);
|
|
12601
12673
|
},
|
|
12602
12674
|
};
|
|
@@ -12610,7 +12682,7 @@ const YEAR_START = {
|
|
|
12610
12682
|
computeFormat: () => "m/d/yyyy",
|
|
12611
12683
|
compute: function (date) {
|
|
12612
12684
|
const year = YEAR.compute(date);
|
|
12613
|
-
const jsDate = new
|
|
12685
|
+
const jsDate = new DateTime(year, 0, 1);
|
|
12614
12686
|
return jsDateToRoundNumber(jsDate);
|
|
12615
12687
|
},
|
|
12616
12688
|
};
|
|
@@ -12624,7 +12696,7 @@ const YEAR_END = {
|
|
|
12624
12696
|
computeFormat: () => "m/d/yyyy",
|
|
12625
12697
|
compute: function (date) {
|
|
12626
12698
|
const year = YEAR.compute(date);
|
|
12627
|
-
const jsDate = new
|
|
12699
|
+
const jsDate = new DateTime(year + 1, 0, 0);
|
|
12628
12700
|
return jsDateToRoundNumber(jsDate);
|
|
12629
12701
|
},
|
|
12630
12702
|
};
|
|
@@ -12671,8 +12743,8 @@ const DEFAULT_DELTA_ARG = 0;
|
|
|
12671
12743
|
const DELTA = {
|
|
12672
12744
|
description: _lt("Compare two numeric values, returning 1 if they're equal."),
|
|
12673
12745
|
args: [
|
|
12674
|
-
arg(" (number)", _lt("The first number to compare.")),
|
|
12675
|
-
arg(` (number, default=${DEFAULT_DELTA_ARG})`, _lt("The second number to compare.")),
|
|
12746
|
+
arg("number1 (number)", _lt("The first number to compare.")),
|
|
12747
|
+
arg(`number2 (number, default=${DEFAULT_DELTA_ARG})`, _lt("The second number to compare.")),
|
|
12676
12748
|
],
|
|
12677
12749
|
returns: ["NUMBER"],
|
|
12678
12750
|
compute: function (number1, number2 = DEFAULT_DELTA_ARG) {
|
|
@@ -12758,7 +12830,7 @@ function assertDeprecationFactorStrictlyPositive(factor) {
|
|
|
12758
12830
|
function assertSettlementLessThanOneYearBeforeMaturity(settlement, maturity) {
|
|
12759
12831
|
const startDate = toJsDate(settlement);
|
|
12760
12832
|
const endDate = toJsDate(maturity);
|
|
12761
|
-
const startDatePlusOneYear =
|
|
12833
|
+
const startDatePlusOneYear = toJsDate(settlement);
|
|
12762
12834
|
startDatePlusOneYear.setFullYear(startDate.getFullYear() + 1);
|
|
12763
12835
|
assert(() => endDate.getTime() <= startDatePlusOneYear.getTime(), _lt("The settlement date (%s) must at most one year after the maturity date (%s).", settlement.toString(), maturity.toString()));
|
|
12764
12836
|
}
|
|
@@ -12893,7 +12965,7 @@ const AMORLINC = {
|
|
|
12893
12965
|
arg("salvage (number)", _lt("The value of the asset at the end of depreciation.")),
|
|
12894
12966
|
arg("period (number)", _lt("The single period within life for which to calculate depreciation.")),
|
|
12895
12967
|
arg("rate (number)", _lt("The deprecation rate.")),
|
|
12896
|
-
arg(" (number, optional)", _lt("An indicator of what day count method to use.")),
|
|
12968
|
+
arg("day_count_convention (number, optional)", _lt("An indicator of what day count method to use.")),
|
|
12897
12969
|
],
|
|
12898
12970
|
returns: ["NUMBER"],
|
|
12899
12971
|
compute: function (cost, purchaseDate, firstPeriodEnd, salvage, period, rate, dayCountConvention = DEFAULT_DAY_COUNT_CONVENTION) {
|
|
@@ -15837,8 +15909,8 @@ const MID = {
|
|
|
15837
15909
|
description: _lt("A segment of a string."),
|
|
15838
15910
|
args: [
|
|
15839
15911
|
arg("text (string)", _lt("The string to extract a segment from.")),
|
|
15840
|
-
arg(" (number)", _lt("The index from the left of string from which to begin extracting. The first character in string has the index 1.")),
|
|
15841
|
-
arg(" (number)", _lt("The length of the segment to extract.")),
|
|
15912
|
+
arg("starting_at (number)", _lt("The index from the left of string from which to begin extracting. The first character in string has the index 1.")),
|
|
15913
|
+
arg("extract_length (number)", _lt("The length of the segment to extract.")),
|
|
15842
15914
|
],
|
|
15843
15915
|
returns: ["STRING"],
|
|
15844
15916
|
compute: function (text, starting_at, extract_length) {
|
|
@@ -16709,10 +16781,10 @@ const arrowMap = {
|
|
|
16709
16781
|
function updateSelectionWithArrowKeys(ev, selection) {
|
|
16710
16782
|
const direction = arrowMap[ev.key];
|
|
16711
16783
|
if (ev.shiftKey) {
|
|
16712
|
-
selection.resizeAnchorZone(direction, ev
|
|
16784
|
+
selection.resizeAnchorZone(direction, isCtrlKey(ev) ? "end" : 1);
|
|
16713
16785
|
}
|
|
16714
16786
|
else {
|
|
16715
|
-
selection.moveAnchorCell(direction, ev
|
|
16787
|
+
selection.moveAnchorCell(direction, isCtrlKey(ev) ? "end" : 1);
|
|
16716
16788
|
}
|
|
16717
16789
|
}
|
|
16718
16790
|
|
|
@@ -21047,7 +21119,10 @@ class GridOverlay extends Component {
|
|
|
21047
21119
|
return;
|
|
21048
21120
|
}
|
|
21049
21121
|
const [col, row] = this.getCartesianCoordinates(ev);
|
|
21050
|
-
this.props.onCellClicked(col, row, {
|
|
21122
|
+
this.props.onCellClicked(col, row, {
|
|
21123
|
+
expandZone: ev.shiftKey,
|
|
21124
|
+
addZone: isCtrlKey(ev),
|
|
21125
|
+
});
|
|
21051
21126
|
}
|
|
21052
21127
|
onDoubleClick(ev) {
|
|
21053
21128
|
const [col, row] = this.getCartesianCoordinates(ev);
|
|
@@ -21291,7 +21366,7 @@ class AbstractResizer extends Component {
|
|
|
21291
21366
|
this._increaseSelection(index);
|
|
21292
21367
|
}
|
|
21293
21368
|
else {
|
|
21294
|
-
this._selectElement(index, ev
|
|
21369
|
+
this._selectElement(index, isCtrlKey(ev));
|
|
21295
21370
|
}
|
|
21296
21371
|
this.lastSelectedElementIndex = index;
|
|
21297
21372
|
const mouseMoveSelect = (col, row) => {
|
|
@@ -21304,7 +21379,7 @@ class AbstractResizer extends Component {
|
|
|
21304
21379
|
const mouseUpSelect = () => {
|
|
21305
21380
|
this.state.isSelecting = false;
|
|
21306
21381
|
this.lastSelectedElementIndex = null;
|
|
21307
|
-
this.env.model.dispatch(ev
|
|
21382
|
+
this.env.model.dispatch(isCtrlKey(ev) ? "PREPARE_SELECTION_INPUT_EXPANSION" : "STOP_SELECTION_INPUT");
|
|
21308
21383
|
this._computeGrabDisplay(ev);
|
|
21309
21384
|
};
|
|
21310
21385
|
dragAndDropBeyondTheViewport(this.env, mouseMoveSelect, mouseUpSelect);
|
|
@@ -21454,8 +21529,8 @@ class ColResizer extends AbstractResizer {
|
|
|
21454
21529
|
this.env.raiseError(MergeErrorMessage);
|
|
21455
21530
|
}
|
|
21456
21531
|
}
|
|
21457
|
-
_selectElement(index,
|
|
21458
|
-
this.env.model.selection.selectColumn(index,
|
|
21532
|
+
_selectElement(index, addDistinctHeader) {
|
|
21533
|
+
this.env.model.selection.selectColumn(index, addDistinctHeader ? "newAnchor" : "overrideSelection");
|
|
21459
21534
|
}
|
|
21460
21535
|
_increaseSelection(index) {
|
|
21461
21536
|
this.env.model.selection.selectColumn(index, "updateAnchor");
|
|
@@ -21627,8 +21702,8 @@ class RowResizer extends AbstractResizer {
|
|
|
21627
21702
|
this.env.raiseError(MergeErrorMessage);
|
|
21628
21703
|
}
|
|
21629
21704
|
}
|
|
21630
|
-
_selectElement(index,
|
|
21631
|
-
this.env.model.selection.selectRow(index,
|
|
21705
|
+
_selectElement(index, addDistinctHeader) {
|
|
21706
|
+
this.env.model.selection.selectRow(index, addDistinctHeader ? "newAnchor" : "overrideSelection");
|
|
21632
21707
|
}
|
|
21633
21708
|
_increaseSelection(index) {
|
|
21634
21709
|
this.env.model.selection.selectRow(index, "updateAnchor");
|
|
@@ -22375,8 +22450,8 @@ class Grid extends Component {
|
|
|
22375
22450
|
// ---------------------------------------------------------------------------
|
|
22376
22451
|
// Zone selection with mouse
|
|
22377
22452
|
// ---------------------------------------------------------------------------
|
|
22378
|
-
onCellClicked(col, row, {
|
|
22379
|
-
if (
|
|
22453
|
+
onCellClicked(col, row, { addZone, expandZone }) {
|
|
22454
|
+
if (addZone) {
|
|
22380
22455
|
this.env.model.dispatch("PREPARE_SELECTION_INPUT_EXPANSION");
|
|
22381
22456
|
}
|
|
22382
22457
|
if (this.env.model.getters.hasOpenedPopover()) {
|
|
@@ -22385,10 +22460,10 @@ class Grid extends Component {
|
|
|
22385
22460
|
if (this.env.model.getters.getEditionMode() === "editing") {
|
|
22386
22461
|
this.env.model.dispatch("STOP_EDITION");
|
|
22387
22462
|
}
|
|
22388
|
-
if (
|
|
22463
|
+
if (expandZone) {
|
|
22389
22464
|
this.env.model.selection.setAnchorCorner(col, row);
|
|
22390
22465
|
}
|
|
22391
|
-
else if (
|
|
22466
|
+
else if (addZone) {
|
|
22392
22467
|
this.env.model.selection.addCellToSelection(col, row);
|
|
22393
22468
|
}
|
|
22394
22469
|
else {
|
|
@@ -22450,9 +22525,7 @@ class Grid extends Component {
|
|
|
22450
22525
|
return;
|
|
22451
22526
|
}
|
|
22452
22527
|
let keyDownString = "";
|
|
22453
|
-
if (ev
|
|
22454
|
-
keyDownString += "CTRL+";
|
|
22455
|
-
if (ev.metaKey)
|
|
22528
|
+
if (isCtrlKey(ev))
|
|
22456
22529
|
keyDownString += "CTRL+";
|
|
22457
22530
|
if (ev.altKey)
|
|
22458
22531
|
keyDownString += "ALT+";
|
|
@@ -31970,13 +32043,18 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
31970
32043
|
// Getters
|
|
31971
32044
|
// ---------------------------------------------------------------------------
|
|
31972
32045
|
evaluateFormula(formulaString, sheetId = this.getters.getActiveSheetId()) {
|
|
31973
|
-
|
|
31974
|
-
|
|
31975
|
-
|
|
31976
|
-
|
|
31977
|
-
|
|
32046
|
+
try {
|
|
32047
|
+
const compiledFormula = compile(formulaString);
|
|
32048
|
+
const params = this.getCompilationParameters((cell) => this.getEvaluatedCell(this.getters.getCellPosition(cell.id)));
|
|
32049
|
+
const ranges = [];
|
|
32050
|
+
for (let xc of compiledFormula.dependencies) {
|
|
32051
|
+
ranges.push(this.getters.getRangeFromSheetXC(sheetId, xc));
|
|
32052
|
+
}
|
|
32053
|
+
return compiledFormula.execute(ranges, ...params).value;
|
|
32054
|
+
}
|
|
32055
|
+
catch (error) {
|
|
32056
|
+
return error instanceof EvaluationError ? error.errorType : CellErrorType.GenericError;
|
|
31978
32057
|
}
|
|
31979
|
-
return compiledFormula.execute(ranges, ...params).value;
|
|
31980
32058
|
}
|
|
31981
32059
|
/**
|
|
31982
32060
|
* Return the value of each cell in the range as they are displayed in the grid.
|
|
@@ -32478,39 +32556,34 @@ class EvaluationConditionalFormatPlugin extends UIPlugin {
|
|
|
32478
32556
|
this.computedIcons[sheetId] = {};
|
|
32479
32557
|
const computedStyle = this.computedStyles[sheetId];
|
|
32480
32558
|
for (let cf of this.getters.getConditionalFormats(sheetId).reverse()) {
|
|
32481
|
-
|
|
32482
|
-
|
|
32483
|
-
|
|
32484
|
-
|
|
32485
|
-
|
|
32486
|
-
|
|
32487
|
-
|
|
32488
|
-
|
|
32489
|
-
|
|
32490
|
-
|
|
32491
|
-
|
|
32492
|
-
|
|
32493
|
-
|
|
32494
|
-
|
|
32495
|
-
|
|
32496
|
-
for (let
|
|
32497
|
-
|
|
32498
|
-
|
|
32499
|
-
|
|
32500
|
-
if (
|
|
32501
|
-
|
|
32502
|
-
|
|
32503
|
-
|
|
32504
|
-
computedStyle[col][row] = Object.assign(((_a = computedStyle[col]) === null || _a === void 0 ? void 0 : _a[row]) || {}, cf.rule.style);
|
|
32505
|
-
}
|
|
32559
|
+
switch (cf.rule.type) {
|
|
32560
|
+
case "ColorScaleRule":
|
|
32561
|
+
for (let range of cf.ranges) {
|
|
32562
|
+
this.applyColorScale(range, cf.rule);
|
|
32563
|
+
}
|
|
32564
|
+
break;
|
|
32565
|
+
case "IconSetRule":
|
|
32566
|
+
for (let range of cf.ranges) {
|
|
32567
|
+
this.applyIcon(range, cf.rule);
|
|
32568
|
+
}
|
|
32569
|
+
break;
|
|
32570
|
+
default:
|
|
32571
|
+
for (let ref of cf.ranges) {
|
|
32572
|
+
const zone = this.getters.getRangeFromSheetXC(sheetId, ref).zone;
|
|
32573
|
+
for (let row = zone.top; row <= zone.bottom; row++) {
|
|
32574
|
+
for (let col = zone.left; col <= zone.right; col++) {
|
|
32575
|
+
const pr = this.rulePredicate[cf.rule.type];
|
|
32576
|
+
let cell = this.getters.getEvaluatedCell({ sheetId, col, row });
|
|
32577
|
+
if (pr && pr(cell, cf.rule)) {
|
|
32578
|
+
if (!computedStyle[col])
|
|
32579
|
+
computedStyle[col] = [];
|
|
32580
|
+
// we must combine all the properties of all the CF rules applied to the given cell
|
|
32581
|
+
computedStyle[col][row] = Object.assign(((_a = computedStyle[col]) === null || _a === void 0 ? void 0 : _a[row]) || {}, cf.rule.style);
|
|
32506
32582
|
}
|
|
32507
32583
|
}
|
|
32508
32584
|
}
|
|
32509
|
-
|
|
32510
|
-
|
|
32511
|
-
}
|
|
32512
|
-
catch (_) {
|
|
32513
|
-
// we don't care about the errors within the evaluation of a rule
|
|
32585
|
+
}
|
|
32586
|
+
break;
|
|
32514
32587
|
}
|
|
32515
32588
|
}
|
|
32516
32589
|
}
|
|
@@ -32535,7 +32608,7 @@ class EvaluationConditionalFormatPlugin extends UIPlugin {
|
|
|
32535
32608
|
return percentile(rangeValues, Number(threshold.value) / 100, true);
|
|
32536
32609
|
case "formula":
|
|
32537
32610
|
const value = threshold.value && this.getters.evaluateFormula(threshold.value);
|
|
32538
|
-
return
|
|
32611
|
+
return typeof value === "number" ? value : null;
|
|
32539
32612
|
default:
|
|
32540
32613
|
return null;
|
|
32541
32614
|
}
|
|
@@ -41883,7 +41956,7 @@ class Spreadsheet extends Component {
|
|
|
41883
41956
|
}
|
|
41884
41957
|
onKeydown(ev) {
|
|
41885
41958
|
let keyDownString = "";
|
|
41886
|
-
if (ev
|
|
41959
|
+
if (isCtrlKey(ev)) {
|
|
41887
41960
|
keyDownString += "CTRL+";
|
|
41888
41961
|
}
|
|
41889
41962
|
keyDownString += ev.key.toUpperCase();
|
|
@@ -45559,6 +45632,6 @@ function addFunction(functionName, functionDescription) {
|
|
|
45559
45632
|
export { AbstractChart, CommandResult, CorePlugin, DATETIME_FORMAT, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, astToFormula, compile, components, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, invalidateEvaluationCommands, links, load, parse, readonlyAllowedCommands, registries, setTranslationMethod, tokenize };
|
|
45560
45633
|
|
|
45561
45634
|
|
|
45562
|
-
__info__.version = '16.2.
|
|
45563
|
-
__info__.date = '
|
|
45564
|
-
__info__.hash = '
|
|
45635
|
+
__info__.version = '16.2.27';
|
|
45636
|
+
__info__.date = '2024-01-12T13:42:07.889Z';
|
|
45637
|
+
__info__.hash = 'd8b1d67';
|