@odoo/o-spreadsheet 18.2.53 → 18.2.54

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.
@@ -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 18.2.53
6
- * @date 2026-05-12T12:17:43.785Z
7
- * @hash d8b08ba
5
+ * @version 18.2.54
6
+ * @date 2026-05-27T05:56:03.418Z
7
+ * @hash bd06c51
8
8
  */
9
9
 
10
10
  (function(exports, _odoo_owl) {
@@ -1347,6 +1347,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1347
1347
  else return ALTERNATING_COLORS_XL;
1348
1348
  }
1349
1349
  var ColorGenerator = class {
1350
+ preferredColors;
1350
1351
  currentColorIndex = 0;
1351
1352
  palette;
1352
1353
  constructor(paletteSize, preferredColors = []) {
@@ -1813,6 +1814,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1813
1814
  return sprintf(_translate(s), ...values);
1814
1815
  };
1815
1816
  var LazyTranslatedString = class extends String {
1817
+ values;
1816
1818
  constructor(str, values) {
1817
1819
  super(str);
1818
1820
  this.values = values;
@@ -3309,6 +3311,8 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
3309
3311
  };
3310
3312
  const errorTypes = new Set(Object.values(CellErrorType));
3311
3313
  var EvaluationError = class {
3314
+ message;
3315
+ value;
3312
3316
  constructor(message = _t("Error"), value = CellErrorType.GenericError) {
3313
3317
  this.message = message;
3314
3318
  this.value = value;
@@ -3341,6 +3345,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
3341
3345
  }
3342
3346
  };
3343
3347
  var SplillBlockedError = class extends EvaluationError {
3348
+ errorOriginPosition;
3344
3349
  constructor(message = _t("Spill range is not empty"), errorOriginPosition) {
3345
3350
  super(message, CellErrorType.SpilledBlocked);
3346
3351
  this.errorOriginPosition = errorOriginPosition;
@@ -5174,6 +5179,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
5174
5179
  //#endregion
5175
5180
  //#region src/helpers/range.ts
5176
5181
  var RangeImpl = class RangeImpl {
5182
+ getSheetSize;
5177
5183
  _zone;
5178
5184
  parts;
5179
5185
  invalidXc;
@@ -5861,6 +5867,8 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
5861
5867
  //#endregion
5862
5868
  //#region src/clipboard_handlers/abstract_clipboard_handler.ts
5863
5869
  var ClipboardHandler = class {
5870
+ getters;
5871
+ dispatch;
5864
5872
  constructor(getters, dispatch) {
5865
5873
  this.getters = getters;
5866
5874
  this.dispatch = dispatch;
@@ -8268,6 +8276,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
8268
8276
  }
8269
8277
  };
8270
8278
  var StoreFactory = class {
8279
+ get;
8271
8280
  pendingBuilds = /* @__PURE__ */ new Set();
8272
8281
  constructor(get) {
8273
8282
  this.get = get;
@@ -8312,6 +8321,7 @@ stores.inject(MyMetaStore, storeInstance);
8312
8321
  return MetaStore;
8313
8322
  }
8314
8323
  var DisposableStore = class {
8324
+ get;
8315
8325
  disposeCallbacks = [];
8316
8326
  constructor(get) {
8317
8327
  this.get = get;
@@ -9455,6 +9465,7 @@ stores.inject(MyMetaStore, storeInstance);
9455
9465
  }, runtime).computeDesign();
9456
9466
  }
9457
9467
  var ScorecardChartConfigBuilder = class {
9468
+ runtime;
9458
9469
  context;
9459
9470
  width;
9460
9471
  height;
@@ -18109,6 +18120,7 @@ stores.inject(MyMetaStore, storeInstance);
18109
18120
  //#endregion
18110
18121
  //#region src/formulas/code_builder.ts
18111
18122
  var FunctionCodeBuilder = class {
18123
+ scope;
18112
18124
  code = "";
18113
18125
  constructor(scope = new Scope()) {
18114
18126
  this.scope = scope;
@@ -18124,6 +18136,8 @@ stores.inject(MyMetaStore, storeInstance);
18124
18136
  }
18125
18137
  };
18126
18138
  var FunctionCodeImpl = class {
18139
+ scope;
18140
+ returnExpression;
18127
18141
  code;
18128
18142
  constructor(scope, code, returnExpression) {
18129
18143
  this.scope = scope;
@@ -18504,6 +18518,9 @@ stores.inject(MyMetaStore, storeInstance);
18504
18518
  function getFirstPivotFunction(tokens) {
18505
18519
  return getFunctionsFromTokens(tokens, PIVOT_FUNCTIONS)[0];
18506
18520
  }
18521
+ function getPivotFunctions(tokens) {
18522
+ return getFunctionsFromTokens(tokens, PIVOT_FUNCTIONS);
18523
+ }
18507
18524
  /**
18508
18525
  * Parse a spreadsheet formula and detect the number of PIVOT functions that are
18509
18526
  * present in the given formula.
@@ -19554,6 +19571,7 @@ stores.inject(MyMetaStore, storeInstance);
19554
19571
  * Represent a raw XML string
19555
19572
  */
19556
19573
  var XMLString = class {
19574
+ xmlString;
19557
19575
  /**
19558
19576
  * @param xmlString should be a well formed, properly escaped XML string
19559
19577
  */
@@ -19672,6 +19690,10 @@ stores.inject(MyMetaStore, storeInstance);
19672
19690
  ROUNDDOWN: [{
19673
19691
  type: "NUMBER",
19674
19692
  value: 0
19693
+ }],
19694
+ IFERROR: [{
19695
+ type: "NUMBER",
19696
+ value: 0
19675
19697
  }]
19676
19698
  };
19677
19699
  /**
@@ -29587,6 +29609,10 @@ stores.inject(MyMetaStore, storeInstance);
29587
29609
  }
29588
29610
  };
29589
29611
  var PopoverPositionContext = class {
29612
+ anchorRect;
29613
+ containerRect;
29614
+ propsMaxSize;
29615
+ spreadsheetOffset;
29590
29616
  constructor(anchorRect, containerRect, propsMaxSize, spreadsheetOffset) {
29591
29617
  this.anchorRect = anchorRect;
29592
29618
  this.containerRect = containerRect;
@@ -32625,7 +32651,7 @@ stores.inject(MyMetaStore, storeInstance);
32625
32651
  col,
32626
32652
  row
32627
32653
  };
32628
- if (pivotId === getters.getPivotIdFromPosition(position)) positions.push(position);
32654
+ if (getters.getPivotIdsFromPosition(position).includes(pivotId)) positions.push(position);
32629
32655
  }
32630
32656
  return positions;
32631
32657
  }
@@ -33403,6 +33429,7 @@ stores.inject(MyMetaStore, storeInstance);
33403
33429
  }
33404
33430
  };
33405
33431
  var ContainerWrapper = class {
33432
+ el;
33406
33433
  constructor(el) {
33407
33434
  this.el = el;
33408
33435
  }
@@ -33488,6 +33515,9 @@ stores.inject(MyMetaStore, storeInstance);
33488
33515
  * This plugin handles this internal state.
33489
33516
  */
33490
33517
  var SelectionInputStore = class extends SpreadsheetStore {
33518
+ initialRanges;
33519
+ inputHasSingleRange;
33520
+ colors;
33491
33521
  mutators = [
33492
33522
  "resetWithRanges",
33493
33523
  "focusById",
@@ -36400,6 +36430,7 @@ stores.inject(MyMetaStore, storeInstance);
36400
36430
  //#endregion
36401
36431
  //#region src/components/composer/standalone_composer/standalone_composer_store.ts
36402
36432
  var StandaloneComposerStore = class extends AbstractComposerStore {
36433
+ args;
36403
36434
  constructor(get, args) {
36404
36435
  super(get);
36405
36436
  this.args = args;
@@ -39974,6 +40005,8 @@ stores.inject(MyMetaStore, storeInstance);
39974
40005
  //#endregion
39975
40006
  //#region src/components/side_panel/pivot/pivot_measure_display_panel/pivot_measure_display_panel_store.ts
39976
40007
  var PivotMeasureDisplayPanelStore = class extends SpreadsheetStore {
40008
+ pivotId;
40009
+ initialMeasure;
39977
40010
  mutators = [
39978
40011
  "cancelMeasureDisplayEdition",
39979
40012
  "updateMeasureDisplayType",
@@ -41012,13 +41045,30 @@ stores.inject(MyMetaStore, storeInstance);
41012
41045
  } : fields[fieldName];
41013
41046
  const aggregator = measure.aggregator;
41014
41047
  return {
41048
+ /**
41049
+ * Get the id of the measure, as it is stored in the pivot formula
41050
+ */
41015
41051
  id: measure.id,
41052
+ /**
41053
+ * Display name of the measure
41054
+ * e.g. "__count" -> "Count", "amount_total" -> "Total Amount"
41055
+ */
41016
41056
  get displayName() {
41017
41057
  return measure.userDefinedName ?? field?.string ?? measure.fieldName;
41018
41058
  },
41019
41059
  userDefinedName: measure.userDefinedName,
41060
+ /**
41061
+ * Get the name of the field of the measure
41062
+ */
41020
41063
  fieldName,
41064
+ /**
41065
+ * Get the aggregator of the measure
41066
+ */
41021
41067
  aggregator,
41068
+ /**
41069
+ * Get the type of the measure field
41070
+ * e.g. "stage_id" -> "many2one", "create_date:month" -> "date"
41071
+ */
41022
41072
  type: fieldName === "__count" ? "integer" : field?.type ?? "integer",
41023
41073
  isValid: !!(field || measure.computedBy),
41024
41074
  isHidden: measure.isHidden,
@@ -41032,10 +41082,30 @@ stores.inject(MyMetaStore, storeInstance);
41032
41082
  const type = field?.type ?? "integer";
41033
41083
  const granularity = field && isDateOrDatetimeField(field) ? dimension.granularity : void 0;
41034
41084
  return {
41085
+ /**
41086
+ * Get the display name of the dimension
41087
+ * e.g. "stage_id" -> "Stage", "create_date:month" -> "Create Date"
41088
+ */
41035
41089
  displayName: field?.string ?? dimension.fieldName,
41090
+ /**
41091
+ * Get the name of the dimension, as it is stored in the pivot formula
41092
+ * e.g. "stage_id", "create_date:month"
41093
+ */
41036
41094
  nameWithGranularity: dimension.fieldName + (granularity ? `:${granularity}` : ""),
41095
+ /**
41096
+ * Get the name of the field of the dimension
41097
+ * e.g. "stage_id" -> "stage_id", "create_date:month" -> "create_date"
41098
+ */
41037
41099
  fieldName: dimension.fieldName,
41100
+ /**
41101
+ * Get the aggregate operator of the dimension
41102
+ * e.g. "stage_id" -> undefined, "create_date:month" -> "month"
41103
+ */
41038
41104
  granularity,
41105
+ /**
41106
+ * Get the type of the field of the dimension
41107
+ * e.g. "stage_id" -> "many2one", "create_date:month" -> "date"
41108
+ */
41039
41109
  type,
41040
41110
  order: dimension.order,
41041
41111
  isValid: !!field
@@ -42075,6 +42145,7 @@ stores.inject(MyMetaStore, storeInstance);
42075
42145
  //#endregion
42076
42146
  //#region src/components/side_panel/pivot/pivot_side_panel/pivot_side_panel_store.ts
42077
42147
  var PivotSidePanelStore = class extends SpreadsheetStore {
42148
+ pivotId;
42078
42149
  mutators = [
42079
42150
  "reset",
42080
42151
  "deferUpdates",
@@ -49576,6 +49647,11 @@ stores.inject(MyMetaStore, storeInstance);
49576
49647
  }
49577
49648
  };
49578
49649
  var FormulaCellWithDependencies = class {
49650
+ id;
49651
+ format;
49652
+ style;
49653
+ sheetId;
49654
+ getRangeString;
49579
49655
  isFormula = true;
49580
49656
  compiledFormula;
49581
49657
  constructor(id, compiledFormula, format, style, dependencies, sheetId, getRangeString) {
@@ -49610,6 +49686,10 @@ stores.inject(MyMetaStore, storeInstance);
49610
49686
  }
49611
49687
  };
49612
49688
  var RangeReferenceToken = class {
49689
+ ranges;
49690
+ rangeIndex;
49691
+ sheetId;
49692
+ getRangeString;
49613
49693
  type = "REFERENCE";
49614
49694
  constructor(ranges, rangeIndex, sheetId, getRangeString) {
49615
49695
  this.ranges = ranges;
@@ -53506,6 +53586,8 @@ stores.inject(MyMetaStore, storeInstance);
53506
53586
  return new CompilationParametersBuilder(context, getters, computeCell).getParameters();
53507
53587
  }
53508
53588
  var CompilationParametersBuilder = class {
53589
+ getters;
53590
+ computeCell;
53509
53591
  evalContext;
53510
53592
  rangeCache = {};
53511
53593
  constructor(context, getters, computeCell) {
@@ -53959,6 +54041,7 @@ stores.inject(MyMetaStore, storeInstance);
53959
54041
  * It uses an R-Tree data structure to efficiently find dependent cells.
53960
54042
  */
53961
54043
  var FormulaDependencyGraph = class {
54044
+ createEmptyPositionSet;
53962
54045
  dependencies = new PositionMap();
53963
54046
  rTree;
53964
54047
  constructor(createEmptyPositionSet, data = []) {
@@ -54260,6 +54343,7 @@ stores.inject(MyMetaStore, storeInstance);
54260
54343
  const ERROR_CYCLE_CELL = Object.freeze(createEvaluatedCell(new CircularDependencyError()));
54261
54344
  const EMPTY_CELL = Object.freeze(createEvaluatedCell({ value: null }));
54262
54345
  var Evaluator = class {
54346
+ context;
54263
54347
  getters;
54264
54348
  compilationParams;
54265
54349
  evaluatedCells = new PositionMap();
@@ -56242,6 +56326,7 @@ stores.inject(MyMetaStore, storeInstance);
56242
56326
  "getPivot",
56243
56327
  "getFirstPivotFunction",
56244
56328
  "getPivotIdFromPosition",
56329
+ "getPivotIdsFromPosition",
56245
56330
  "getPivotCellFromPosition",
56246
56331
  "generateNewCalculatedMeasureName",
56247
56332
  "isPivotUnused",
@@ -56299,37 +56384,52 @@ stores.inject(MyMetaStore, storeInstance);
56299
56384
  }
56300
56385
  }
56301
56386
  /**
56302
- * Get the id of the pivot at the given position. Returns undefined if there
56387
+ * Get the id of the first pivot in the formula at the given position. Returns undefined if there
56303
56388
  * is no pivot at this position
56304
56389
  */
56305
56390
  getPivotIdFromPosition(position) {
56391
+ return this.getPivotIdsFromPosition(position)[0];
56392
+ }
56393
+ /**
56394
+ * Get all of the ids of the pivot present in the formula at the given position.
56395
+ */
56396
+ getPivotIdsFromPosition(position) {
56306
56397
  const cell = this.getters.getCorrespondingFormulaCell(position);
56307
- if (cell && cell.isFormula) {
56308
- const pivotFunction = this.getFirstPivotFunction(position.sheetId, cell.compiledFormula.tokens);
56309
- if (pivotFunction) {
56310
- const pivotId = pivotFunction.args[0]?.toString();
56311
- return pivotId && this.getters.getPivotId(pivotId);
56312
- }
56313
- }
56398
+ if (cell && cell.isFormula) return this.getPivotIdsFromFormula(position.sheetId, cell.compiledFormula);
56399
+ return [];
56400
+ }
56401
+ getPivotIdsFromFormula(sheetId, formula) {
56402
+ return this.getPivotFunctions(sheetId, formula.tokens).map((pivotFunction) => {
56403
+ const pivotId = pivotFunction.args[0]?.toString();
56404
+ return pivotId && this.getters.getPivotId(pivotId);
56405
+ }).filter(isDefined);
56314
56406
  }
56315
56407
  isSpillPivotFormula(position) {
56316
56408
  const cell = this.getters.getCorrespondingFormulaCell(position);
56317
56409
  if (cell && cell.isFormula) return this.getFirstPivotFunction(position.sheetId, cell.compiledFormula.tokens)?.functionName === "PIVOT";
56318
56410
  return false;
56319
56411
  }
56320
- getFirstPivotFunction(sheetId, tokens) {
56321
- const pivotFunction = getFirstPivotFunction(tokens);
56322
- if (!pivotFunction) return;
56323
- const { functionName, args } = pivotFunction;
56324
- return {
56325
- functionName,
56326
- args: args.map((argAst) => {
56412
+ getPivotFunctions(sheetId, tokens) {
56413
+ const pivotFunctions = getPivotFunctions(tokens);
56414
+ if (!pivotFunctions.length) return [];
56415
+ const evaluatedPivotFunctions = [];
56416
+ for (const pivotFunction of pivotFunctions) {
56417
+ const { functionName, args } = pivotFunction;
56418
+ const evaluatedArgs = args.map((argAst) => {
56327
56419
  if (argAst.type === "EMPTY") return;
56328
56420
  else if (argAst.type === "STRING" || argAst.type === "BOOLEAN" || argAst.type === "NUMBER") return argAst.value;
56329
56421
  const argsString = astToFormula(argAst);
56330
56422
  return this.getters.evaluateFormula(sheetId, argsString);
56331
- })
56332
- };
56423
+ });
56424
+ evaluatedPivotFunctions.push({
56425
+ functionName,
56426
+ args: evaluatedArgs
56427
+ });
56428
+ }
56429
+ return evaluatedPivotFunctions;
56430
+ }
56431
+ getFirstPivotFunction(sheetId, tokens) {
56432
+ return this.getPivotFunctions(sheetId, tokens)[0];
56333
56433
  }
56334
56434
  /**
56335
56435
  * Returns the domain args of a pivot formula from a position.
@@ -56423,8 +56523,8 @@ stores.inject(MyMetaStore, storeInstance);
56423
56523
  const unusedPivots = new Set(this.getters.getPivotIds());
56424
56524
  for (const sheetId of this.getters.getSheetIds()) for (const cellId in this.getters.getCells(sheetId)) {
56425
56525
  const position = this.getters.getCellPosition(cellId);
56426
- const pivotId = this.getPivotIdFromPosition(position);
56427
- if (pivotId) {
56526
+ const pivotIds = this.getPivotIdsFromPosition(position);
56527
+ for (const pivotId of pivotIds) {
56428
56528
  unusedPivots.delete(pivotId);
56429
56529
  if (!unusedPivots.size) {
56430
56530
  this.unusedPivots = [];
@@ -56432,6 +56532,21 @@ stores.inject(MyMetaStore, storeInstance);
56432
56532
  }
56433
56533
  }
56434
56534
  }
56535
+ for (const pivotId of this.getters.getPivotIds()) {
56536
+ const pivot = this.getters.getPivot(pivotId);
56537
+ for (const measure of pivot.definition.measures) if (measure.computedBy) {
56538
+ const { sheetId } = measure.computedBy;
56539
+ const formula = this.getters.getMeasureCompiledFormula(pivotId, measure);
56540
+ const relatedPivotIds = this.getPivotIdsFromFormula(sheetId, formula);
56541
+ for (const relatedPivotId of relatedPivotIds) {
56542
+ unusedPivots.delete(relatedPivotId);
56543
+ if (!unusedPivots.size) {
56544
+ this.unusedPivots = [];
56545
+ return [];
56546
+ }
56547
+ }
56548
+ }
56549
+ }
56435
56550
  this.unusedPivots = [...unusedPivots];
56436
56551
  return this.unusedPivots;
56437
56552
  }
@@ -57584,6 +57699,8 @@ stores.inject(MyMetaStore, storeInstance);
57584
57699
  //#endregion
57585
57700
  //#region src/collaborative/revisions.ts
57586
57701
  var Revision = class {
57702
+ rootCommand;
57703
+ timestamp;
57587
57704
  id;
57588
57705
  clientId;
57589
57706
  _commands = [];
@@ -57620,6 +57737,9 @@ stores.inject(MyMetaStore, storeInstance);
57620
57737
  //#region src/collaborative/session.ts
57621
57738
  var ClientDisconnectedError = class extends Error {};
57622
57739
  var Session = class extends EventBus {
57740
+ revisions;
57741
+ transportService;
57742
+ serverRevisionId;
57623
57743
  /**
57624
57744
  * Positions of the others client.
57625
57745
  */
@@ -61059,6 +61179,9 @@ stores.inject(MyMetaStore, storeInstance);
61059
61179
  //#endregion
61060
61180
  //#region src/helpers/internal_viewport.ts
61061
61181
  var InternalViewport = class {
61182
+ getters;
61183
+ sheetId;
61184
+ boundaries;
61062
61185
  top;
61063
61186
  bottom;
61064
61187
  left;
@@ -64272,6 +64395,7 @@ stores.inject(MyMetaStore, storeInstance);
64272
64395
  return new WebClipboardWrapper(navigator.clipboard);
64273
64396
  }
64274
64397
  var WebClipboardWrapper = class {
64398
+ clipboard;
64275
64399
  constructor(clipboard) {
64276
64400
  this.clipboard = clipboard;
64277
64401
  }
@@ -64750,6 +64874,8 @@ stores.inject(MyMetaStore, storeInstance);
64750
64874
  * @param operations initial operations
64751
64875
  */
64752
64876
  var Branch = class Branch {
64877
+ buildTransformation;
64878
+ operations;
64753
64879
  constructor(buildTransformation, operations = []) {
64754
64880
  this.buildTransformation = buildTransformation;
64755
64881
  this.operations = operations;
@@ -64866,6 +64992,8 @@ stores.inject(MyMetaStore, storeInstance);
64866
64992
  * to revert it).
64867
64993
  */
64868
64994
  var Operation = class {
64995
+ id;
64996
+ data;
64869
64997
  constructor(id, data) {
64870
64998
  this.id = id;
64871
64999
  this.data = data;
@@ -64875,6 +65003,8 @@ stores.inject(MyMetaStore, storeInstance);
64875
65003
  }
64876
65004
  };
64877
65005
  var LazyOperation = class LazyOperation {
65006
+ id;
65007
+ lazyData;
64878
65008
  constructor(id, lazyData) {
64879
65009
  this.id = id;
64880
65010
  this.lazyData = lazyData;
@@ -64900,6 +65030,7 @@ stores.inject(MyMetaStore, storeInstance);
64900
65030
  * ```
64901
65031
  */
64902
65032
  var OperationSequence = class OperationSequence {
65033
+ operations;
64903
65034
  constructor(operations) {
64904
65035
  this.operations = operations;
64905
65036
  }
@@ -64975,6 +65106,7 @@ stores.inject(MyMetaStore, storeInstance);
64975
65106
  *
64976
65107
  */
64977
65108
  var Tree = class {
65109
+ buildTransformation;
64978
65110
  branches;
64979
65111
  branchingOperationIds = /* @__PURE__ */ new Map();
64980
65112
  constructor(buildTransformation, initialBranch) {
@@ -65557,6 +65689,7 @@ stores.inject(MyMetaStore, storeInstance);
65557
65689
  * with the new selected anchor
65558
65690
  */
65559
65691
  var SelectionStreamProcessorImpl = class {
65692
+ getters;
65560
65693
  stream;
65561
65694
  /**
65562
65695
  * "Active" anchor used as a reference to compute new anchors
@@ -68850,8 +68983,8 @@ exports.stores = stores;
68850
68983
  exports.tokenColors = tokenColors;
68851
68984
  exports.tokenize = tokenize;
68852
68985
 
68853
- __info__.version = "18.2.53";
68854
- __info__.date = "2026-05-12T12:17:43.785Z";
68855
- __info__.hash = "d8b08ba";
68986
+ __info__.version = "18.2.54";
68987
+ __info__.date = "2026-05-27T05:56:03.418Z";
68988
+ __info__.hash = "bd06c51";
68856
68989
 
68857
68990
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);