@odoo/o-spreadsheet 16.1.28 → 16.1.31
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 +208 -119
- package/dist/o-spreadsheet.d.ts +39 -10
- package/dist/o-spreadsheet.esm.js +208 -119
- package/dist/o-spreadsheet.iife.js +208 -119
- package/dist/o-spreadsheet.iife.min.js +230 -230
- package/dist/o_spreadsheet.xml +3 -3
- package/package.json +1 -1
|
@@ -309,15 +309,76 @@ for (let font of fontSizes) {
|
|
|
309
309
|
// -----------------------------------------------------------------------------
|
|
310
310
|
// Date Type
|
|
311
311
|
// -----------------------------------------------------------------------------
|
|
312
|
+
/**
|
|
313
|
+
* A DateTime object that can be used to manipulate spreadsheet dates.
|
|
314
|
+
* Conceptually, a spreadsheet date is simply a number with a date format,
|
|
315
|
+
* and it is timezone-agnostic.
|
|
316
|
+
* This DateTime object consistently uses UTC time to represent a naive date and time.
|
|
317
|
+
*/
|
|
318
|
+
class DateTime {
|
|
319
|
+
constructor(year, month, day, hours = 0, minutes = 0, seconds = 0) {
|
|
320
|
+
this.jsDate = new Date(Date.UTC(year, month, day, hours, minutes, seconds, 0));
|
|
321
|
+
}
|
|
322
|
+
static fromTimestamp(timestamp) {
|
|
323
|
+
const date = new Date(timestamp);
|
|
324
|
+
return new DateTime(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds());
|
|
325
|
+
}
|
|
326
|
+
static now() {
|
|
327
|
+
const now = new Date();
|
|
328
|
+
return new DateTime(now.getFullYear(), now.getMonth(), now.getDate(), now.getHours(), now.getMinutes(), now.getSeconds());
|
|
329
|
+
}
|
|
330
|
+
toString() {
|
|
331
|
+
return this.jsDate.toString();
|
|
332
|
+
}
|
|
333
|
+
getTime() {
|
|
334
|
+
return this.jsDate.getTime();
|
|
335
|
+
}
|
|
336
|
+
getFullYear() {
|
|
337
|
+
return this.jsDate.getUTCFullYear();
|
|
338
|
+
}
|
|
339
|
+
getMonth() {
|
|
340
|
+
return this.jsDate.getUTCMonth();
|
|
341
|
+
}
|
|
342
|
+
getDate() {
|
|
343
|
+
return this.jsDate.getUTCDate();
|
|
344
|
+
}
|
|
345
|
+
getDay() {
|
|
346
|
+
return this.jsDate.getUTCDay();
|
|
347
|
+
}
|
|
348
|
+
getHours() {
|
|
349
|
+
return this.jsDate.getUTCHours();
|
|
350
|
+
}
|
|
351
|
+
getMinutes() {
|
|
352
|
+
return this.jsDate.getUTCMinutes();
|
|
353
|
+
}
|
|
354
|
+
getSeconds() {
|
|
355
|
+
return this.jsDate.getUTCSeconds();
|
|
356
|
+
}
|
|
357
|
+
setFullYear(year) {
|
|
358
|
+
this.jsDate.setFullYear(year);
|
|
359
|
+
}
|
|
360
|
+
setDate(date) {
|
|
361
|
+
this.jsDate.setUTCDate(date);
|
|
362
|
+
}
|
|
363
|
+
setHours(hours) {
|
|
364
|
+
this.jsDate.setUTCHours(hours);
|
|
365
|
+
}
|
|
366
|
+
setMinutes(minutes) {
|
|
367
|
+
this.jsDate.setUTCMinutes(minutes);
|
|
368
|
+
}
|
|
369
|
+
setSeconds(seconds) {
|
|
370
|
+
this.jsDate.setUTCSeconds(seconds);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
312
373
|
// -----------------------------------------------------------------------------
|
|
313
374
|
// Parsing
|
|
314
375
|
// -----------------------------------------------------------------------------
|
|
315
|
-
const INITIAL_1900_DAY = new
|
|
376
|
+
const INITIAL_1900_DAY = new DateTime(1899, 11, 30);
|
|
316
377
|
const MS_PER_DAY = 24 * 60 * 60 * 1000;
|
|
317
378
|
const CURRENT_MILLENIAL = 2000; // note: don't forget to update this in 2999
|
|
318
|
-
const CURRENT_YEAR =
|
|
319
|
-
const INITIAL_JS_DAY =
|
|
320
|
-
const DATE_JS_1900_OFFSET = INITIAL_JS_DAY - INITIAL_1900_DAY;
|
|
379
|
+
const CURRENT_YEAR = DateTime.now().getFullYear();
|
|
380
|
+
const INITIAL_JS_DAY = DateTime.fromTimestamp(0);
|
|
381
|
+
const DATE_JS_1900_OFFSET = INITIAL_JS_DAY.getTime() - INITIAL_1900_DAY.getTime();
|
|
321
382
|
const mdyDateRegexp = /^\d{1,2}(\/|-|\s)\d{1,2}((\/|-|\s)\d{1,4})?$/;
|
|
322
383
|
const ymdDateRegexp = /^\d{3,4}(\/|-|\s)\d{1,2}(\/|-|\s)\d{1,2}$/;
|
|
323
384
|
const timeRegexp = /((\d+(:\d+)?(:\d+)?\s*(AM|PM))|(\d+:\d+(:\d+)?))$/;
|
|
@@ -366,7 +427,7 @@ function _parseDateTime(str) {
|
|
|
366
427
|
return {
|
|
367
428
|
value: date.value + time.value,
|
|
368
429
|
format: date.format + " " + (time.format === "hhhh:mm:ss" ? "hh:mm:ss" : time.format),
|
|
369
|
-
jsDate: new
|
|
430
|
+
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()),
|
|
370
431
|
};
|
|
371
432
|
}
|
|
372
433
|
return date || time;
|
|
@@ -383,13 +444,13 @@ function parseDate(str, dateFormat) {
|
|
|
383
444
|
const day = Number(parts[dayIndex]);
|
|
384
445
|
const leadingZero = (parts[monthIndex].length === 2 && month < 10) || (parts[dayIndex].length === 2 && day < 10);
|
|
385
446
|
const year = parts[yearIndex] ? inferYear(parts[yearIndex]) : CURRENT_YEAR;
|
|
386
|
-
const jsDate = new
|
|
447
|
+
const jsDate = new DateTime(year, month - 1, day);
|
|
387
448
|
const sep = str.match(/\/|-|\s/)[0];
|
|
388
449
|
if (jsDate.getMonth() !== month - 1 || jsDate.getDate() !== day) {
|
|
389
450
|
// invalid date
|
|
390
451
|
return null;
|
|
391
452
|
}
|
|
392
|
-
const delta = jsDate - INITIAL_1900_DAY;
|
|
453
|
+
const delta = jsDate.getTime() - INITIAL_1900_DAY.getTime();
|
|
393
454
|
let format = leadingZero ? `mm${sep}dd` : `m${sep}d`;
|
|
394
455
|
if (parts[yearIndex]) {
|
|
395
456
|
format = isMDY ? format + sep + "yyyy" : "yyyy" + sep + format;
|
|
@@ -449,7 +510,7 @@ function parseTime(str) {
|
|
|
449
510
|
if (hours >= 24) {
|
|
450
511
|
format = "hhhh:mm:ss";
|
|
451
512
|
}
|
|
452
|
-
const jsDate = new
|
|
513
|
+
const jsDate = new DateTime(1899, 11, 30, hours, minutes, seconds);
|
|
453
514
|
return {
|
|
454
515
|
value: hours / 24 + minutes / 1440 + seconds / 86400,
|
|
455
516
|
format: format,
|
|
@@ -463,7 +524,7 @@ function parseTime(str) {
|
|
|
463
524
|
// -----------------------------------------------------------------------------
|
|
464
525
|
function numberToJsDate(value) {
|
|
465
526
|
const truncValue = Math.trunc(value);
|
|
466
|
-
let date =
|
|
527
|
+
let date = DateTime.fromTimestamp(truncValue * MS_PER_DAY - DATE_JS_1900_OFFSET);
|
|
467
528
|
let time = value - truncValue;
|
|
468
529
|
time = time < 0 ? 1 + time : time;
|
|
469
530
|
const hours = Math.round(time * 24);
|
|
@@ -480,7 +541,7 @@ function jsDateToRoundNumber(date) {
|
|
|
480
541
|
}
|
|
481
542
|
/** Return the number of days in the current month of the given date */
|
|
482
543
|
function getDaysInMonth(date) {
|
|
483
|
-
return new
|
|
544
|
+
return new DateTime(date.getFullYear(), date.getMonth() + 1, 0).getDate();
|
|
484
545
|
}
|
|
485
546
|
function isLastDayOfMonth(date) {
|
|
486
547
|
return getDaysInMonth(date) === date.getDate();
|
|
@@ -498,7 +559,7 @@ function addMonthsToDate(date, months, keepEndOfMonth) {
|
|
|
498
559
|
const yStart = date.getFullYear();
|
|
499
560
|
const mStart = date.getMonth();
|
|
500
561
|
const dStart = date.getDate();
|
|
501
|
-
const jsDate = new
|
|
562
|
+
const jsDate = new DateTime(yStart, mStart + months, 1);
|
|
502
563
|
if (keepEndOfMonth && dStart === getDaysInMonth(date)) {
|
|
503
564
|
jsDate.setDate(getDaysInMonth(jsDate));
|
|
504
565
|
}
|
|
@@ -1347,8 +1408,10 @@ function isSameColor(color1, color2) {
|
|
|
1347
1408
|
const cellReference = new RegExp(/\$?([A-Z]{1,3})\$?([0-9]{1,7})/, "i");
|
|
1348
1409
|
// Same as above, but matches the exact string (nothing before or after)
|
|
1349
1410
|
const singleCellReference = new RegExp(/^\$?([A-Z]{1,3})\$?([0-9]{1,7})$/, "i");
|
|
1350
|
-
/** Reference of a column header (eg. A, AB) */
|
|
1351
|
-
const colHeader = new RegExp(
|
|
1411
|
+
/** Reference of a column header (eg. A, AB, $A) */
|
|
1412
|
+
const colHeader = new RegExp(/^\$?([A-Z]{1,3})+$/, "i");
|
|
1413
|
+
/** Reference of a row header (eg. 1, $1) */
|
|
1414
|
+
const rowHeader = new RegExp(/^\$?([0-9]{1,7})+$/, "i");
|
|
1352
1415
|
/** Reference of a column (eg. A, $CA, Sheet1!B) */
|
|
1353
1416
|
const colReference = new RegExp(/^\s*('.+'!|[^']+!)?\$?([A-Z]{1,3})$/, "i");
|
|
1354
1417
|
/** Reference of a row (eg. 1, 59, Sheet1!9) */
|
|
@@ -1378,6 +1441,9 @@ function isRowReference(xc) {
|
|
|
1378
1441
|
function isColHeader(str) {
|
|
1379
1442
|
return colHeader.test(str);
|
|
1380
1443
|
}
|
|
1444
|
+
function isRowHeader(str) {
|
|
1445
|
+
return rowHeader.test(str);
|
|
1446
|
+
}
|
|
1381
1447
|
/**
|
|
1382
1448
|
* Return true if the given xc is the reference of a single cell,
|
|
1383
1449
|
* without any specified sheet (e.g. A1)
|
|
@@ -1876,7 +1942,7 @@ function formatJSTime(jsDate, format) {
|
|
|
1876
1942
|
.map((p) => {
|
|
1877
1943
|
switch (p) {
|
|
1878
1944
|
case "hhhh":
|
|
1879
|
-
const helapsedHours = Math.floor((jsDate.getTime() - INITIAL_1900_DAY) / (60 * 60 * 1000));
|
|
1945
|
+
const helapsedHours = Math.floor((jsDate.getTime() - INITIAL_1900_DAY.getTime()) / (60 * 60 * 1000));
|
|
1880
1946
|
return helapsedHours.toString();
|
|
1881
1947
|
case "hh":
|
|
1882
1948
|
return hours.toString().padStart(2, "0");
|
|
@@ -2167,18 +2233,10 @@ class RangeImpl {
|
|
|
2167
2233
|
if (isFullCol) {
|
|
2168
2234
|
parts[0].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
2169
2235
|
parts[1].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
2170
|
-
if (zone.left === zone.right) {
|
|
2171
|
-
parts[0].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
2172
|
-
parts[1].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
2173
|
-
}
|
|
2174
2236
|
}
|
|
2175
2237
|
if (isFullRow) {
|
|
2176
2238
|
parts[0].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
2177
2239
|
parts[1].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
2178
|
-
if (zone.top === zone.bottom) {
|
|
2179
|
-
parts[0].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
2180
|
-
parts[1].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
2181
|
-
}
|
|
2182
2240
|
}
|
|
2183
2241
|
return parts;
|
|
2184
2242
|
}
|
|
@@ -5705,6 +5763,7 @@ function getMenuDescription(node) {
|
|
|
5705
5763
|
return node.description ? node.description : "";
|
|
5706
5764
|
}
|
|
5707
5765
|
|
|
5766
|
+
const macRegex = /Mac/i;
|
|
5708
5767
|
/**
|
|
5709
5768
|
* Return true if the event was triggered from
|
|
5710
5769
|
* a child element.
|
|
@@ -5722,6 +5781,17 @@ function gridOverlayPosition() {
|
|
|
5722
5781
|
}
|
|
5723
5782
|
function getOpenedMenus() {
|
|
5724
5783
|
return Array.from(document.querySelectorAll(".o-spreadsheet .o-menu"));
|
|
5784
|
+
}
|
|
5785
|
+
function isMacOS() {
|
|
5786
|
+
return Boolean(macRegex.test(navigator.userAgent));
|
|
5787
|
+
}
|
|
5788
|
+
/**
|
|
5789
|
+
* @param {KeyboardEvent | MouseEvent} ev
|
|
5790
|
+
* @returns Returns true if the event was triggered with the "ctrl" modifier pressed.
|
|
5791
|
+
* On Mac, this is the "meta" or "command" key.
|
|
5792
|
+
*/
|
|
5793
|
+
function isCtrlKey(ev) {
|
|
5794
|
+
return isMacOS() ? ev.metaKey : ev.ctrlKey;
|
|
5725
5795
|
}
|
|
5726
5796
|
|
|
5727
5797
|
/**
|
|
@@ -10882,7 +10952,7 @@ const DATE = {
|
|
|
10882
10952
|
if (_year < 1900) {
|
|
10883
10953
|
_year += 1900;
|
|
10884
10954
|
}
|
|
10885
|
-
const jsDate = new
|
|
10955
|
+
const jsDate = new DateTime(_year, _month - 1, _day);
|
|
10886
10956
|
const result = jsDateToRoundNumber(jsDate);
|
|
10887
10957
|
assert(() => result >= 0, _lt(`The function [[FUNCTION_NAME]] result must be greater than or equal 01/01/1900.`));
|
|
10888
10958
|
return result;
|
|
@@ -10994,7 +11064,7 @@ const EOMONTH = {
|
|
|
10994
11064
|
const _months = Math.trunc(toNumber(months));
|
|
10995
11065
|
const yStart = _startDate.getFullYear();
|
|
10996
11066
|
const mStart = _startDate.getMonth();
|
|
10997
|
-
const jsDate = new
|
|
11067
|
+
const jsDate = new DateTime(yStart, mStart + _months + 1, 0);
|
|
10998
11068
|
return jsDateToRoundNumber(jsDate);
|
|
10999
11069
|
},
|
|
11000
11070
|
isExported: true,
|
|
@@ -11033,17 +11103,17 @@ const ISOWEEKNUM = {
|
|
|
11033
11103
|
// The first week of the year is the week that contains the first
|
|
11034
11104
|
// Thursday of the year.
|
|
11035
11105
|
let firstThursday = 1;
|
|
11036
|
-
while (new
|
|
11106
|
+
while (new DateTime(y, 0, firstThursday).getDay() !== 4) {
|
|
11037
11107
|
firstThursday += 1;
|
|
11038
11108
|
}
|
|
11039
|
-
const firstDayOfFirstWeek = new
|
|
11109
|
+
const firstDayOfFirstWeek = new DateTime(y, 0, firstThursday - 3);
|
|
11040
11110
|
// The last week of the year is the week that contains the last Thursday of
|
|
11041
11111
|
// the year.
|
|
11042
11112
|
let lastThursday = 31;
|
|
11043
|
-
while (new
|
|
11113
|
+
while (new DateTime(y, 11, lastThursday).getDay() !== 4) {
|
|
11044
11114
|
lastThursday -= 1;
|
|
11045
11115
|
}
|
|
11046
|
-
const lastDayOfLastWeek = new
|
|
11116
|
+
const lastDayOfLastWeek = new DateTime(y, 11, lastThursday + 3);
|
|
11047
11117
|
// B - If our date > lastDayOfLastWeek then it's in the weeks of the year after
|
|
11048
11118
|
// If our date < firstDayOfFirstWeek then it's in the weeks of the year before
|
|
11049
11119
|
let offsetYear;
|
|
@@ -11069,17 +11139,17 @@ const ISOWEEKNUM = {
|
|
|
11069
11139
|
case 1:
|
|
11070
11140
|
// firstDay is the 1st day of the 1st week of the year after
|
|
11071
11141
|
// firstDay = lastDayOfLastWeek + 1 Day
|
|
11072
|
-
firstDay = new
|
|
11142
|
+
firstDay = new DateTime(y, 11, lastThursday + 3 + 1);
|
|
11073
11143
|
break;
|
|
11074
11144
|
case -1:
|
|
11075
11145
|
// firstDay is the 1st day of the 1st week of the previous year.
|
|
11076
11146
|
// The first week of the previous year is the week that contains the
|
|
11077
11147
|
// first Thursday of the previous year.
|
|
11078
11148
|
let firstThursdayPreviousYear = 1;
|
|
11079
|
-
while (new
|
|
11149
|
+
while (new DateTime(y - 1, 0, firstThursdayPreviousYear).getDay() !== 4) {
|
|
11080
11150
|
firstThursdayPreviousYear += 1;
|
|
11081
11151
|
}
|
|
11082
|
-
firstDay = new
|
|
11152
|
+
firstDay = new DateTime(y - 1, 0, firstThursdayPreviousYear - 3);
|
|
11083
11153
|
break;
|
|
11084
11154
|
}
|
|
11085
11155
|
const diff = (_date.getTime() - firstDay.getTime()) / MS_PER_DAY;
|
|
@@ -11218,8 +11288,8 @@ const NETWORKDAYS_INTL = {
|
|
|
11218
11288
|
});
|
|
11219
11289
|
}
|
|
11220
11290
|
const invertDate = _startDate.getTime() > _endDate.getTime();
|
|
11221
|
-
const stopDate =
|
|
11222
|
-
let stepDate =
|
|
11291
|
+
const stopDate = DateTime.fromTimestamp((invertDate ? _startDate : _endDate).getTime());
|
|
11292
|
+
let stepDate = DateTime.fromTimestamp((invertDate ? _endDate : _startDate).getTime());
|
|
11223
11293
|
const timeStopDate = stopDate.getTime();
|
|
11224
11294
|
let timeStepDate = stepDate.getTime();
|
|
11225
11295
|
let netWorkingDay = 0;
|
|
@@ -11243,8 +11313,7 @@ const NOW = {
|
|
|
11243
11313
|
returns: ["DATE"],
|
|
11244
11314
|
computeFormat: () => "m/d/yyyy hh:mm:ss",
|
|
11245
11315
|
compute: function () {
|
|
11246
|
-
let today =
|
|
11247
|
-
today.setMilliseconds(0);
|
|
11316
|
+
let today = DateTime.now();
|
|
11248
11317
|
const delta = today.getTime() - INITIAL_1900_DAY.getTime();
|
|
11249
11318
|
const time = today.getHours() / 24 + today.getMinutes() / 1440 + today.getSeconds() / 86400;
|
|
11250
11319
|
return Math.floor(delta / MS_PER_DAY) + time;
|
|
@@ -11318,8 +11387,8 @@ const TODAY = {
|
|
|
11318
11387
|
returns: ["DATE"],
|
|
11319
11388
|
computeFormat: () => "m/d/yyyy",
|
|
11320
11389
|
compute: function () {
|
|
11321
|
-
const today =
|
|
11322
|
-
const jsDate = new
|
|
11390
|
+
const today = DateTime.now();
|
|
11391
|
+
const jsDate = new DateTime(today.getFullYear(), today.getMonth(), today.getDate());
|
|
11323
11392
|
return jsDateToRoundNumber(jsDate);
|
|
11324
11393
|
},
|
|
11325
11394
|
isExported: true,
|
|
@@ -11374,10 +11443,10 @@ const WEEKNUM = {
|
|
|
11374
11443
|
}
|
|
11375
11444
|
const y = _date.getFullYear();
|
|
11376
11445
|
let dayStart = 1;
|
|
11377
|
-
let startDayOfFirstWeek = new
|
|
11446
|
+
let startDayOfFirstWeek = new DateTime(y, 0, dayStart);
|
|
11378
11447
|
while (startDayOfFirstWeek.getDay() !== startDayOfWeek) {
|
|
11379
11448
|
dayStart += 1;
|
|
11380
|
-
startDayOfFirstWeek = new
|
|
11449
|
+
startDayOfFirstWeek = new DateTime(y, 0, dayStart);
|
|
11381
11450
|
}
|
|
11382
11451
|
const dif = (_date.getTime() - startDayOfFirstWeek.getTime()) / MS_PER_DAY;
|
|
11383
11452
|
if (dif < 0) {
|
|
@@ -11431,7 +11500,7 @@ const WORKDAY_INTL = {
|
|
|
11431
11500
|
timesHoliday.add(holiday.getTime());
|
|
11432
11501
|
});
|
|
11433
11502
|
}
|
|
11434
|
-
let stepDate =
|
|
11503
|
+
let stepDate = DateTime.fromTimestamp(_startDate.getTime());
|
|
11435
11504
|
let timeStepDate = stepDate.getTime();
|
|
11436
11505
|
const unitDay = Math.sign(_numDays);
|
|
11437
11506
|
let stepDay = Math.abs(_numDays);
|
|
@@ -11497,7 +11566,7 @@ const MONTH_START = {
|
|
|
11497
11566
|
const _startDate = toJsDate(date);
|
|
11498
11567
|
const yStart = _startDate.getFullYear();
|
|
11499
11568
|
const mStart = _startDate.getMonth();
|
|
11500
|
-
const jsDate = new
|
|
11569
|
+
const jsDate = new DateTime(yStart, mStart, 1);
|
|
11501
11570
|
return jsDateToRoundNumber(jsDate);
|
|
11502
11571
|
},
|
|
11503
11572
|
};
|
|
@@ -11541,7 +11610,7 @@ const QUARTER_START = {
|
|
|
11541
11610
|
compute: function (date) {
|
|
11542
11611
|
const quarter = QUARTER.compute(date);
|
|
11543
11612
|
const year = YEAR.compute(date);
|
|
11544
|
-
const jsDate = new
|
|
11613
|
+
const jsDate = new DateTime(year, (quarter - 1) * 3, 1);
|
|
11545
11614
|
return jsDateToRoundNumber(jsDate);
|
|
11546
11615
|
},
|
|
11547
11616
|
};
|
|
@@ -11558,7 +11627,7 @@ const QUARTER_END = {
|
|
|
11558
11627
|
compute: function (date) {
|
|
11559
11628
|
const quarter = QUARTER.compute(date);
|
|
11560
11629
|
const year = YEAR.compute(date);
|
|
11561
|
-
const jsDate = new
|
|
11630
|
+
const jsDate = new DateTime(year, quarter * 3, 0);
|
|
11562
11631
|
return jsDateToRoundNumber(jsDate);
|
|
11563
11632
|
},
|
|
11564
11633
|
};
|
|
@@ -11574,7 +11643,7 @@ const YEAR_START = {
|
|
|
11574
11643
|
computeFormat: () => "m/d/yyyy",
|
|
11575
11644
|
compute: function (date) {
|
|
11576
11645
|
const year = YEAR.compute(date);
|
|
11577
|
-
const jsDate = new
|
|
11646
|
+
const jsDate = new DateTime(year, 0, 1);
|
|
11578
11647
|
return jsDateToRoundNumber(jsDate);
|
|
11579
11648
|
},
|
|
11580
11649
|
};
|
|
@@ -11590,7 +11659,7 @@ const YEAR_END = {
|
|
|
11590
11659
|
computeFormat: () => "m/d/yyyy",
|
|
11591
11660
|
compute: function (date) {
|
|
11592
11661
|
const year = YEAR.compute(date);
|
|
11593
|
-
const jsDate = new
|
|
11662
|
+
const jsDate = new DateTime(year + 1, 0, 0);
|
|
11594
11663
|
return jsDateToRoundNumber(jsDate);
|
|
11595
11664
|
},
|
|
11596
11665
|
};
|
|
@@ -11724,7 +11793,7 @@ function assertDeprecationFactorStrictlyPositive(factor) {
|
|
|
11724
11793
|
function assertSettlementLessThanOneYearBeforeMaturity(settlement, maturity) {
|
|
11725
11794
|
const startDate = toJsDate(settlement);
|
|
11726
11795
|
const endDate = toJsDate(maturity);
|
|
11727
|
-
const startDatePlusOneYear =
|
|
11796
|
+
const startDatePlusOneYear = toJsDate(settlement);
|
|
11728
11797
|
startDatePlusOneYear.setFullYear(startDate.getFullYear() + 1);
|
|
11729
11798
|
assert(() => endDate.getTime() <= startDatePlusOneYear.getTime(), _lt("The settlement date (%s) must at most one year after the maturity date (%s).", settlement.toString(), maturity.toString()));
|
|
11730
11799
|
}
|
|
@@ -15650,7 +15719,7 @@ const machine = {
|
|
|
15650
15719
|
SPACE: goTo(State.RightRef),
|
|
15651
15720
|
NUMBER: goTo(State.Found),
|
|
15652
15721
|
REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
|
|
15653
|
-
SYMBOL: goTo(State.Found, (token) => isColHeader(token.value)),
|
|
15722
|
+
SYMBOL: goTo(State.Found, (token) => isColHeader(token.value) || isRowHeader(token.value)),
|
|
15654
15723
|
},
|
|
15655
15724
|
[State.RightColumnRef]: {
|
|
15656
15725
|
SPACE: goTo(State.RightColumnRef),
|
|
@@ -15661,6 +15730,7 @@ const machine = {
|
|
|
15661
15730
|
SPACE: goTo(State.RightRowRef),
|
|
15662
15731
|
NUMBER: goTo(State.Found),
|
|
15663
15732
|
REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
|
|
15733
|
+
SYMBOL: goTo(State.Found, (token) => isRowHeader(token.value)),
|
|
15664
15734
|
},
|
|
15665
15735
|
[State.Found]: {},
|
|
15666
15736
|
};
|
|
@@ -16170,6 +16240,10 @@ function setXcToReferenceType(xc, referenceType) {
|
|
|
16170
16240
|
return xc.slice(0, indexOfNumber) + "$" + xc.slice(indexOfNumber);
|
|
16171
16241
|
case "colrow":
|
|
16172
16242
|
indexOfNumber = xc.search(/[0-9]/);
|
|
16243
|
+
if (indexOfNumber === -1 || indexOfNumber === 0) {
|
|
16244
|
+
// no row number (eg. A) or no column (eg. 1)
|
|
16245
|
+
return "$" + xc;
|
|
16246
|
+
}
|
|
16173
16247
|
xc = xc.slice(0, indexOfNumber) + "$" + xc.slice(indexOfNumber);
|
|
16174
16248
|
return "$" + xc;
|
|
16175
16249
|
case "none":
|
|
@@ -16943,10 +17017,10 @@ const arrowMap = {
|
|
|
16943
17017
|
function updateSelectionWithArrowKeys(ev, selection) {
|
|
16944
17018
|
const direction = arrowMap[ev.key];
|
|
16945
17019
|
if (ev.shiftKey) {
|
|
16946
|
-
selection.resizeAnchorZone(direction, ev
|
|
17020
|
+
selection.resizeAnchorZone(direction, isCtrlKey(ev) ? "end" : 1);
|
|
16947
17021
|
}
|
|
16948
17022
|
else {
|
|
16949
|
-
selection.moveAnchorCell(direction, ev
|
|
17023
|
+
selection.moveAnchorCell(direction, isCtrlKey(ev) ? "end" : 1);
|
|
16950
17024
|
}
|
|
16951
17025
|
}
|
|
16952
17026
|
|
|
@@ -22603,7 +22677,10 @@ class GridOverlay extends owl.Component {
|
|
|
22603
22677
|
return;
|
|
22604
22678
|
}
|
|
22605
22679
|
const [col, row] = this.getCartesianCoordinates(ev);
|
|
22606
|
-
this.props.onCellClicked(col, row, {
|
|
22680
|
+
this.props.onCellClicked(col, row, {
|
|
22681
|
+
expandZone: ev.shiftKey,
|
|
22682
|
+
addZone: isCtrlKey(ev),
|
|
22683
|
+
});
|
|
22607
22684
|
}
|
|
22608
22685
|
onDoubleClick(ev) {
|
|
22609
22686
|
const [col, row] = this.getCartesianCoordinates(ev);
|
|
@@ -22691,6 +22768,7 @@ class AbstractResizer extends owl.Component {
|
|
|
22691
22768
|
draggerShadowThickness: 0,
|
|
22692
22769
|
delta: 0,
|
|
22693
22770
|
base: 0,
|
|
22771
|
+
position: "before",
|
|
22694
22772
|
});
|
|
22695
22773
|
}
|
|
22696
22774
|
_computeHandleDisplay(ev) {
|
|
@@ -22816,11 +22894,13 @@ class AbstractResizer extends owl.Component {
|
|
|
22816
22894
|
this.state.draggerLinePosition = dimensions.start;
|
|
22817
22895
|
this.state.draggerShadowPosition = dimensions.start;
|
|
22818
22896
|
this.state.base = elementIndex;
|
|
22897
|
+
this.state.position = "before";
|
|
22819
22898
|
}
|
|
22820
22899
|
else if (this._getSelectedZoneEnd() < elementIndex) {
|
|
22821
22900
|
this.state.draggerLinePosition = dimensions.end;
|
|
22822
22901
|
this.state.draggerShadowPosition = dimensions.end - this.state.draggerShadowThickness;
|
|
22823
|
-
this.state.base = elementIndex
|
|
22902
|
+
this.state.base = elementIndex;
|
|
22903
|
+
this.state.position = "after";
|
|
22824
22904
|
}
|
|
22825
22905
|
else {
|
|
22826
22906
|
this.state.draggerLinePosition = startDimensions.start;
|
|
@@ -22844,7 +22924,7 @@ class AbstractResizer extends owl.Component {
|
|
|
22844
22924
|
this._increaseSelection(index);
|
|
22845
22925
|
}
|
|
22846
22926
|
else {
|
|
22847
|
-
this._selectElement(index, ev
|
|
22927
|
+
this._selectElement(index, isCtrlKey(ev));
|
|
22848
22928
|
}
|
|
22849
22929
|
this.lastSelectedElementIndex = index;
|
|
22850
22930
|
const mouseMoveSelect = (col, row) => {
|
|
@@ -22857,7 +22937,7 @@ class AbstractResizer extends owl.Component {
|
|
|
22857
22937
|
const mouseUpSelect = () => {
|
|
22858
22938
|
this.state.isSelecting = false;
|
|
22859
22939
|
this.lastSelectedElementIndex = null;
|
|
22860
|
-
this.env.model.dispatch(ev
|
|
22940
|
+
this.env.model.dispatch(isCtrlKey(ev) ? "PREPARE_SELECTION_INPUT_EXPANSION" : "STOP_SELECTION_INPUT");
|
|
22861
22941
|
this._computeGrabDisplay(ev);
|
|
22862
22942
|
};
|
|
22863
22943
|
dragAndDropBeyondTheViewport(this.env, mouseMoveSelect, mouseUpSelect);
|
|
@@ -23001,13 +23081,14 @@ class ColResizer extends AbstractResizer {
|
|
|
23001
23081
|
dimension: "COL",
|
|
23002
23082
|
base: this.state.base,
|
|
23003
23083
|
elements,
|
|
23084
|
+
position: this.state.position,
|
|
23004
23085
|
});
|
|
23005
23086
|
if (!result.isSuccessful && result.reasons.includes(2 /* CommandResult.WillRemoveExistingMerge */)) {
|
|
23006
23087
|
this.env.raiseError(MergeErrorMessage);
|
|
23007
23088
|
}
|
|
23008
23089
|
}
|
|
23009
|
-
_selectElement(index,
|
|
23010
|
-
this.env.model.selection.selectColumn(index,
|
|
23090
|
+
_selectElement(index, addDistinctHeader) {
|
|
23091
|
+
this.env.model.selection.selectColumn(index, addDistinctHeader ? "newAnchor" : "overrideSelection");
|
|
23011
23092
|
}
|
|
23012
23093
|
_increaseSelection(index) {
|
|
23013
23094
|
this.env.model.selection.selectColumn(index, "updateAnchor");
|
|
@@ -23173,13 +23254,14 @@ class RowResizer extends AbstractResizer {
|
|
|
23173
23254
|
dimension: "ROW",
|
|
23174
23255
|
base: this.state.base,
|
|
23175
23256
|
elements,
|
|
23257
|
+
position: this.state.position,
|
|
23176
23258
|
});
|
|
23177
23259
|
if (!result.isSuccessful && result.reasons.includes(2 /* CommandResult.WillRemoveExistingMerge */)) {
|
|
23178
23260
|
this.env.raiseError(MergeErrorMessage);
|
|
23179
23261
|
}
|
|
23180
23262
|
}
|
|
23181
|
-
_selectElement(index,
|
|
23182
|
-
this.env.model.selection.selectRow(index,
|
|
23263
|
+
_selectElement(index, addDistinctHeader) {
|
|
23264
|
+
this.env.model.selection.selectRow(index, addDistinctHeader ? "newAnchor" : "overrideSelection");
|
|
23183
23265
|
}
|
|
23184
23266
|
_increaseSelection(index) {
|
|
23185
23267
|
this.env.model.selection.selectRow(index, "updateAnchor");
|
|
@@ -23281,8 +23363,8 @@ function useWheelHandler(handler) {
|
|
|
23281
23363
|
return val * (deltaMode === 0 ? 1 : DEFAULT_CELL_HEIGHT);
|
|
23282
23364
|
}
|
|
23283
23365
|
const onMouseWheel = (ev) => {
|
|
23284
|
-
const deltaX = normalize(ev.shiftKey ? ev.deltaY : ev.deltaX, ev.deltaMode);
|
|
23285
|
-
const deltaY = normalize(ev.shiftKey ? ev.deltaX : ev.deltaY, ev.deltaMode);
|
|
23366
|
+
const deltaX = normalize(ev.shiftKey && !isMacOS() ? ev.deltaY : ev.deltaX, ev.deltaMode);
|
|
23367
|
+
const deltaY = normalize(ev.shiftKey && !isMacOS() ? ev.deltaX : ev.deltaY, ev.deltaMode);
|
|
23286
23368
|
handler(deltaX, deltaY);
|
|
23287
23369
|
};
|
|
23288
23370
|
return onMouseWheel;
|
|
@@ -23926,8 +24008,8 @@ class Grid extends owl.Component {
|
|
|
23926
24008
|
// ---------------------------------------------------------------------------
|
|
23927
24009
|
// Zone selection with mouse
|
|
23928
24010
|
// ---------------------------------------------------------------------------
|
|
23929
|
-
onCellClicked(col, row, {
|
|
23930
|
-
if (
|
|
24011
|
+
onCellClicked(col, row, { addZone, expandZone }) {
|
|
24012
|
+
if (addZone) {
|
|
23931
24013
|
this.env.model.dispatch("PREPARE_SELECTION_INPUT_EXPANSION");
|
|
23932
24014
|
}
|
|
23933
24015
|
if (this.env.model.getters.hasOpenedPopover()) {
|
|
@@ -23936,10 +24018,10 @@ class Grid extends owl.Component {
|
|
|
23936
24018
|
if (this.env.model.getters.getEditionMode() === "editing") {
|
|
23937
24019
|
this.env.model.dispatch("STOP_EDITION");
|
|
23938
24020
|
}
|
|
23939
|
-
if (
|
|
24021
|
+
if (expandZone) {
|
|
23940
24022
|
this.env.model.selection.setAnchorCorner(col, row);
|
|
23941
24023
|
}
|
|
23942
|
-
else if (
|
|
24024
|
+
else if (addZone) {
|
|
23943
24025
|
this.env.model.selection.addCellToSelection(col, row);
|
|
23944
24026
|
}
|
|
23945
24027
|
else {
|
|
@@ -24001,9 +24083,7 @@ class Grid extends owl.Component {
|
|
|
24001
24083
|
return;
|
|
24002
24084
|
}
|
|
24003
24085
|
let keyDownString = "";
|
|
24004
|
-
if (ev
|
|
24005
|
-
keyDownString += "CTRL+";
|
|
24006
|
-
if (ev.metaKey)
|
|
24086
|
+
if (isCtrlKey(ev))
|
|
24007
24087
|
keyDownString += "CTRL+";
|
|
24008
24088
|
if (ev.altKey)
|
|
24009
24089
|
keyDownString += "ALT+";
|
|
@@ -31351,7 +31431,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
31351
31431
|
const elements = cmd.dimension === "COL"
|
|
31352
31432
|
? this.getNumberCols(cmd.sheetId)
|
|
31353
31433
|
: this.getNumberRows(cmd.sheetId);
|
|
31354
|
-
if (cmd.base < 0 || cmd.base
|
|
31434
|
+
if (cmd.base < 0 || cmd.base >= elements) {
|
|
31355
31435
|
return 86 /* CommandResult.InvalidHeaderIndex */;
|
|
31356
31436
|
}
|
|
31357
31437
|
else if (cmd.quantity <= 0) {
|
|
@@ -32374,13 +32454,18 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
32374
32454
|
// Getters
|
|
32375
32455
|
// ---------------------------------------------------------------------------
|
|
32376
32456
|
evaluateFormula(formulaString, sheetId = this.getters.getActiveSheetId()) {
|
|
32377
|
-
|
|
32378
|
-
|
|
32379
|
-
|
|
32380
|
-
|
|
32381
|
-
|
|
32457
|
+
try {
|
|
32458
|
+
const compiledFormula = compile(formulaString);
|
|
32459
|
+
const params = this.getCompilationParameters((cell) => this.getEvaluatedCell(this.getters.getCellPosition(cell.id)));
|
|
32460
|
+
const ranges = [];
|
|
32461
|
+
for (let xc of compiledFormula.dependencies) {
|
|
32462
|
+
ranges.push(this.getters.getRangeFromSheetXC(sheetId, xc));
|
|
32463
|
+
}
|
|
32464
|
+
return compiledFormula.execute(ranges, ...params).value;
|
|
32465
|
+
}
|
|
32466
|
+
catch (error) {
|
|
32467
|
+
return error instanceof EvaluationError ? error.errorType : CellErrorType.GenericError;
|
|
32382
32468
|
}
|
|
32383
|
-
return compiledFormula.execute(ranges, ...params).value;
|
|
32384
32469
|
}
|
|
32385
32470
|
/**
|
|
32386
32471
|
* Return the value of each cell in the range as they are displayed in the grid.
|
|
@@ -32872,39 +32957,34 @@ class EvaluationConditionalFormatPlugin extends UIPlugin {
|
|
|
32872
32957
|
this.computedIcons[sheetId] = {};
|
|
32873
32958
|
const computedStyle = this.computedStyles[sheetId];
|
|
32874
32959
|
for (let cf of this.getters.getConditionalFormats(sheetId).reverse()) {
|
|
32875
|
-
|
|
32876
|
-
|
|
32877
|
-
|
|
32878
|
-
|
|
32879
|
-
|
|
32880
|
-
|
|
32881
|
-
|
|
32882
|
-
|
|
32883
|
-
|
|
32884
|
-
|
|
32885
|
-
|
|
32886
|
-
|
|
32887
|
-
|
|
32888
|
-
|
|
32889
|
-
|
|
32890
|
-
for (let
|
|
32891
|
-
|
|
32892
|
-
|
|
32893
|
-
|
|
32894
|
-
if (
|
|
32895
|
-
|
|
32896
|
-
|
|
32897
|
-
|
|
32898
|
-
computedStyle[col][row] = Object.assign(((_a = computedStyle[col]) === null || _a === void 0 ? void 0 : _a[row]) || {}, cf.rule.style);
|
|
32899
|
-
}
|
|
32960
|
+
switch (cf.rule.type) {
|
|
32961
|
+
case "ColorScaleRule":
|
|
32962
|
+
for (let range of cf.ranges) {
|
|
32963
|
+
this.applyColorScale(range, cf.rule);
|
|
32964
|
+
}
|
|
32965
|
+
break;
|
|
32966
|
+
case "IconSetRule":
|
|
32967
|
+
for (let range of cf.ranges) {
|
|
32968
|
+
this.applyIcon(range, cf.rule);
|
|
32969
|
+
}
|
|
32970
|
+
break;
|
|
32971
|
+
default:
|
|
32972
|
+
for (let ref of cf.ranges) {
|
|
32973
|
+
const zone = this.getters.getRangeFromSheetXC(sheetId, ref).zone;
|
|
32974
|
+
for (let row = zone.top; row <= zone.bottom; row++) {
|
|
32975
|
+
for (let col = zone.left; col <= zone.right; col++) {
|
|
32976
|
+
const pr = this.rulePredicate[cf.rule.type];
|
|
32977
|
+
let cell = this.getters.getEvaluatedCell({ sheetId, col, row });
|
|
32978
|
+
if (pr && pr(cell, cf.rule)) {
|
|
32979
|
+
if (!computedStyle[col])
|
|
32980
|
+
computedStyle[col] = [];
|
|
32981
|
+
// we must combine all the properties of all the CF rules applied to the given cell
|
|
32982
|
+
computedStyle[col][row] = Object.assign(((_a = computedStyle[col]) === null || _a === void 0 ? void 0 : _a[row]) || {}, cf.rule.style);
|
|
32900
32983
|
}
|
|
32901
32984
|
}
|
|
32902
32985
|
}
|
|
32903
|
-
|
|
32904
|
-
|
|
32905
|
-
}
|
|
32906
|
-
catch (_) {
|
|
32907
|
-
// we don't care about the errors within the evaluation of a rule
|
|
32986
|
+
}
|
|
32987
|
+
break;
|
|
32908
32988
|
}
|
|
32909
32989
|
}
|
|
32910
32990
|
}
|
|
@@ -32929,7 +33009,7 @@ class EvaluationConditionalFormatPlugin extends UIPlugin {
|
|
|
32929
33009
|
return percentile(rangeValues, Number(threshold.value) / 100, true);
|
|
32930
33010
|
case "formula":
|
|
32931
33011
|
const value = threshold.value && this.getters.evaluateFormula(threshold.value);
|
|
32932
|
-
return
|
|
33012
|
+
return typeof value === "number" ? value : null;
|
|
32933
33013
|
default:
|
|
32934
33014
|
return null;
|
|
32935
33015
|
}
|
|
@@ -34491,24 +34571,27 @@ class AutofillPlugin extends UIPlugin {
|
|
|
34491
34571
|
* autofiller
|
|
34492
34572
|
*/
|
|
34493
34573
|
autofillAuto() {
|
|
34574
|
+
var _a, _b;
|
|
34494
34575
|
const zone = this.getters.getSelectedZone();
|
|
34495
34576
|
const sheetId = this.getters.getActiveSheetId();
|
|
34496
34577
|
let col = zone.left;
|
|
34497
34578
|
let row = zone.bottom;
|
|
34498
34579
|
if (col > 0) {
|
|
34499
|
-
let
|
|
34500
|
-
while (
|
|
34580
|
+
let leftPosition = { sheetId, col: col - 1, row };
|
|
34581
|
+
while (this.getters.getEvaluatedCell(leftPosition).type !== CellValueType.empty ||
|
|
34582
|
+
((_a = this.getters.getCell(leftPosition)) === null || _a === void 0 ? void 0 : _a.content)) {
|
|
34501
34583
|
row += 1;
|
|
34502
|
-
|
|
34584
|
+
leftPosition = { sheetId, col: col - 1, row };
|
|
34503
34585
|
}
|
|
34504
34586
|
}
|
|
34505
34587
|
if (row === zone.bottom) {
|
|
34506
34588
|
col = zone.right;
|
|
34507
34589
|
if (col <= this.getters.getNumberCols(sheetId)) {
|
|
34508
|
-
let
|
|
34509
|
-
while (
|
|
34590
|
+
let rightPosition = { sheetId, col: col + 1, row };
|
|
34591
|
+
while (this.getters.getEvaluatedCell(rightPosition).type !== CellValueType.empty ||
|
|
34592
|
+
((_b = this.getters.getCell(rightPosition)) === null || _b === void 0 ? void 0 : _b.content)) {
|
|
34510
34593
|
row += 1;
|
|
34511
|
-
|
|
34594
|
+
rightPosition = { sheetId, col: col + 1, row };
|
|
34512
34595
|
}
|
|
34513
34596
|
}
|
|
34514
34597
|
}
|
|
@@ -39240,7 +39323,7 @@ class GridSelectionPlugin extends UIPlugin {
|
|
|
39240
39323
|
sheetId: cmd.sheetId,
|
|
39241
39324
|
base: cmd.base,
|
|
39242
39325
|
quantity: thickness,
|
|
39243
|
-
position:
|
|
39326
|
+
position: cmd.position,
|
|
39244
39327
|
});
|
|
39245
39328
|
const isCol = cmd.dimension === "COL";
|
|
39246
39329
|
const start = cmd.elements[0];
|
|
@@ -39257,12 +39340,13 @@ class GridSelectionPlugin extends UIPlugin {
|
|
|
39257
39340
|
},
|
|
39258
39341
|
];
|
|
39259
39342
|
const state = new ClipboardCellsState(target, "CUT", this.getters, this.dispatch, this.selection);
|
|
39343
|
+
const base = isBasedBefore ? cmd.base : cmd.base + 1;
|
|
39260
39344
|
const pasteTarget = [
|
|
39261
39345
|
{
|
|
39262
|
-
left: isCol ?
|
|
39263
|
-
right: isCol ?
|
|
39264
|
-
top: !isCol ?
|
|
39265
|
-
bottom: !isCol ?
|
|
39346
|
+
left: isCol ? base : 0,
|
|
39347
|
+
right: isCol ? base + thickness - 1 : this.getters.getNumberCols(cmd.sheetId) - 1,
|
|
39348
|
+
top: !isCol ? base : 0,
|
|
39349
|
+
bottom: !isCol ? base + thickness - 1 : this.getters.getNumberRows(cmd.sheetId) - 1,
|
|
39266
39350
|
},
|
|
39267
39351
|
];
|
|
39268
39352
|
state.paste(pasteTarget, { selectTarget: true });
|
|
@@ -39299,6 +39383,11 @@ class GridSelectionPlugin extends UIPlugin {
|
|
|
39299
39383
|
doesElementsHaveCommonMerges(id, cmd.base - 1, cmd.base)) {
|
|
39300
39384
|
return 2 /* CommandResult.WillRemoveExistingMerge */;
|
|
39301
39385
|
}
|
|
39386
|
+
const headers = [cmd.base, ...cmd.elements];
|
|
39387
|
+
const maxHeaderValue = isCol ? this.getters.getNumberCols(id) : this.getters.getNumberRows(id);
|
|
39388
|
+
if (headers.some((h) => h < 0 || h >= maxHeaderValue)) {
|
|
39389
|
+
return 86 /* CommandResult.InvalidHeaderIndex */;
|
|
39390
|
+
}
|
|
39302
39391
|
return 0 /* CommandResult.Success */;
|
|
39303
39392
|
}
|
|
39304
39393
|
//-------------------------------------------
|
|
@@ -40852,7 +40941,7 @@ class Spreadsheet extends owl.Component {
|
|
|
40852
40941
|
}
|
|
40853
40942
|
onKeydown(ev) {
|
|
40854
40943
|
let keyDownString = "";
|
|
40855
|
-
if (ev
|
|
40944
|
+
if (isCtrlKey(ev)) {
|
|
40856
40945
|
keyDownString += "CTRL+";
|
|
40857
40946
|
}
|
|
40858
40947
|
keyDownString += ev.key.toUpperCase();
|
|
@@ -44477,6 +44566,6 @@ exports.setTranslationMethod = setTranslationMethod;
|
|
|
44477
44566
|
exports.tokenize = tokenize;
|
|
44478
44567
|
|
|
44479
44568
|
|
|
44480
|
-
__info__.version = '16.1.
|
|
44481
|
-
__info__.date = '
|
|
44482
|
-
__info__.hash = '
|
|
44569
|
+
__info__.version = '16.1.31';
|
|
44570
|
+
__info__.date = '2024-01-12T13:42:11.001Z';
|
|
44571
|
+
__info__.hash = 'f51befa';
|