@odoo/o-spreadsheet 17.4.6 → 17.4.8
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 +143 -54
- package/dist/o-spreadsheet.d.ts +14 -7
- package/dist/o-spreadsheet.esm.js +143 -54
- package/dist/o-spreadsheet.iife.js +143 -54
- package/dist/o-spreadsheet.iife.min.js +332 -321
- package/dist/o_spreadsheet.xml +4 -4
- package/package.json +1 -1
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* This file is generated by o-spreadsheet build tools. Do not edit it.
|
|
4
4
|
* @see https://github.com/odoo/o-spreadsheet
|
|
5
|
-
* @version 17.4.
|
|
6
|
-
* @date 2024-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 17.4.8
|
|
6
|
+
* @date 2024-09-17T08:10:18.777Z
|
|
7
|
+
* @hash caad8bd
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, useState, onPatched, onWillPatch, onWillUpdateProps, useExternalListener, onWillStart, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
|
|
@@ -4559,6 +4559,17 @@ function reorderZone(zone) {
|
|
|
4559
4559
|
}
|
|
4560
4560
|
return zone;
|
|
4561
4561
|
}
|
|
4562
|
+
function aggregatePositionsToZones(positions) {
|
|
4563
|
+
const result = {};
|
|
4564
|
+
for (const position of positions) {
|
|
4565
|
+
result[position.sheetId] ??= [];
|
|
4566
|
+
result[position.sheetId].push(positionToZone(position));
|
|
4567
|
+
}
|
|
4568
|
+
for (const sheetId in result) {
|
|
4569
|
+
result[sheetId] = recomputeZones(result[sheetId]);
|
|
4570
|
+
}
|
|
4571
|
+
return result;
|
|
4572
|
+
}
|
|
4562
4573
|
/**
|
|
4563
4574
|
* This function returns a zone with coordinates modified according to the change
|
|
4564
4575
|
* applied to the zone. It may be possible to change the zone by resizing or moving
|
|
@@ -6774,9 +6785,11 @@ class CellClipboardHandler extends AbstractCellClipboardHandler {
|
|
|
6774
6785
|
const targetCell = this.getters.getEvaluatedCell(target);
|
|
6775
6786
|
const originFormat = origin.cell?.format ?? origin.evaluatedCell.format;
|
|
6776
6787
|
if (clipboardOption?.pasteOption === "asValue") {
|
|
6777
|
-
|
|
6778
|
-
|
|
6779
|
-
|
|
6788
|
+
this.dispatch("UPDATE_CELL", {
|
|
6789
|
+
...target,
|
|
6790
|
+
content: origin.evaluatedCell.value?.toString() || "",
|
|
6791
|
+
format: originFormat,
|
|
6792
|
+
});
|
|
6780
6793
|
return;
|
|
6781
6794
|
}
|
|
6782
6795
|
if (clipboardOption?.pasteOption === "onlyFormat") {
|
|
@@ -28378,8 +28391,8 @@ const CREATE_PIVOT = (env) => {
|
|
|
28378
28391
|
env.openSidePanel("PivotSidePanel", { pivotId });
|
|
28379
28392
|
}
|
|
28380
28393
|
};
|
|
28381
|
-
const
|
|
28382
|
-
id: `
|
|
28394
|
+
const REINSERT_DYNAMIC_PIVOT_CHILDREN = (env) => env.model.getters.getPivotIds().map((pivotId, index) => ({
|
|
28395
|
+
id: `reinsert_dynamic_pivot_${env.model.getters.getPivotFormulaId(pivotId)}`,
|
|
28383
28396
|
name: env.model.getters.getPivotDisplayName(pivotId),
|
|
28384
28397
|
sequence: index,
|
|
28385
28398
|
execute: (env) => {
|
|
@@ -28391,9 +28404,30 @@ const REINSERT_PIVOT_CHILDREN = (env) => env.model.getters.getPivotIds().map((pi
|
|
|
28391
28404
|
col: zone.left,
|
|
28392
28405
|
row: zone.top,
|
|
28393
28406
|
sheetId: env.model.getters.getActiveSheetId(),
|
|
28407
|
+
pivotMode: "dynamic",
|
|
28394
28408
|
});
|
|
28395
28409
|
env.model.dispatch("REFRESH_PIVOT", { id: pivotId });
|
|
28396
28410
|
},
|
|
28411
|
+
isVisible: (env) => env.model.getters.getPivot(pivotId).isValid(),
|
|
28412
|
+
}));
|
|
28413
|
+
const REINSERT_STATIC_PIVOT_CHILDREN = (env) => env.model.getters.getPivotIds().map((pivotId, index) => ({
|
|
28414
|
+
id: `reinsert_static_pivot_${env.model.getters.getPivotFormulaId(pivotId)}`,
|
|
28415
|
+
name: env.model.getters.getPivotDisplayName(pivotId),
|
|
28416
|
+
sequence: index,
|
|
28417
|
+
execute: (env) => {
|
|
28418
|
+
const zone = env.model.getters.getSelectedZone();
|
|
28419
|
+
const table = env.model.getters.getPivot(pivotId).getTableStructure().export();
|
|
28420
|
+
env.model.dispatch("INSERT_PIVOT_WITH_TABLE", {
|
|
28421
|
+
pivotId,
|
|
28422
|
+
table,
|
|
28423
|
+
col: zone.left,
|
|
28424
|
+
row: zone.top,
|
|
28425
|
+
sheetId: env.model.getters.getActiveSheetId(),
|
|
28426
|
+
pivotMode: "static",
|
|
28427
|
+
});
|
|
28428
|
+
env.model.dispatch("REFRESH_PIVOT", { id: pivotId });
|
|
28429
|
+
},
|
|
28430
|
+
isVisible: (env) => env.model.getters.getPivot(pivotId).isValid(),
|
|
28397
28431
|
}));
|
|
28398
28432
|
//------------------------------------------------------------------------------
|
|
28399
28433
|
// Image
|
|
@@ -29259,13 +29293,21 @@ const splitToColumns = {
|
|
|
29259
29293
|
isEnabled: (env) => env.model.getters.isSingleColSelected(),
|
|
29260
29294
|
icon: "o-spreadsheet-Icon.SPLIT_TEXT",
|
|
29261
29295
|
};
|
|
29262
|
-
const
|
|
29263
|
-
id: "
|
|
29264
|
-
name: _t("Re-insert pivot"),
|
|
29296
|
+
const reinsertDynamicPivotMenu = {
|
|
29297
|
+
id: "reinsert_dynamic_pivot",
|
|
29298
|
+
name: _t("Re-insert dynamic pivot"),
|
|
29299
|
+
sequence: 1020,
|
|
29300
|
+
icon: "o-spreadsheet-Icon.INSERT_PIVOT",
|
|
29301
|
+
children: [REINSERT_DYNAMIC_PIVOT_CHILDREN],
|
|
29302
|
+
isVisible: (env) => env.model.getters.getPivotIds().some((id) => env.model.getters.getPivot(id).isValid()),
|
|
29303
|
+
};
|
|
29304
|
+
const reinsertStaticPivotMenu = {
|
|
29305
|
+
id: "reinsert_static_pivot",
|
|
29306
|
+
name: _t("Re-insert static pivot"),
|
|
29265
29307
|
sequence: 1020,
|
|
29266
29308
|
icon: "o-spreadsheet-Icon.INSERT_PIVOT",
|
|
29267
|
-
children: [
|
|
29268
|
-
isVisible: (env) => env.model.getters.getPivotIds().
|
|
29309
|
+
children: [REINSERT_STATIC_PIVOT_CHILDREN],
|
|
29310
|
+
isVisible: (env) => env.model.getters.getPivotIds().some((id) => env.model.getters.getPivot(id).isValid()),
|
|
29269
29311
|
};
|
|
29270
29312
|
|
|
29271
29313
|
var ACTION_DATA = /*#__PURE__*/Object.freeze({
|
|
@@ -29273,7 +29315,8 @@ var ACTION_DATA = /*#__PURE__*/Object.freeze({
|
|
|
29273
29315
|
createRemoveFilter: createRemoveFilter,
|
|
29274
29316
|
createRemoveFilterTool: createRemoveFilterTool,
|
|
29275
29317
|
dataCleanup: dataCleanup,
|
|
29276
|
-
|
|
29318
|
+
reinsertDynamicPivotMenu: reinsertDynamicPivotMenu,
|
|
29319
|
+
reinsertStaticPivotMenu: reinsertStaticPivotMenu,
|
|
29277
29320
|
removeDuplicates: removeDuplicates,
|
|
29278
29321
|
sortAscending: sortAscending,
|
|
29279
29322
|
sortDescending: sortDescending,
|
|
@@ -30755,7 +30798,8 @@ topbarMenuRegistry
|
|
|
30755
30798
|
};
|
|
30756
30799
|
});
|
|
30757
30800
|
})
|
|
30758
|
-
.addChild("
|
|
30801
|
+
.addChild("reinsert_dynamic_pivot", ["data"], reinsertDynamicPivotMenu)
|
|
30802
|
+
.addChild("reinsert_static_pivot", ["data"], reinsertStaticPivotMenu);
|
|
30759
30803
|
|
|
30760
30804
|
class OTRegistry extends Registry {
|
|
30761
30805
|
/**
|
|
@@ -44065,6 +44109,18 @@ function convertOperator(operator) {
|
|
|
44065
44109
|
// -------------------------------------
|
|
44066
44110
|
// WORKSHEET HELPERS
|
|
44067
44111
|
// -------------------------------------
|
|
44112
|
+
function getCellType(value) {
|
|
44113
|
+
switch (typeof value) {
|
|
44114
|
+
case "boolean":
|
|
44115
|
+
return "b";
|
|
44116
|
+
case "string":
|
|
44117
|
+
return "str";
|
|
44118
|
+
case "number":
|
|
44119
|
+
return "n";
|
|
44120
|
+
default:
|
|
44121
|
+
return undefined;
|
|
44122
|
+
}
|
|
44123
|
+
}
|
|
44068
44124
|
function convertHeightToExcel(height) {
|
|
44069
44125
|
return Math.round(HEIGHT_FACTOR * height * 100) / 100;
|
|
44070
44126
|
}
|
|
@@ -54315,8 +54371,9 @@ class Evaluator {
|
|
|
54315
54371
|
}
|
|
54316
54372
|
getCellsDependingOn(positions) {
|
|
54317
54373
|
const ranges = [];
|
|
54318
|
-
|
|
54319
|
-
|
|
54374
|
+
const zonesBySheetIds = aggregatePositionsToZones(positions);
|
|
54375
|
+
for (const sheetId in zonesBySheetIds) {
|
|
54376
|
+
ranges.push(...zonesBySheetIds[sheetId].map((zone) => ({ sheetId, zone })));
|
|
54320
54377
|
}
|
|
54321
54378
|
return this.formulaDependencies().getCellsDependingOn(ranges);
|
|
54322
54379
|
}
|
|
@@ -57226,9 +57283,9 @@ class Session extends EventBus {
|
|
|
57226
57283
|
/**
|
|
57227
57284
|
* Notify the server that the user client left the collaborative session
|
|
57228
57285
|
*/
|
|
57229
|
-
leave(data) {
|
|
57286
|
+
async leave(data) {
|
|
57230
57287
|
if (Object.keys(this.clients).length === 1 && this.processedRevisions.size) {
|
|
57231
|
-
this.snapshot(data());
|
|
57288
|
+
await this.snapshot(data());
|
|
57232
57289
|
}
|
|
57233
57290
|
delete this.clients[this.clientId];
|
|
57234
57291
|
this.transportService.leave(this.clientId);
|
|
@@ -57241,12 +57298,12 @@ class Session extends EventBus {
|
|
|
57241
57298
|
/**
|
|
57242
57299
|
* Send a snapshot of the spreadsheet to the collaboration server
|
|
57243
57300
|
*/
|
|
57244
|
-
snapshot(data) {
|
|
57301
|
+
async snapshot(data) {
|
|
57245
57302
|
if (this.pendingMessages.length !== 0) {
|
|
57246
57303
|
return;
|
|
57247
57304
|
}
|
|
57248
57305
|
const snapshotId = this.uuidGenerator.uuidv4();
|
|
57249
|
-
this.transportService.sendMessage({
|
|
57306
|
+
await this.transportService.sendMessage({
|
|
57250
57307
|
type: "SNAPSHOT",
|
|
57251
57308
|
nextRevisionId: snapshotId,
|
|
57252
57309
|
serverRevisionId: this.serverRevisionId,
|
|
@@ -57930,7 +57987,7 @@ class InsertPivotPlugin extends UIPlugin {
|
|
|
57930
57987
|
this.duplicatePivotInNewSheet(cmd.pivotId, cmd.newPivotId, cmd.newSheetId);
|
|
57931
57988
|
break;
|
|
57932
57989
|
case "INSERT_PIVOT_WITH_TABLE":
|
|
57933
|
-
this.insertPivotWithTable(cmd.sheetId, cmd.col, cmd.row, cmd.pivotId, cmd.table);
|
|
57990
|
+
this.insertPivotWithTable(cmd.sheetId, cmd.col, cmd.row, cmd.pivotId, cmd.table, cmd.pivotMode);
|
|
57934
57991
|
break;
|
|
57935
57992
|
}
|
|
57936
57993
|
}
|
|
@@ -58006,26 +58063,44 @@ class InsertPivotPlugin extends UIPlugin {
|
|
|
58006
58063
|
}
|
|
58007
58064
|
return name;
|
|
58008
58065
|
}
|
|
58009
|
-
insertPivotWithTable(sheetId, col, row, pivotId, table) {
|
|
58066
|
+
insertPivotWithTable(sheetId, col, row, pivotId, table, mode) {
|
|
58010
58067
|
const { cols, rows, measures, fieldsType } = table;
|
|
58011
58068
|
const pivotTable = new SpreadsheetPivotTable(cols, rows, measures, fieldsType || {});
|
|
58069
|
+
const numberOfHeaders = pivotTable.columns.length - 1;
|
|
58012
58070
|
this.resizeSheet(sheetId, col, row, pivotTable);
|
|
58013
58071
|
const pivotFormulaId = this.getters.getPivotFormulaId(pivotId);
|
|
58014
|
-
|
|
58015
|
-
|
|
58016
|
-
|
|
58017
|
-
|
|
58018
|
-
|
|
58019
|
-
|
|
58020
|
-
|
|
58021
|
-
|
|
58022
|
-
|
|
58023
|
-
|
|
58024
|
-
|
|
58025
|
-
|
|
58026
|
-
|
|
58072
|
+
let zone;
|
|
58073
|
+
if (mode === "dynamic") {
|
|
58074
|
+
this.dispatch("UPDATE_CELL", {
|
|
58075
|
+
sheetId,
|
|
58076
|
+
col,
|
|
58077
|
+
row,
|
|
58078
|
+
content: `=PIVOT(${pivotFormulaId})`,
|
|
58079
|
+
});
|
|
58080
|
+
zone = {
|
|
58081
|
+
left: col,
|
|
58082
|
+
right: col,
|
|
58083
|
+
top: row,
|
|
58084
|
+
bottom: row,
|
|
58085
|
+
};
|
|
58086
|
+
}
|
|
58087
|
+
else {
|
|
58088
|
+
this.dispatch("INSERT_PIVOT", {
|
|
58089
|
+
sheetId,
|
|
58090
|
+
col,
|
|
58091
|
+
row,
|
|
58092
|
+
pivotId,
|
|
58093
|
+
table: pivotTable.export(),
|
|
58094
|
+
});
|
|
58095
|
+
zone = {
|
|
58096
|
+
left: col,
|
|
58097
|
+
right: col + pivotTable.getNumberOfDataColumns(),
|
|
58098
|
+
top: row,
|
|
58099
|
+
bottom: row + numberOfHeaders + pivotTable.rows.length,
|
|
58100
|
+
};
|
|
58101
|
+
}
|
|
58027
58102
|
this.dispatch("CREATE_TABLE", {
|
|
58028
|
-
tableType:
|
|
58103
|
+
tableType: mode,
|
|
58029
58104
|
sheetId,
|
|
58030
58105
|
ranges: [this.getters.getRangeDataFromZone(sheetId, zone)],
|
|
58031
58106
|
config: { ...PIVOT_TABLE_CONFIG, numberOfHeaders },
|
|
@@ -58587,6 +58662,7 @@ class CellComputedStylePlugin extends UIPlugin {
|
|
|
58587
58662
|
handle(cmd) {
|
|
58588
58663
|
if (invalidateEvaluationCommands.has(cmd.type) ||
|
|
58589
58664
|
cmd.type === "UPDATE_CELL" ||
|
|
58665
|
+
cmd.type === "SET_FORMATTING" ||
|
|
58590
58666
|
cmd.type === "EVALUATE_CELLS") {
|
|
58591
58667
|
this.styles = {};
|
|
58592
58668
|
this.borders = {};
|
|
@@ -60227,6 +60303,8 @@ class GridSelectionPlugin extends UIPlugin {
|
|
|
60227
60303
|
this.selectedFigureId = null;
|
|
60228
60304
|
break;
|
|
60229
60305
|
}
|
|
60306
|
+
}
|
|
60307
|
+
finalize() {
|
|
60230
60308
|
/** Any change to the selection has to be reflected in the selection processor. */
|
|
60231
60309
|
this.selection.resetDefaultAnchor(this, deepCopy(this.gridSelection.anchor));
|
|
60232
60310
|
}
|
|
@@ -61008,7 +61086,6 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
61008
61086
|
}
|
|
61009
61087
|
}
|
|
61010
61088
|
handle(cmd) {
|
|
61011
|
-
this.cleanViewports();
|
|
61012
61089
|
// changing the evaluation can hide/show rows because of data filters
|
|
61013
61090
|
if (invalidateEvaluationCommands.has(cmd.type)) {
|
|
61014
61091
|
for (const sheetId of this.getters.getSheetIds()) {
|
|
@@ -61024,6 +61101,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
61024
61101
|
break;
|
|
61025
61102
|
case "UNDO":
|
|
61026
61103
|
case "REDO":
|
|
61104
|
+
this.cleanViewports();
|
|
61027
61105
|
for (const sheetId of this.getters.getSheetIds()) {
|
|
61028
61106
|
this.sheetsWithDirtyViewports.add(sheetId);
|
|
61029
61107
|
}
|
|
@@ -61078,6 +61156,9 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
61078
61156
|
}
|
|
61079
61157
|
}
|
|
61080
61158
|
break;
|
|
61159
|
+
case "DELETE_SHEET":
|
|
61160
|
+
this.cleanViewports();
|
|
61161
|
+
break;
|
|
61081
61162
|
case "ACTIVATE_SHEET":
|
|
61082
61163
|
this.sheetsWithDirtyViewports.add(cmd.sheetIdTo);
|
|
61083
61164
|
break;
|
|
@@ -62365,6 +62446,17 @@ css /* scss */ `
|
|
|
62365
62446
|
.o-bottom-bar-fade-in {
|
|
62366
62447
|
background-image: linear-gradient(90deg, #cfcfcf, transparent 1%);
|
|
62367
62448
|
}
|
|
62449
|
+
|
|
62450
|
+
.o-sheet-list {
|
|
62451
|
+
overflow-y: hidden;
|
|
62452
|
+
overflow-x: auto;
|
|
62453
|
+
|
|
62454
|
+
&::-webkit-scrollbar {
|
|
62455
|
+
display: none; /* Chrome */
|
|
62456
|
+
}
|
|
62457
|
+
-ms-overflow-style: none; /* IE and Edge */
|
|
62458
|
+
scrollbar-width: none; /* Firefox */
|
|
62459
|
+
}
|
|
62368
62460
|
}
|
|
62369
62461
|
|
|
62370
62462
|
.o-bottom-bar-arrows {
|
|
@@ -64338,7 +64430,7 @@ class Spreadsheet extends Component {
|
|
|
64338
64430
|
|
|
64339
64431
|
class LocalTransportService {
|
|
64340
64432
|
listeners = [];
|
|
64341
|
-
sendMessage(message) {
|
|
64433
|
+
async sendMessage(message) {
|
|
64342
64434
|
for (const { callback } of this.listeners) {
|
|
64343
64435
|
callback(message);
|
|
64344
64436
|
}
|
|
@@ -66431,17 +66523,13 @@ function addFormula(cell) {
|
|
|
66431
66523
|
if (!formula) {
|
|
66432
66524
|
return { attrs: [], node: escapeXml `` };
|
|
66433
66525
|
}
|
|
66434
|
-
const
|
|
66435
|
-
|
|
66436
|
-
|
|
66437
|
-
const XlsxFormula = adaptFormulaToExcel(formula);
|
|
66438
|
-
// hack for cycles : if we don't set a value (be it 0 or #VALUE!), it will appear as invisible on excel,
|
|
66439
|
-
// Making it very hard for the client to find where the recursion is.
|
|
66440
|
-
if (cell.value === CellErrorType.CircularDependency) {
|
|
66441
|
-
attrs.push(["t", "str"]);
|
|
66442
|
-
cycle = escapeXml /*xml*/ `<v>${cell.value}</v>`;
|
|
66526
|
+
const type = getCellType(cell.value);
|
|
66527
|
+
if (type === undefined) {
|
|
66528
|
+
return { attrs: [], node: escapeXml `` };
|
|
66443
66529
|
}
|
|
66444
|
-
|
|
66530
|
+
const attrs = [["t", type]];
|
|
66531
|
+
const XlsxFormula = adaptFormulaToExcel(formula);
|
|
66532
|
+
const node = escapeXml /*xml*/ `<f>${XlsxFormula}</f><v>${cell.value}</v>`;
|
|
66445
66533
|
return { attrs, node };
|
|
66446
66534
|
}
|
|
66447
66535
|
function addContent(content, sharedStrings, forceString = false) {
|
|
@@ -67855,8 +67943,8 @@ class Model extends EventBus {
|
|
|
67855
67943
|
joinSession() {
|
|
67856
67944
|
this.session.join(this.config.client);
|
|
67857
67945
|
}
|
|
67858
|
-
leaveSession() {
|
|
67859
|
-
this.session.leave(lazy(() => this.exportData()));
|
|
67946
|
+
async leaveSession() {
|
|
67947
|
+
await this.session.leave(lazy(() => this.exportData()));
|
|
67860
67948
|
}
|
|
67861
67949
|
setupUiPlugin(Plugin) {
|
|
67862
67950
|
const plugin = new Plugin(this.uiPluginConfig);
|
|
@@ -68328,6 +68416,7 @@ const helpers = {
|
|
|
68328
68416
|
UNDO_REDO_PIVOT_COMMANDS,
|
|
68329
68417
|
createPivotFormula,
|
|
68330
68418
|
areDomainArgsFieldsValid,
|
|
68419
|
+
formatTickValue,
|
|
68331
68420
|
};
|
|
68332
68421
|
const links = {
|
|
68333
68422
|
isMarkdownLink,
|
|
@@ -68415,6 +68504,6 @@ const constants = {
|
|
|
68415
68504
|
export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
|
|
68416
68505
|
|
|
68417
68506
|
|
|
68418
|
-
__info__.version = "17.4.
|
|
68419
|
-
__info__.date = "2024-
|
|
68420
|
-
__info__.hash = "
|
|
68507
|
+
__info__.version = "17.4.8";
|
|
68508
|
+
__info__.date = "2024-09-17T08:10:18.777Z";
|
|
68509
|
+
__info__.hash = "caad8bd";
|