@actual-app/api 6.8.2 → 6.9.0

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.
@@ -23720,17 +23720,21 @@
23720
23720
  /* harmony export */ deleteRule: () => ( /* binding */deleteRule),
23721
23721
  /* harmony export */ deleteTransaction: () => ( /* binding */deleteTransaction),
23722
23722
  /* harmony export */ downloadBudget: () => ( /* binding */downloadBudget),
23723
+ /* harmony export */ getAccountBalance: () => ( /* binding */getAccountBalance),
23723
23724
  /* harmony export */ getAccounts: () => ( /* binding */getAccounts),
23724
23725
  /* harmony export */ getBudgetMonth: () => ( /* binding */getBudgetMonth),
23725
23726
  /* harmony export */ getBudgetMonths: () => ( /* binding */getBudgetMonths),
23727
+ /* harmony export */ getBudgets: () => ( /* binding */getBudgets),
23726
23728
  /* harmony export */ getCategories: () => ( /* binding */getCategories),
23727
23729
  /* harmony export */ getCategoryGroups: () => ( /* binding */getCategoryGroups),
23730
+ /* harmony export */ getCommonPayees: () => ( /* binding */getCommonPayees),
23728
23731
  /* harmony export */ getPayeeRules: () => ( /* binding */getPayeeRules),
23729
23732
  /* harmony export */ getPayees: () => ( /* binding */getPayees),
23730
23733
  /* harmony export */ getRules: () => ( /* binding */getRules),
23731
23734
  /* harmony export */ getTransactions: () => ( /* binding */getTransactions),
23732
23735
  /* harmony export */ importTransactions: () => ( /* binding */importTransactions),
23733
23736
  /* harmony export */ loadBudget: () => ( /* binding */loadBudget),
23737
+ /* harmony export */ mergePayees: () => ( /* binding */mergePayees),
23734
23738
  /* harmony export */ q: () => ( /* reexport safe */_app_query__WEBPACK_IMPORTED_MODULE_1__.q),
23735
23739
  /* harmony export */ reopenAccount: () => ( /* binding */reopenAccount),
23736
23740
  /* harmony export */ runBankSync: () => ( /* binding */runBankSync),
@@ -23983,6 +23987,20 @@
23983
23987
  });
23984
23988
  return _downloadBudget.apply(this, arguments);
23985
23989
  }
23990
+ function getBudgets() {
23991
+ return _getBudgets.apply(this, arguments);
23992
+ }
23993
+ function _getBudgets() {
23994
+ _getBudgets = _async_to_generator(function () {
23995
+ return _ts_generator(this, function (_state) {
23996
+ return [
23997
+ 2,
23998
+ send('api/get-budgets')
23999
+ ];
24000
+ });
24001
+ });
24002
+ return _getBudgets.apply(this, arguments);
24003
+ }
23986
24004
  function sync() {
23987
24005
  return _sync.apply(this, arguments);
23988
24006
  }
@@ -24154,6 +24172,12 @@
24154
24172
  id: id
24155
24173
  });
24156
24174
  }
24175
+ function getAccountBalance(id, cutoff) {
24176
+ return send('api/account-balance', {
24177
+ id: id,
24178
+ cutoff: cutoff
24179
+ });
24180
+ }
24157
24181
  function getCategoryGroups() {
24158
24182
  return send('api/category-groups-get');
24159
24183
  }
@@ -24196,6 +24220,9 @@
24196
24220
  transferCategoryId: transferCategoryId
24197
24221
  });
24198
24222
  }
24223
+ function getCommonPayees() {
24224
+ return send('api/common-payees-get');
24225
+ }
24199
24226
  function getPayees() {
24200
24227
  return send('api/payees-get');
24201
24228
  }
@@ -24215,6 +24242,12 @@
24215
24242
  id: id
24216
24243
  });
24217
24244
  }
24245
+ function mergePayees(targetId, mergeIds) {
24246
+ return send('api/payees-merge', {
24247
+ targetId: targetId,
24248
+ mergeIds: mergeIds
24249
+ });
24250
+ }
24218
24251
  function getRules() {
24219
24252
  return send('api/rules-get');
24220
24253
  }
@@ -24422,18 +24455,17 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
24422
24455
  /* harmony import */ var _server_budget_base__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../server/budget/base */ "./packages/loot-core/src/server/budget/base.ts");
24423
24456
  /* harmony import */ var _server_db__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../server/db */ "./packages/loot-core/src/server/db/index.ts");
24424
24457
  /* harmony import */ var _server_mutators__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../server/mutators */ "./packages/loot-core/src/server/mutators.ts");
24425
- /* harmony import */ var _server_prefs__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../server/prefs */ "./packages/loot-core/src/server/prefs.ts");
24426
- /* harmony import */ var _server_sheet__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../server/sheet */ "./packages/loot-core/src/server/sheet.ts");
24427
- /* harmony import */ var _server_sync__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../server/sync */ "./packages/loot-core/src/server/sync/index.ts");
24428
- /* harmony import */ var _shared_months__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../shared/months */ "./packages/loot-core/src/shared/months.ts");
24429
- /* harmony import */ var _shared_query__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../shared/query */ "./packages/loot-core/src/shared/query.ts");
24430
- /* harmony import */ var _random__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./random */ "./packages/loot-core/src/mocks/random.ts");
24458
+ /* harmony import */ var _server_sheet__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../server/sheet */ "./packages/loot-core/src/server/sheet.ts");
24459
+ /* harmony import */ var _server_sync__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../server/sync */ "./packages/loot-core/src/server/sync/index.ts");
24460
+ /* harmony import */ var _shared_months__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../shared/months */ "./packages/loot-core/src/shared/months.ts");
24461
+ /* harmony import */ var _shared_query__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../shared/query */ "./packages/loot-core/src/shared/query.ts");
24462
+ /* harmony import */ var _random__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./random */ "./packages/loot-core/src/mocks/random.ts");
24431
24463
  // @ts-strict-ignore
24432
24464
  function pickRandom(list) {
24433
- return list[Math.floor((0, _random__WEBPACK_IMPORTED_MODULE_11__.random)() * list.length) % list.length];
24465
+ return list[Math.floor((0, _random__WEBPACK_IMPORTED_MODULE_10__.random)() * list.length) % list.length];
24434
24466
  }
24435
24467
  function number(start, end) {
24436
- return start + (end - start) * (0, _random__WEBPACK_IMPORTED_MODULE_11__.random)();
24468
+ return start + (end - start) * (0, _random__WEBPACK_IMPORTED_MODULE_10__.random)();
24437
24469
  }
24438
24470
  function integer(start, end) {
24439
24471
  return Math.round(number(start, end));
@@ -24479,7 +24511,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
24479
24511
  const transactions = [];
24480
24512
  for (let i = 0; i < numTransactions; i++) {
24481
24513
  let payee;
24482
- if ((0, _random__WEBPACK_IMPORTED_MODULE_11__.random)() < 0.09) {
24514
+ if ((0, _random__WEBPACK_IMPORTED_MODULE_10__.random)() < 0.09) {
24483
24515
  payee = incomePayee;
24484
24516
  }
24485
24517
  else {
@@ -24497,17 +24529,17 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
24497
24529
  amount = integer(50000, 70000);
24498
24530
  }
24499
24531
  else {
24500
- amount = integer(0, (0, _random__WEBPACK_IMPORTED_MODULE_11__.random)() < 0.05 ? -8000 : -700);
24532
+ amount = integer(0, (0, _random__WEBPACK_IMPORTED_MODULE_10__.random)() < 0.05 ? -8000 : -700);
24501
24533
  }
24502
24534
  const transaction = {
24503
24535
  amount,
24504
24536
  payee: payee.id,
24505
24537
  account: account.id,
24506
- date: _shared_months__WEBPACK_IMPORTED_MODULE_9__.subDays(_shared_months__WEBPACK_IMPORTED_MODULE_9__.currentDay(), Math.floor(i / 3)),
24538
+ date: _shared_months__WEBPACK_IMPORTED_MODULE_8__.subDays(_shared_months__WEBPACK_IMPORTED_MODULE_8__.currentDay(), Math.floor(i / 3)),
24507
24539
  category: category.id
24508
24540
  };
24509
24541
  transactions.push(transaction);
24510
- if ((0, _random__WEBPACK_IMPORTED_MODULE_11__.random)() < 0.2) {
24542
+ if ((0, _random__WEBPACK_IMPORTED_MODULE_10__.random)() < 0.2) {
24511
24543
  const a = Math.round(transaction.amount / 3);
24512
24544
  const pick = () => payee === incomePayee ? incomeGroup.categories.find((c) => c.name === 'Income').id : pickRandom(expenseCategories).id;
24513
24545
  transaction.subtransactions = [
@@ -24526,12 +24558,12 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
24526
24558
  ];
24527
24559
  }
24528
24560
  }
24529
- const earliestMonth = _shared_months__WEBPACK_IMPORTED_MODULE_9__.monthFromDate(transactions[transactions.length - 1].date);
24530
- const months = _shared_months__WEBPACK_IMPORTED_MODULE_9__.rangeInclusive(earliestMonth, _shared_months__WEBPACK_IMPORTED_MODULE_9__.currentMonth());
24531
- const currentDay = _shared_months__WEBPACK_IMPORTED_MODULE_9__.currentDay();
24561
+ const earliestMonth = _shared_months__WEBPACK_IMPORTED_MODULE_8__.monthFromDate(transactions[transactions.length - 1].date);
24562
+ const months = _shared_months__WEBPACK_IMPORTED_MODULE_8__.rangeInclusive(earliestMonth, _shared_months__WEBPACK_IMPORTED_MODULE_8__.currentMonth());
24563
+ const currentDay = _shared_months__WEBPACK_IMPORTED_MODULE_8__.currentDay();
24532
24564
  for (const month of months) {
24533
- let date = _shared_months__WEBPACK_IMPORTED_MODULE_9__.addDays(month, 12);
24534
- if (_shared_months__WEBPACK_IMPORTED_MODULE_9__.isBefore(date, currentDay)) {
24565
+ let date = _shared_months__WEBPACK_IMPORTED_MODULE_8__.addDays(month, 12);
24566
+ if (_shared_months__WEBPACK_IMPORTED_MODULE_8__.isBefore(date, currentDay)) {
24535
24567
  transactions.push({
24536
24568
  amount: -10000,
24537
24569
  payee: billPayees.find((p) => p.name.toLowerCase().includes('power')).id,
@@ -24540,8 +24572,8 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
24540
24572
  category: billCategories.find((c) => c.name === 'Power').id
24541
24573
  });
24542
24574
  }
24543
- date = _shared_months__WEBPACK_IMPORTED_MODULE_9__.addDays(month, 18);
24544
- if (_shared_months__WEBPACK_IMPORTED_MODULE_9__.isBefore(date, currentDay)) {
24575
+ date = _shared_months__WEBPACK_IMPORTED_MODULE_8__.addDays(month, 18);
24576
+ if (_shared_months__WEBPACK_IMPORTED_MODULE_8__.isBefore(date, currentDay)) {
24545
24577
  transactions.push({
24546
24578
  amount: -9000,
24547
24579
  payee: billPayees.find((p) => p.name.toLowerCase().includes('water')).id,
@@ -24550,8 +24582,8 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
24550
24582
  category: billCategories.find((c) => c.name === 'Water').id
24551
24583
  });
24552
24584
  }
24553
- date = _shared_months__WEBPACK_IMPORTED_MODULE_9__.addDays(month, 2);
24554
- if (_shared_months__WEBPACK_IMPORTED_MODULE_9__.isBefore(date, currentDay)) {
24585
+ date = _shared_months__WEBPACK_IMPORTED_MODULE_8__.addDays(month, 2);
24586
+ if (_shared_months__WEBPACK_IMPORTED_MODULE_8__.isBefore(date, currentDay)) {
24555
24587
  transactions.push({
24556
24588
  amount: -120000,
24557
24589
  payee: billPayees.find((p) => p.name.toLowerCase().includes('housy')).id,
@@ -24560,8 +24592,8 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
24560
24592
  category: billCategories.find((c) => c.name === 'Mortgage').id
24561
24593
  });
24562
24594
  }
24563
- date = _shared_months__WEBPACK_IMPORTED_MODULE_9__.addDays(month, 20);
24564
- if (_shared_months__WEBPACK_IMPORTED_MODULE_9__.isBefore(date, currentDay)) {
24595
+ date = _shared_months__WEBPACK_IMPORTED_MODULE_8__.addDays(month, 20);
24596
+ if (_shared_months__WEBPACK_IMPORTED_MODULE_8__.isBefore(date, currentDay)) {
24565
24597
  transactions.push({
24566
24598
  amount: -6000,
24567
24599
  payee: billPayees.find((p) => p.name.toLowerCase().includes('internet')).id,
@@ -24570,8 +24602,8 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
24570
24602
  category: billCategories.find((c) => c.name === 'Internet').id
24571
24603
  });
24572
24604
  }
24573
- date = _shared_months__WEBPACK_IMPORTED_MODULE_9__.addDays(month, 23);
24574
- if (_shared_months__WEBPACK_IMPORTED_MODULE_9__.isBefore(date, currentDay)) {
24605
+ date = _shared_months__WEBPACK_IMPORTED_MODULE_8__.addDays(month, 23);
24606
+ if (_shared_months__WEBPACK_IMPORTED_MODULE_8__.isBefore(date, currentDay)) {
24575
24607
  transactions.push({
24576
24608
  amount: -7500,
24577
24609
  payee: billPayees.find((p) => p.name.toLowerCase().includes('t-mobile')).id,
@@ -24603,7 +24635,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
24603
24635
  const transactions = [];
24604
24636
  for (let i = 0; i < numTransactions; i++) {
24605
24637
  let payee;
24606
- if ((0, _random__WEBPACK_IMPORTED_MODULE_11__.random)() < 0.04) {
24638
+ if ((0, _random__WEBPACK_IMPORTED_MODULE_10__.random)() < 0.04) {
24607
24639
  payee = incomePayee;
24608
24640
  }
24609
24641
  else {
@@ -24621,7 +24653,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
24621
24653
  amount,
24622
24654
  payee: payee.id,
24623
24655
  account: account.id,
24624
- date: _shared_months__WEBPACK_IMPORTED_MODULE_9__.subDays(_shared_months__WEBPACK_IMPORTED_MODULE_9__.currentDay(), i * 2),
24656
+ date: _shared_months__WEBPACK_IMPORTED_MODULE_8__.subDays(_shared_months__WEBPACK_IMPORTED_MODULE_8__.currentDay(), i * 2),
24625
24657
  category: category.id
24626
24658
  });
24627
24659
  }
@@ -24650,7 +24682,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
24650
24682
  amount,
24651
24683
  payee: payee.id,
24652
24684
  account: account.id,
24653
- date: _shared_months__WEBPACK_IMPORTED_MODULE_9__.subDays(_shared_months__WEBPACK_IMPORTED_MODULE_9__.currentDay(), integer(10, 360)),
24685
+ date: _shared_months__WEBPACK_IMPORTED_MODULE_8__.subDays(_shared_months__WEBPACK_IMPORTED_MODULE_8__.currentDay(), integer(10, 360)),
24654
24686
  category: category.id
24655
24687
  });
24656
24688
  }
@@ -24673,7 +24705,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
24673
24705
  const transactions = [];
24674
24706
  for (let i = 0; i < numTransactions; i++) {
24675
24707
  let payee;
24676
- if ((0, _random__WEBPACK_IMPORTED_MODULE_11__.random)() < 0.3) {
24708
+ if ((0, _random__WEBPACK_IMPORTED_MODULE_10__.random)() < 0.3) {
24677
24709
  payee = incomePayee;
24678
24710
  }
24679
24711
  else {
@@ -24685,7 +24717,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
24685
24717
  amount,
24686
24718
  payee: payee.id,
24687
24719
  account: account.id,
24688
- date: _shared_months__WEBPACK_IMPORTED_MODULE_9__.subDays(_shared_months__WEBPACK_IMPORTED_MODULE_9__.currentDay(), i * 5),
24720
+ date: _shared_months__WEBPACK_IMPORTED_MODULE_8__.subDays(_shared_months__WEBPACK_IMPORTED_MODULE_8__.currentDay(), i * 5),
24689
24721
  category: category.id
24690
24722
  });
24691
24723
  }
@@ -24712,7 +24744,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
24712
24744
  amount: integer(-3000, -3500) * 100 * 100,
24713
24745
  payee: payees.find((p) => p.name === 'Starting Balance').id,
24714
24746
  account: account.id,
24715
- date: _shared_months__WEBPACK_IMPORTED_MODULE_9__.subMonths(_shared_months__WEBPACK_IMPORTED_MODULE_9__.currentDay(), numTransactions) + '-02',
24747
+ date: _shared_months__WEBPACK_IMPORTED_MODULE_8__.subMonths(_shared_months__WEBPACK_IMPORTED_MODULE_8__.currentDay(), numTransactions) + '-02',
24716
24748
  category: getStartingBalanceCat(incomeGroup.categories),
24717
24749
  starting_balance_flag: true
24718
24750
  }
@@ -24723,7 +24755,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
24723
24755
  amount,
24724
24756
  payee: payee.id,
24725
24757
  account: account.id,
24726
- date: _shared_months__WEBPACK_IMPORTED_MODULE_9__.subMonths(_shared_months__WEBPACK_IMPORTED_MODULE_9__.currentDay(), i) + '-02',
24758
+ date: _shared_months__WEBPACK_IMPORTED_MODULE_8__.subMonths(_shared_months__WEBPACK_IMPORTED_MODULE_8__.currentDay(), i) + '-02',
24727
24759
  category: category.id,
24728
24760
  starting_balance_flag: true
24729
24761
  });
@@ -24742,7 +24774,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
24742
24774
  amount: integer(3250, 3700) * 100 * 100,
24743
24775
  payee: payees.find((p) => p.name === 'Starting Balance').id,
24744
24776
  account: account.id,
24745
- date: _shared_months__WEBPACK_IMPORTED_MODULE_9__.subMonths(_shared_months__WEBPACK_IMPORTED_MODULE_9__.currentDay(), numTransactions) + '-02',
24777
+ date: _shared_months__WEBPACK_IMPORTED_MODULE_8__.subMonths(_shared_months__WEBPACK_IMPORTED_MODULE_8__.currentDay(), numTransactions) + '-02',
24746
24778
  category: getStartingBalanceCat(incomeGroup.categories),
24747
24779
  starting_balance_flag: true
24748
24780
  }
@@ -24754,7 +24786,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
24754
24786
  amount,
24755
24787
  payee: payee.id,
24756
24788
  account: account.id,
24757
- date: _shared_months__WEBPACK_IMPORTED_MODULE_9__.subMonths(_shared_months__WEBPACK_IMPORTED_MODULE_9__.currentDay(), i) + '-02',
24789
+ date: _shared_months__WEBPACK_IMPORTED_MODULE_8__.subMonths(_shared_months__WEBPACK_IMPORTED_MODULE_8__.currentDay(), i) + '-02',
24758
24790
  category: category.id
24759
24791
  });
24760
24792
  }
@@ -24771,9 +24803,9 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
24771
24803
  WHERE a.id = ? AND a.offbudget = 0 AND t.is_child = 0 ORDER BY date ASC LIMIT 1`, [
24772
24804
  primaryAccount.id
24773
24805
  ])).date;
24774
- const start = _shared_months__WEBPACK_IMPORTED_MODULE_9__.monthFromDate(_server_db__WEBPACK_IMPORTED_MODULE_4__.fromDateRepr(earliestDate));
24775
- const end = _shared_months__WEBPACK_IMPORTED_MODULE_9__.currentMonth();
24776
- const months = _shared_months__WEBPACK_IMPORTED_MODULE_9__.rangeInclusive(start, end);
24806
+ const start = _shared_months__WEBPACK_IMPORTED_MODULE_8__.monthFromDate(_server_db__WEBPACK_IMPORTED_MODULE_4__.fromDateRepr(earliestDate));
24807
+ const end = _shared_months__WEBPACK_IMPORTED_MODULE_8__.currentMonth();
24808
+ const months = _shared_months__WEBPACK_IMPORTED_MODULE_8__.rangeInclusive(start, end);
24777
24809
  function category(name) {
24778
24810
  for (const group of groups) {
24779
24811
  const cat = group.categories.find((c) => c.name === name);
@@ -24790,14 +24822,14 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
24790
24822
  });
24791
24823
  }
24792
24824
  function setBudgetIfSpent(month, cat) {
24793
- const spent = _server_sheet__WEBPACK_IMPORTED_MODULE_7__.getCellValue(_shared_months__WEBPACK_IMPORTED_MODULE_9__.sheetForMonth(month), `sum-amount-${cat.id}`);
24825
+ const spent = _server_sheet__WEBPACK_IMPORTED_MODULE_6__.getCellValue(_shared_months__WEBPACK_IMPORTED_MODULE_8__.sheetForMonth(month), `sum-amount-${cat.id}`);
24794
24826
  if (spent < 0) {
24795
24827
  setBudget(month, cat, -spent);
24796
24828
  }
24797
24829
  }
24798
- await (0, _server_mutators__WEBPACK_IMPORTED_MODULE_5__.runMutator)(() => (0, _server_sync__WEBPACK_IMPORTED_MODULE_8__.batchMessages)(async () => {
24830
+ await (0, _server_mutators__WEBPACK_IMPORTED_MODULE_5__.runMutator)(() => (0, _server_sync__WEBPACK_IMPORTED_MODULE_7__.batchMessages)(async () => {
24799
24831
  for (const month of months) {
24800
- if (month >= _shared_months__WEBPACK_IMPORTED_MODULE_9__.monthFromDate(_server_db__WEBPACK_IMPORTED_MODULE_4__.fromDateRepr(earliestPrimaryDate))) {
24832
+ if (month >= _shared_months__WEBPACK_IMPORTED_MODULE_8__.monthFromDate(_server_db__WEBPACK_IMPORTED_MODULE_4__.fromDateRepr(earliestPrimaryDate))) {
24801
24833
  setBudget(month, category('Food'), 40000);
24802
24834
  setBudget(month, category('Restaurants'), 30000);
24803
24835
  setBudget(month, category('Entertainment'), 10000);
@@ -24827,13 +24859,13 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
24827
24859
  }
24828
24860
  }
24829
24861
  }));
24830
- await _server_sheet__WEBPACK_IMPORTED_MODULE_7__.waitOnSpreadsheet();
24831
- await (0, _server_mutators__WEBPACK_IMPORTED_MODULE_5__.runMutator)(() => (0, _server_sync__WEBPACK_IMPORTED_MODULE_8__.batchMessages)(async () => {
24862
+ await _server_sheet__WEBPACK_IMPORTED_MODULE_6__.waitOnSpreadsheet();
24863
+ await (0, _server_mutators__WEBPACK_IMPORTED_MODULE_5__.runMutator)(() => (0, _server_sync__WEBPACK_IMPORTED_MODULE_7__.batchMessages)(async () => {
24832
24864
  let prevSaved = 0;
24833
24865
  for (const month of months) {
24834
- if (month >= _shared_months__WEBPACK_IMPORTED_MODULE_9__.monthFromDate(_server_db__WEBPACK_IMPORTED_MODULE_4__.fromDateRepr(earliestPrimaryDate)) && month <= _shared_months__WEBPACK_IMPORTED_MODULE_9__.currentMonth()) {
24835
- const sheetName = _shared_months__WEBPACK_IMPORTED_MODULE_9__.sheetForMonth(month);
24836
- const toBudget = _server_sheet__WEBPACK_IMPORTED_MODULE_7__.getCellValue(sheetName, 'to-budget');
24866
+ if (month >= _shared_months__WEBPACK_IMPORTED_MODULE_8__.monthFromDate(_server_db__WEBPACK_IMPORTED_MODULE_4__.fromDateRepr(earliestPrimaryDate)) && month <= _shared_months__WEBPACK_IMPORTED_MODULE_8__.currentMonth()) {
24867
+ const sheetName = _shared_months__WEBPACK_IMPORTED_MODULE_8__.sheetForMonth(month);
24868
+ const toBudget = _server_sheet__WEBPACK_IMPORTED_MODULE_6__.getCellValue(sheetName, 'to-budget');
24837
24869
  const available = toBudget - prevSaved;
24838
24870
  if (available - 403000 > 0) {
24839
24871
  setBudget(month, category('Savings'), available - 403000);
@@ -24846,25 +24878,25 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
24846
24878
  }
24847
24879
  }
24848
24880
  }));
24849
- await _server_sheet__WEBPACK_IMPORTED_MODULE_7__.waitOnSpreadsheet();
24850
- const sheetName = _shared_months__WEBPACK_IMPORTED_MODULE_9__.sheetForMonth(_shared_months__WEBPACK_IMPORTED_MODULE_9__.currentMonth());
24851
- const toBudget = _server_sheet__WEBPACK_IMPORTED_MODULE_7__.getCellValue(sheetName, 'to-budget');
24881
+ await _server_sheet__WEBPACK_IMPORTED_MODULE_6__.waitOnSpreadsheet();
24882
+ const sheetName = _shared_months__WEBPACK_IMPORTED_MODULE_8__.sheetForMonth(_shared_months__WEBPACK_IMPORTED_MODULE_8__.currentMonth());
24883
+ const toBudget = _server_sheet__WEBPACK_IMPORTED_MODULE_6__.getCellValue(sheetName, 'to-budget');
24852
24884
  if (toBudget < 0) {
24853
24885
  await (0, _server_accounts_sync__WEBPACK_IMPORTED_MODULE_0__.addTransactions)(primaryAccount.id, [
24854
24886
  {
24855
24887
  amount: -toBudget,
24856
24888
  category: category('Income').id,
24857
- date: _shared_months__WEBPACK_IMPORTED_MODULE_9__.currentMonth() + '-01'
24889
+ date: _shared_months__WEBPACK_IMPORTED_MODULE_8__.currentMonth() + '-01'
24858
24890
  }
24859
24891
  ]);
24860
24892
  }
24861
24893
  // let sheetName = monthUtils.sheetForMonth(monthUtils.currentMonth());
24862
24894
  // let toBudget = sheet.getCellValue(sheetName, 'to-budget');
24863
24895
  // setBudget(monthUtils.currentMonth(), category('Savings'), toBudget);
24864
- await _server_sheet__WEBPACK_IMPORTED_MODULE_7__.waitOnSpreadsheet();
24896
+ await _server_sheet__WEBPACK_IMPORTED_MODULE_6__.waitOnSpreadsheet();
24865
24897
  }
24866
24898
  async function createTestBudget(handlers) {
24867
- (0, _server_sync__WEBPACK_IMPORTED_MODULE_8__.setSyncingMode)('import');
24899
+ (0, _server_sync__WEBPACK_IMPORTED_MODULE_7__.setSyncingMode)('import');
24868
24900
  await _server_db__WEBPACK_IMPORTED_MODULE_4__.execQuery('PRAGMA journal_mode = OFF');
24869
24901
  // Clear out the default categories. This is fine to do without
24870
24902
  // going through the sync system because we are in import mode and
@@ -24949,7 +24981,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
24949
24981
  bill: true
24950
24982
  }
24951
24983
  ];
24952
- await (0, _server_mutators__WEBPACK_IMPORTED_MODULE_5__.runMutator)(() => (0, _server_sync__WEBPACK_IMPORTED_MODULE_8__.batchMessages)(async () => {
24984
+ await (0, _server_mutators__WEBPACK_IMPORTED_MODULE_5__.runMutator)(() => (0, _server_sync__WEBPACK_IMPORTED_MODULE_7__.batchMessages)(async () => {
24953
24985
  for (const payee of payees) {
24954
24986
  payee.id = await handlers['payee-create']({
24955
24987
  name: payee.name
@@ -25041,8 +25073,8 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
25041
25073
  }
25042
25074
  });
25043
25075
  const allGroups = (await (0, _server_mutators__WEBPACK_IMPORTED_MODULE_5__.runHandler)(handlers['get-categories'])).grouped;
25044
- (0, _server_sync__WEBPACK_IMPORTED_MODULE_8__.setSyncingMode)('import');
25045
- await (0, _server_mutators__WEBPACK_IMPORTED_MODULE_5__.runMutator)(() => (0, _server_sync__WEBPACK_IMPORTED_MODULE_8__.batchMessages)(async () => {
25076
+ (0, _server_sync__WEBPACK_IMPORTED_MODULE_7__.setSyncingMode)('import');
25077
+ await (0, _server_mutators__WEBPACK_IMPORTED_MODULE_5__.runMutator)(() => (0, _server_sync__WEBPACK_IMPORTED_MODULE_7__.batchMessages)(async () => {
25046
25078
  for (const account of accounts) {
25047
25079
  if (account.name === 'Bank of America') {
25048
25080
  await fillPrimaryChecking(handlers, account, payees, allGroups);
@@ -25068,19 +25100,19 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
25068
25100
  }
25069
25101
  }
25070
25102
  }));
25071
- (0, _server_sync__WEBPACK_IMPORTED_MODULE_8__.setSyncingMode)('import');
25103
+ (0, _server_sync__WEBPACK_IMPORTED_MODULE_7__.setSyncingMode)('import');
25072
25104
  // This checks to see if the primary account is in the negative.
25073
25105
  // This might happen depending on the transactions added, but we
25074
25106
  // don't want to show that as it'd be weird. We modify the latest
25075
25107
  // deposit transaction to force it to be positive
25076
25108
  const primaryAccount = accounts.find((a) => a.name = 'Bank of America');
25077
- const { data: primaryBalance } = await (0, _server_aql__WEBPACK_IMPORTED_MODULE_1__.runQuery)((0, _shared_query__WEBPACK_IMPORTED_MODULE_10__.q)('transactions').filter({
25109
+ const { data: primaryBalance } = await (0, _server_aql__WEBPACK_IMPORTED_MODULE_1__.runQuery)((0, _shared_query__WEBPACK_IMPORTED_MODULE_9__.q)('transactions').filter({
25078
25110
  account: primaryAccount.id
25079
25111
  }).calculate({
25080
25112
  $sum: '$amount'
25081
25113
  }).serialize());
25082
25114
  if (primaryBalance < 0) {
25083
- const { data: results } = await (0, _server_aql__WEBPACK_IMPORTED_MODULE_1__.runQuery)((0, _shared_query__WEBPACK_IMPORTED_MODULE_10__.q)('transactions').filter({
25115
+ const { data: results } = await (0, _server_aql__WEBPACK_IMPORTED_MODULE_1__.runQuery)((0, _shared_query__WEBPACK_IMPORTED_MODULE_9__.q)('transactions').filter({
25084
25116
  account: primaryAccount.id,
25085
25117
  amount: {
25086
25118
  $gt: 0
@@ -25096,15 +25128,12 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
25096
25128
  });
25097
25129
  }
25098
25130
  // Bust the cache and reload the spreadsheet
25099
- (0, _server_sync__WEBPACK_IMPORTED_MODULE_8__.setSyncingMode)('disabled');
25100
- await _server_prefs__WEBPACK_IMPORTED_MODULE_6__.savePrefs({
25101
- isCached: false
25102
- });
25103
- await _server_sheet__WEBPACK_IMPORTED_MODULE_7__.reloadSpreadsheet(_server_db__WEBPACK_IMPORTED_MODULE_4__);
25131
+ (0, _server_sync__WEBPACK_IMPORTED_MODULE_7__.setSyncingMode)('disabled');
25132
+ await _server_sheet__WEBPACK_IMPORTED_MODULE_6__.reloadSpreadsheet(_server_db__WEBPACK_IMPORTED_MODULE_4__);
25104
25133
  await _server_budget_base__WEBPACK_IMPORTED_MODULE_3__.createAllBudgets();
25105
- await _server_sheet__WEBPACK_IMPORTED_MODULE_7__.waitOnSpreadsheet();
25134
+ await _server_sheet__WEBPACK_IMPORTED_MODULE_6__.waitOnSpreadsheet();
25106
25135
  // Create some schedules
25107
- await (0, _server_mutators__WEBPACK_IMPORTED_MODULE_5__.runMutator)(() => (0, _server_sync__WEBPACK_IMPORTED_MODULE_8__.batchMessages)(async () => {
25136
+ await (0, _server_mutators__WEBPACK_IMPORTED_MODULE_5__.runMutator)(() => (0, _server_sync__WEBPACK_IMPORTED_MODULE_7__.batchMessages)(async () => {
25108
25137
  const account = accounts.find((acc) => acc.name === 'Bank of America');
25109
25138
  await (0, _server_mutators__WEBPACK_IMPORTED_MODULE_5__.runHandler)(handlers['schedule/create'], {
25110
25139
  schedule: {
@@ -25126,7 +25155,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
25126
25155
  op: 'is',
25127
25156
  field: 'date',
25128
25157
  value: {
25129
- start: _shared_months__WEBPACK_IMPORTED_MODULE_9__.currentDay(),
25158
+ start: _shared_months__WEBPACK_IMPORTED_MODULE_8__.currentDay(),
25130
25159
  frequency: 'monthly',
25131
25160
  patterns: [],
25132
25161
  skipWeekend: false,
@@ -25159,7 +25188,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
25159
25188
  {
25160
25189
  op: 'is',
25161
25190
  field: 'date',
25162
- value: _shared_months__WEBPACK_IMPORTED_MODULE_9__.subDays(_shared_months__WEBPACK_IMPORTED_MODULE_9__.currentDay(), 1)
25191
+ value: _shared_months__WEBPACK_IMPORTED_MODULE_8__.subDays(_shared_months__WEBPACK_IMPORTED_MODULE_8__.currentDay(), 1)
25163
25192
  },
25164
25193
  {
25165
25194
  op: 'isapprox',
@@ -25178,7 +25207,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
25178
25207
  op: 'is',
25179
25208
  field: 'date',
25180
25209
  value: {
25181
- start: _shared_months__WEBPACK_IMPORTED_MODULE_9__.subDays(_shared_months__WEBPACK_IMPORTED_MODULE_9__.currentDay(), 3),
25210
+ start: _shared_months__WEBPACK_IMPORTED_MODULE_8__.subDays(_shared_months__WEBPACK_IMPORTED_MODULE_8__.currentDay(), 3),
25182
25211
  frequency: 'monthly',
25183
25212
  patterns: [],
25184
25213
  skipWeekend: false,
@@ -25207,7 +25236,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
25207
25236
  op: 'is',
25208
25237
  field: 'date',
25209
25238
  value: {
25210
- start: _shared_months__WEBPACK_IMPORTED_MODULE_9__.addDays(_shared_months__WEBPACK_IMPORTED_MODULE_9__.currentDay(), 1),
25239
+ start: _shared_months__WEBPACK_IMPORTED_MODULE_8__.addDays(_shared_months__WEBPACK_IMPORTED_MODULE_8__.currentDay(), 1),
25211
25240
  frequency: 'monthly',
25212
25241
  patterns: [],
25213
25242
  skipWeekend: false,
@@ -25661,8 +25690,10 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
25661
25690
  });
25662
25691
  /* harmony import */ var better_sqlite3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! better-sqlite3 */ "better-sqlite3");
25663
25692
  /* harmony import */ var better_sqlite3__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/ __webpack_require__.n(better_sqlite3__WEBPACK_IMPORTED_MODULE_0__);
25664
- /* harmony import */ var uuid__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! uuid */ "./node_modules/uuid/dist/esm-node/v4.js");
25693
+ /* harmony import */ var uuid__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! uuid */ "./node_modules/uuid/dist/esm-node/v4.js");
25665
25694
  /* harmony import */ var _fs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../fs */ "./packages/loot-core/src/platform/server/fs/index.electron.ts");
25695
+ /* harmony import */ var _normalise__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./normalise */ "./packages/loot-core/src/platform/server/sqlite/normalise.ts");
25696
+ /* harmony import */ var _unicodeLike__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./unicodeLike */ "./packages/loot-core/src/platform/server/sqlite/unicodeLike.ts");
25666
25697
  // @ts-strict-ignore
25667
25698
  function verifyParamTypes(sql, arr) {
25668
25699
  arr.forEach((val) => {
@@ -25750,7 +25781,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
25750
25781
  }
25751
25782
  function openDatabase(pathOrBuffer) {
25752
25783
  const db = new (better_sqlite3__WEBPACK_IMPORTED_MODULE_0___default())(pathOrBuffer);
25753
- // Define Unicode-aware LOWER and UPPER implementation.
25784
+ // Define Unicode-aware LOWER, UPPER, and LIKE implementation.
25754
25785
  // This is necessary because better-sqlite3 uses SQLite build without ICU support.
25755
25786
  // @ts-expect-error @types/better-sqlite3 does not support setting strict 3rd argument
25756
25787
  db.function('UNICODE_LOWER', {
@@ -25761,9 +25792,17 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
25761
25792
  deterministic: true
25762
25793
  }, (arg) => arg?.toUpperCase());
25763
25794
  // @ts-expect-error @types/better-sqlite3 does not support setting strict 3rd argument
25795
+ db.function('UNICODE_LIKE', {
25796
+ deterministic: true
25797
+ }, _unicodeLike__WEBPACK_IMPORTED_MODULE_3__.unicodeLike);
25798
+ // @ts-expect-error @types/better-sqlite3 does not support setting strict 3rd argument
25764
25799
  db.function('REGEXP', {
25765
25800
  deterministic: true
25766
25801
  }, regexp);
25802
+ // @ts-expect-error @types/better-sqlite3 does not support setting strict 3rd argument
25803
+ db.function('NORMALISE', {
25804
+ deterministic: true
25805
+ }, _normalise__WEBPACK_IMPORTED_MODULE_2__.normalise);
25767
25806
  return db;
25768
25807
  }
25769
25808
  function closeDatabase(db) {
@@ -25772,7 +25811,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
25772
25811
  async function exportDatabase(db) {
25773
25812
  // electron does not support better-sqlite serialize since v21
25774
25813
  // save to file and read in the raw data.
25775
- const name = `backup-for-export-${(0, uuid__WEBPACK_IMPORTED_MODULE_2__["default"])()}.db`;
25814
+ const name = `backup-for-export-${(0, uuid__WEBPACK_IMPORTED_MODULE_4__["default"])()}.db`;
25776
25815
  await db.backup(name);
25777
25816
  const data = await (0, _fs__WEBPACK_IMPORTED_MODULE_1__.readFile)(name, 'binary');
25778
25817
  await (0, _fs__WEBPACK_IMPORTED_MODULE_1__.removeFile)(name);
@@ -25780,6 +25819,63 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
25780
25819
  }
25781
25820
  /***/
25782
25821
  }),
25822
+ /***/ "./packages/loot-core/src/platform/server/sqlite/normalise.ts":
25823
+ /*!********************************************************************!*\
25824
+ !*** ./packages/loot-core/src/platform/server/sqlite/normalise.ts ***!
25825
+ \********************************************************************/
25826
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
25827
+ "use strict";
25828
+ __webpack_require__.r(__webpack_exports__);
25829
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
25830
+ /* harmony export */ normalise: () => ( /* binding */normalise)
25831
+ /* harmony export */
25832
+ });
25833
+ /* harmony import */ var _shared_normalisation__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../shared/normalisation */ "./packages/loot-core/src/shared/normalisation.ts");
25834
+ function normalise(value) {
25835
+ if (!value) {
25836
+ return null;
25837
+ }
25838
+ return (0, _shared_normalisation__WEBPACK_IMPORTED_MODULE_0__.getNormalisedString)(value);
25839
+ }
25840
+ /***/
25841
+ }),
25842
+ /***/ "./packages/loot-core/src/platform/server/sqlite/unicodeLike.ts":
25843
+ /*!**********************************************************************!*\
25844
+ !*** ./packages/loot-core/src/platform/server/sqlite/unicodeLike.ts ***!
25845
+ \**********************************************************************/
25846
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
25847
+ "use strict";
25848
+ __webpack_require__.r(__webpack_exports__);
25849
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
25850
+ /* harmony export */ unicodeLike: () => ( /* binding */unicodeLike)
25851
+ /* harmony export */
25852
+ });
25853
+ /* harmony import */ var lru_cache__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lru-cache */ "./node_modules/lru-cache/index.js");
25854
+ /* harmony import */ var lru_cache__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/ __webpack_require__.n(lru_cache__WEBPACK_IMPORTED_MODULE_0__);
25855
+ // @ts-strict-ignore
25856
+ const likePatternCache = new (lru_cache__WEBPACK_IMPORTED_MODULE_0___default())({
25857
+ max: 500
25858
+ });
25859
+ function unicodeLike(pattern, value) {
25860
+ if (!pattern) {
25861
+ return 0;
25862
+ }
25863
+ if (!value) {
25864
+ value = '';
25865
+ }
25866
+ let cachedRegExp = likePatternCache.get(pattern);
25867
+ if (!cachedRegExp) {
25868
+ // we don't escape ? and % because we don't know
25869
+ // whether they originate from the user input or from our query compiler.
25870
+ // Maybe improve the query compiler to correctly process these characters?
25871
+ const processedPattern = pattern.replace(/[.*+^${}()|[\]\\]/g, '\\$&').replaceAll('?', '.').replaceAll('%', '.*');
25872
+ cachedRegExp = new RegExp(processedPattern, 'i');
25873
+ likePatternCache.set(pattern, cachedRegExp);
25874
+ }
25875
+ return cachedRegExp.test(value) ? 1 : 0;
25876
+ }
25877
+ /***/
25878
+ }),
25783
25879
  /***/ "./packages/loot-core/src/server/accounts/export-to-csv.ts":
25784
25880
  /*!*****************************************************************!*\
25785
25881
  !*** ./packages/loot-core/src/server/accounts/export-to-csv.ts ***!
@@ -25844,6 +25940,12 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
25844
25940
  {
25845
25941
  IsParent: 'is_parent'
25846
25942
  },
25943
+ {
25944
+ IsChild: 'is_child'
25945
+ },
25946
+ {
25947
+ SortOrder: 'sort_order'
25948
+ },
25847
25949
  {
25848
25950
  Notes: 'notes'
25849
25951
  },
@@ -25862,23 +25964,28 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
25862
25964
  ]).options({
25863
25965
  splits: 'all'
25864
25966
  }));
25865
- const parentsPayees = new Map();
25967
+ // initialize a map to allow splits to have correct number of split from
25968
+ const parentsChildCount = new Map();
25969
+ const childSplitOrder = new Map();
25970
+ // find children, their order, and total # siblings
25866
25971
  for (const trans of transactions) {
25867
- if (trans.IsParent) {
25868
- parentsPayees.set(trans.Id, trans.Payee);
25972
+ if (trans.IsChild) {
25973
+ let childNumber = parentsChildCount.get(trans.ParentId) || 0;
25974
+ childNumber++;
25975
+ childSplitOrder.set(trans.Id, childNumber);
25976
+ parentsChildCount.set(trans.ParentId, childNumber);
25869
25977
  }
25870
25978
  }
25871
- // filter out any parent transactions
25872
- const noParents = transactions.filter((t) => !t.IsParent);
25873
- // map final properties for export and grab the payee for splits from their parent transaction
25874
- const transactionsForExport = noParents.map((trans) => {
25979
+ // map final properties for export and grab the child count for splits from their parent transaction
25980
+ const transactionsForExport = transactions.map((trans) => {
25875
25981
  return {
25876
25982
  Account: trans.Account,
25877
25983
  Date: trans.Date,
25878
- Payee: trans.ParentId ? parentsPayees.get(trans.ParentId) : trans.Payee,
25879
- Notes: trans.Notes,
25984
+ Payee: trans.Payee,
25985
+ Notes: trans.IsParent ? '(SPLIT INTO ' + parentsChildCount.get(trans.Id) + ') ' + (trans.Notes || '') : trans.IsChild ? '(SPLIT ' + childSplitOrder.get(trans.Id) + ' OF ' + parentsChildCount.get(trans.ParentId) + ') ' + (trans.Notes || '') : trans.Notes,
25880
25986
  Category: trans.Category,
25881
- Amount: trans.Amount == null ? 0 : (0, _shared_util__WEBPACK_IMPORTED_MODULE_1__.integerToAmount)(trans.Amount),
25987
+ Amount: trans.IsParent ? 0 : trans.Amount == null ? 0 : (0, _shared_util__WEBPACK_IMPORTED_MODULE_1__.integerToAmount)(trans.Amount),
25988
+ Split_Amount: trans.IsParent ? (0, _shared_util__WEBPACK_IMPORTED_MODULE_1__.integerToAmount)(trans.Amount) : 0,
25882
25989
  Cleared: trans.Reconciled === true ? 'Reconciled' : trans.Cleared === true ? 'Cleared' : 'Not cleared'
25883
25990
  };
25884
25991
  });
@@ -26759,6 +26866,9 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
26759
26866
  this.field = null;
26760
26867
  this.type = 'id';
26761
26868
  }
26869
+ if (field === 'account') {
26870
+ assert(value, 'no-null', `Field cannot be empty: ${field}`);
26871
+ }
26762
26872
  this.op = op;
26763
26873
  this.rawValue = value;
26764
26874
  this.value = value;
@@ -27196,6 +27306,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
27196
27306
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
27197
27307
  /* harmony export */ addTransactions: () => ( /* binding */addTransactions),
27198
27308
  /* harmony export */ getGoCardlessAccounts: () => ( /* binding */getGoCardlessAccounts),
27309
+ /* harmony export */ matchTransactions: () => ( /* binding */matchTransactions),
27199
27310
  /* harmony export */ reconcileTransactions: () => ( /* binding */reconcileTransactions),
27200
27311
  /* harmony export */ syncAccount: () => ( /* binding */syncAccount)
27201
27312
  /* harmony export */
@@ -27398,33 +27509,10 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
27398
27509
  if (trans.date == null) {
27399
27510
  throw new Error('`date` is required when adding a transaction');
27400
27511
  }
27401
- let payee_name;
27402
- // When the amount is equal to 0, we need to determine
27403
- // if this is a "Credited" or "Debited" transaction. This means
27404
- // that it matters whether the amount is a positive or negative zero.
27405
- if (trans.amount > 0 || Object.is(Number(trans.amount), 0)) {
27406
- const nameParts = [];
27407
- const name = trans.debtorName || trans.remittanceInformationUnstructured || (trans.remittanceInformationUnstructuredArray || []).join(', ') || trans.additionalInformation;
27408
- if (name) {
27409
- nameParts.push((0, _title__WEBPACK_IMPORTED_MODULE_10__.title)(name));
27410
- }
27411
- if (trans.debtorAccount && trans.debtorAccount.iban) {
27412
- nameParts.push('(' + trans.debtorAccount.iban.slice(0, 4) + ' XXX ' + trans.debtorAccount.iban.slice(-4) + ')');
27413
- }
27414
- payee_name = nameParts.join(' ');
27415
- }
27416
- else {
27417
- const nameParts = [];
27418
- const name = trans.creditorName || trans.remittanceInformationUnstructured || (trans.remittanceInformationUnstructuredArray || []).join(', ') || trans.additionalInformation;
27419
- if (name) {
27420
- nameParts.push((0, _title__WEBPACK_IMPORTED_MODULE_10__.title)(name));
27421
- }
27422
- if (trans.creditorAccount && trans.creditorAccount.iban) {
27423
- nameParts.push('(' + trans.creditorAccount.iban.slice(0, 4) + ' XXX ' + trans.creditorAccount.iban.slice(-4) + ')');
27424
- }
27425
- payee_name = nameParts.join(' ');
27512
+ if (trans.payeeName == null) {
27513
+ throw new Error('`payeeName` is required when adding a transaction');
27426
27514
  }
27427
- trans.imported_payee = trans.imported_payee || payee_name;
27515
+ trans.imported_payee = trans.imported_payee || trans.payeeName;
27428
27516
  if (trans.imported_payee) {
27429
27517
  trans.imported_payee = trans.imported_payee.trim();
27430
27518
  }
@@ -27432,10 +27520,10 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
27432
27520
  // when rules are run, they have the right data. Resolving payees
27433
27521
  // also simplifies the payee creation process
27434
27522
  trans.account = acctId;
27435
- trans.payee = await resolvePayee(trans, payee_name, payeesToCreate);
27523
+ trans.payee = await resolvePayee(trans, trans.payeeName, payeesToCreate);
27436
27524
  trans.cleared = Boolean(trans.booked);
27437
27525
  normalized.push({
27438
- payee_name,
27526
+ payee_name: trans.payeeName,
27439
27527
  trans: {
27440
27528
  amount: (0, _shared_util__WEBPACK_IMPORTED_MODULE_3__.amountToInteger)(trans.amount),
27441
27529
  payee: trans.payee,
@@ -27464,11 +27552,117 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
27464
27552
  }
27465
27553
  });
27466
27554
  }
27467
- async function reconcileTransactions(acctId, transactions, isBankSyncAccount = false) {
27555
+ async function reconcileTransactions(acctId, transactions, isBankSyncAccount = false, isPreview = false) {
27468
27556
  console.log('Performing transaction reconciliation');
27469
- const hasMatched = new Set();
27470
27557
  const updated = [];
27471
27558
  const added = [];
27559
+ const updatedPreview = [];
27560
+ const existingPayeeMap = new Map();
27561
+ const { payeesToCreate, transactionsStep1, transactionsStep2, transactionsStep3 } = await matchTransactions(acctId, transactions, isBankSyncAccount);
27562
+ // Finally, generate & commit the changes
27563
+ for (const { trans, subtransactions, match } of transactionsStep3) {
27564
+ if (match && !trans.forceAddTransaction) {
27565
+ // Skip updating already reconciled (locked) transactions
27566
+ if (match.reconciled) {
27567
+ updatedPreview.push({
27568
+ transaction: trans,
27569
+ ignored: true
27570
+ });
27571
+ continue;
27572
+ }
27573
+ // TODO: change the above sql query to use aql
27574
+ const existing = {
27575
+ ...match,
27576
+ cleared: match.cleared === 1,
27577
+ date: _db__WEBPACK_IMPORTED_MODULE_4__.fromDateRepr(match.date)
27578
+ };
27579
+ // Update the transaction
27580
+ const updates = {
27581
+ imported_id: trans.imported_id || null,
27582
+ payee: existing.payee || trans.payee || null,
27583
+ category: existing.category || trans.category || null,
27584
+ imported_payee: trans.imported_payee || null,
27585
+ notes: existing.notes || trans.notes || null,
27586
+ cleared: trans.cleared != null ? trans.cleared : true
27587
+ };
27588
+ if ((0, _shared_util__WEBPACK_IMPORTED_MODULE_3__.hasFieldsChanged)(existing, updates, Object.keys(updates))) {
27589
+ updated.push({
27590
+ id: existing.id,
27591
+ ...updates
27592
+ });
27593
+ if (!existingPayeeMap.has(existing.payee)) {
27594
+ const payee = await _db__WEBPACK_IMPORTED_MODULE_4__.getPayee(existing.payee);
27595
+ existingPayeeMap.set(existing.payee, payee?.name);
27596
+ }
27597
+ existing.payee_name = existingPayeeMap.get(existing.payee);
27598
+ existing.amount = (0, _shared_util__WEBPACK_IMPORTED_MODULE_3__.integerToAmount)(existing.amount);
27599
+ updatedPreview.push({
27600
+ transaction: trans,
27601
+ existing
27602
+ });
27603
+ }
27604
+ else {
27605
+ updatedPreview.push({
27606
+ transaction: trans,
27607
+ ignored: true
27608
+ });
27609
+ }
27610
+ if (existing.is_parent && existing.cleared !== updates.cleared) {
27611
+ const children = await _db__WEBPACK_IMPORTED_MODULE_4__.all('SELECT id FROM v_transactions WHERE parent_id = ?', [
27612
+ existing.id
27613
+ ]);
27614
+ for (const child of children) {
27615
+ updated.push({
27616
+ id: child.id,
27617
+ cleared: updates.cleared
27618
+ });
27619
+ }
27620
+ }
27621
+ }
27622
+ else {
27623
+ // Insert a new transaction
27624
+ const { forceAddTransaction, ...newTrans } = trans;
27625
+ const finalTransaction = {
27626
+ ...newTrans,
27627
+ id: (0, uuid__WEBPACK_IMPORTED_MODULE_13__["default"])(),
27628
+ category: trans.category || null,
27629
+ cleared: trans.cleared != null ? trans.cleared : true
27630
+ };
27631
+ if (subtransactions && subtransactions.length > 0) {
27632
+ added.push(...makeSplitTransaction(finalTransaction, subtransactions));
27633
+ }
27634
+ else {
27635
+ added.push(finalTransaction);
27636
+ }
27637
+ }
27638
+ }
27639
+ if (!isPreview) {
27640
+ await createNewPayees(payeesToCreate, [
27641
+ ...added,
27642
+ ...updated
27643
+ ]);
27644
+ await (0, _transactions__WEBPACK_IMPORTED_MODULE_12__.batchUpdateTransactions)({
27645
+ added,
27646
+ updated
27647
+ });
27648
+ }
27649
+ console.log('Debug data for the operations:', {
27650
+ transactionsStep1,
27651
+ transactionsStep2,
27652
+ transactionsStep3,
27653
+ added,
27654
+ updated,
27655
+ updatedPreview
27656
+ });
27657
+ return {
27658
+ added: added.map((trans) => trans.id),
27659
+ updated: updated.map((trans) => trans.id),
27660
+ updatedPreview
27661
+ };
27662
+ }
27663
+ async function matchTransactions(acctId, transactions, isBankSyncAccount = false) {
27664
+ console.log('Performing transaction reconciliation matching');
27665
+ const hasMatched = new Set();
27472
27666
  const transactionNormalization = isBankSyncAccount ? normalizeBankSyncTransactions : normalizeTransactions;
27473
27667
  const { normalized, payeesToCreate } = await transactionNormalization(transactions, acctId);
27474
27668
  // The first pass runs the rules, and preps data for fuzzy matching
@@ -27496,7 +27690,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
27496
27690
  // needs to select all fields that need to be read from the
27497
27691
  // matched transaction. See the final pass below for the needed
27498
27692
  // fields.
27499
- fuzzyDataset = await _db__WEBPACK_IMPORTED_MODULE_4__.all(`SELECT id, is_parent, date, imported_id, payee, category, notes, reconciled FROM v_transactions
27693
+ fuzzyDataset = await _db__WEBPACK_IMPORTED_MODULE_4__.all(`SELECT id, is_parent, date, imported_id, payee, imported_payee, category, notes, reconciled, cleared, amount FROM v_transactions
27500
27694
  WHERE date >= ? AND date <= ? AND amount = ? AND account = ?`, [
27501
27695
  _db__WEBPACK_IMPORTED_MODULE_4__.toDateRepr(_shared_months__WEBPACK_IMPORTED_MODULE_1__.subDays(trans.date, 7)),
27502
27696
  _db__WEBPACK_IMPORTED_MODULE_4__.toDateRepr(_shared_months__WEBPACK_IMPORTED_MODULE_1__.addDays(trans.date, 7)),
@@ -27557,80 +27751,11 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
27557
27751
  }
27558
27752
  return data;
27559
27753
  });
27560
- // Finally, generate & commit the changes
27561
- for (const { trans, subtransactions, match } of transactionsStep3) {
27562
- if (match) {
27563
- // Skip updating already reconciled (locked) transactions
27564
- if (match.reconciled) {
27565
- continue;
27566
- }
27567
- // TODO: change the above sql query to use aql
27568
- const existing = {
27569
- ...match,
27570
- cleared: match.cleared === 1,
27571
- date: _db__WEBPACK_IMPORTED_MODULE_4__.fromDateRepr(match.date)
27572
- };
27573
- // Update the transaction
27574
- const updates = {
27575
- imported_id: trans.imported_id || null,
27576
- payee: existing.payee || trans.payee || null,
27577
- category: existing.category || trans.category || null,
27578
- imported_payee: trans.imported_payee || null,
27579
- notes: existing.notes || trans.notes || null,
27580
- cleared: trans.cleared != null ? trans.cleared : true
27581
- };
27582
- if ((0, _shared_util__WEBPACK_IMPORTED_MODULE_3__.hasFieldsChanged)(existing, updates, Object.keys(updates))) {
27583
- updated.push({
27584
- id: existing.id,
27585
- ...updates
27586
- });
27587
- }
27588
- if (existing.is_parent && existing.cleared !== updates.cleared) {
27589
- const children = await _db__WEBPACK_IMPORTED_MODULE_4__.all('SELECT id FROM v_transactions WHERE parent_id = ?', [
27590
- existing.id
27591
- ]);
27592
- for (const child of children) {
27593
- updated.push({
27594
- id: child.id,
27595
- cleared: updates.cleared
27596
- });
27597
- }
27598
- }
27599
- }
27600
- else {
27601
- // Insert a new transaction
27602
- const finalTransaction = {
27603
- ...trans,
27604
- id: (0, uuid__WEBPACK_IMPORTED_MODULE_13__["default"])(),
27605
- category: trans.category || null,
27606
- cleared: trans.cleared != null ? trans.cleared : true
27607
- };
27608
- if (subtransactions && subtransactions.length > 0) {
27609
- added.push(...makeSplitTransaction(finalTransaction, subtransactions));
27610
- }
27611
- else {
27612
- added.push(finalTransaction);
27613
- }
27614
- }
27615
- }
27616
- await createNewPayees(payeesToCreate, [
27617
- ...added,
27618
- ...updated
27619
- ]);
27620
- await (0, _transactions__WEBPACK_IMPORTED_MODULE_12__.batchUpdateTransactions)({
27621
- added,
27622
- updated
27623
- });
27624
- console.log('Debug data for the operations:', {
27754
+ return {
27755
+ payeesToCreate,
27625
27756
  transactionsStep1,
27626
27757
  transactionsStep2,
27627
- transactionsStep3,
27628
- added,
27629
- updated
27630
- });
27631
- return {
27632
- added: added.map((trans) => trans.id),
27633
- updated: updated.map((trans) => trans.id)
27758
+ transactionsStep3
27634
27759
  };
27635
27760
  }
27636
27761
  // This is similar to `reconcileTransactions` except much simpler: it
@@ -28985,6 +29110,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
28985
29110
  date: transaction.date,
28986
29111
  transfer_id: transaction.id,
28987
29112
  notes: transaction.notes || null,
29113
+ schedule: transaction.schedule,
28988
29114
  cleared: false
28989
29115
  });
28990
29116
  await _db__WEBPACK_IMPORTED_MODULE_0__.updateTransaction({
@@ -29042,7 +29168,8 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
29042
29168
  payee: payee.id,
29043
29169
  date: transaction.date,
29044
29170
  notes: transaction.notes,
29045
- amount: -transaction.amount
29171
+ amount: -transaction.amount,
29172
+ schedule: transaction.schedule
29046
29173
  });
29047
29174
  const categoryCleared = await clearCategory(transaction, transferredAccount);
29048
29175
  if (categoryCleared) {
@@ -29133,6 +29260,9 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
29133
29260
  return isNaN(number) ? null : number;
29134
29261
  }
29135
29262
  function getDtOrDtTm(Date) {
29263
+ if (!Date) {
29264
+ return null;
29265
+ }
29136
29266
  if ('DtTm' in Date) {
29137
29267
  return Date.DtTm.slice(0, 10);
29138
29268
  }
@@ -29211,9 +29341,11 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
29211
29341
  __webpack_require__.r(__webpack_exports__);
29212
29342
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
29213
29343
  /* harmony export */ accountModel: () => ( /* binding */accountModel),
29344
+ /* harmony export */ budgetModel: () => ( /* binding */budgetModel),
29214
29345
  /* harmony export */ categoryGroupModel: () => ( /* binding */categoryGroupModel),
29215
29346
  /* harmony export */ categoryModel: () => ( /* binding */categoryModel),
29216
- /* harmony export */ payeeModel: () => ( /* binding */payeeModel)
29347
+ /* harmony export */ payeeModel: () => ( /* binding */payeeModel),
29348
+ /* harmony export */ remoteFileModel: () => ( /* binding */remoteFileModel)
29217
29349
  /* harmony export */
29218
29350
  });
29219
29351
  /* harmony import */ var _models__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./models */ "./packages/loot-core/src/server/models.ts");
@@ -29294,6 +29426,36 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
29294
29426
  return payee;
29295
29427
  }
29296
29428
  };
29429
+ const remoteFileModel = {
29430
+ toExternal(file) {
29431
+ if (file.deleted) {
29432
+ return null;
29433
+ }
29434
+ return {
29435
+ cloudFileId: file.fileId,
29436
+ state: 'remote',
29437
+ groupId: file.groupId,
29438
+ name: file.name,
29439
+ encryptKeyId: file.encryptKeyId,
29440
+ hasKey: file.hasKey
29441
+ };
29442
+ },
29443
+ fromExternal(file) {
29444
+ return {
29445
+ deleted: false,
29446
+ fileId: file.cloudFileId,
29447
+ ...file
29448
+ };
29449
+ }
29450
+ };
29451
+ const budgetModel = {
29452
+ toExternal(file) {
29453
+ return file;
29454
+ },
29455
+ fromExternal(file) {
29456
+ return file;
29457
+ }
29458
+ };
29297
29459
  /***/
29298
29460
  }),
29299
29461
  /***/ "./packages/loot-core/src/server/api.ts":
@@ -29493,6 +29655,14 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
29493
29655
  id: result.id
29494
29656
  });
29495
29657
  };
29658
+ handlers['api/get-budgets'] = async function () {
29659
+ const budgets = await handlers['get-budgets']();
29660
+ const files = await handlers['get-remote-files']() || [];
29661
+ return [
29662
+ ...budgets.map((file) => _api_models__WEBPACK_IMPORTED_MODULE_8__.budgetModel.toExternal(file)),
29663
+ ...files.map((file) => _api_models__WEBPACK_IMPORTED_MODULE_8__.remoteFileModel.toExternal(file)).filter((file) => file)
29664
+ ];
29665
+ };
29496
29666
  handlers['api/sync'] = async function () {
29497
29667
  const { id } = _prefs__WEBPACK_IMPORTED_MODULE_14__.getPrefs();
29498
29668
  const result = await handlers['sync-budget']();
@@ -29638,11 +29808,12 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
29638
29808
  payees
29639
29809
  });
29640
29810
  };
29641
- handlers['api/transactions-import'] = withMutation(async function ({ accountId, transactions }) {
29811
+ handlers['api/transactions-import'] = withMutation(async function ({ accountId, transactions, isPreview = false }) {
29642
29812
  checkFileOpen();
29643
29813
  return handlers['transactions-import']({
29644
29814
  accountId,
29645
- transactions
29815
+ transactions,
29816
+ isPreview
29646
29817
  });
29647
29818
  });
29648
29819
  handlers['api/transactions-add'] = withMutation(async function ({ accountId, transactions, runTransfers = false, learnCategories = false }) {
@@ -29751,6 +29922,13 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
29751
29922
  forced: true
29752
29923
  });
29753
29924
  });
29925
+ handlers['api/account-balance'] = withMutation(async function ({ id, cutoff = new Date() }) {
29926
+ checkFileOpen();
29927
+ return handlers['account-balance']({
29928
+ id,
29929
+ cutoff
29930
+ });
29931
+ });
29754
29932
  handlers['api/categories-get'] = async function ({ grouped } = {}) {
29755
29933
  checkFileOpen();
29756
29934
  const result = await handlers['get-categories']();
@@ -29803,6 +29981,11 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
29803
29981
  transferId: transferCategoryId
29804
29982
  });
29805
29983
  });
29984
+ handlers['api/common-payees-get'] = async function () {
29985
+ checkFileOpen();
29986
+ const payees = await handlers['common-payees-get']();
29987
+ return payees.map(_api_models__WEBPACK_IMPORTED_MODULE_8__.payeeModel.toExternal);
29988
+ };
29806
29989
  handlers['api/payees-get'] = async function () {
29807
29990
  checkFileOpen();
29808
29991
  const payees = await handlers['payees-get']();
@@ -29835,6 +30018,13 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
29835
30018
  ]
29836
30019
  });
29837
30020
  });
30021
+ handlers['api/payees-merge'] = withMutation(async function ({ targetId, mergeIds }) {
30022
+ checkFileOpen();
30023
+ return handlers['payees-merge']({
30024
+ targetId,
30025
+ mergeIds
30026
+ });
30027
+ });
29838
30028
  handlers['api/rules-get'] = async function () {
29839
30029
  checkFileOpen();
29840
30030
  return handlers['rules-get']();
@@ -29956,6 +30146,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
29956
30146
  /* harmony export */ quoteAlias: () => ( /* binding */quoteAlias)
29957
30147
  /* harmony export */
29958
30148
  });
30149
+ /* harmony import */ var _shared_normalisation__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../shared/normalisation */ "./packages/loot-core/src/shared/normalisation.ts");
29959
30150
  // @ts-strict-ignore
29960
30151
  let _uid = 0;
29961
30152
  function resetUid() {
@@ -30697,7 +30888,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
30697
30888
  'string',
30698
30889
  'string'
30699
30890
  ]);
30700
- return `${left} LIKE ${right}`;
30891
+ return `UNICODE_LIKE(${(0, _shared_normalisation__WEBPACK_IMPORTED_MODULE_0__.getNormalisedString)(right)}, NORMALISE(${left}))`;
30701
30892
  }
30702
30893
  case '$regexp':
30703
30894
  {
@@ -30719,7 +30910,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
30719
30910
  'string',
30720
30911
  'string'
30721
30912
  ]);
30722
- return `(${left} NOT LIKE ${right}\n OR ${left} IS NULL)`;
30913
+ return `(NOT UNICODE_LIKE(${(0, _shared_normalisation__WEBPACK_IMPORTED_MODULE_0__.getNormalisedString)(right)}, NORMALISE(${left}))\n OR ${left} IS NULL)`;
30723
30914
  }
30724
30915
  default:
30725
30916
  throw new CompileError(`Unknown operator: ${op}`);
@@ -31654,7 +31845,8 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
31654
31845
  transfer_acct: f('id', {
31655
31846
  ref: 'accounts'
31656
31847
  }),
31657
- tombstone: f('boolean')
31848
+ tombstone: f('boolean'),
31849
+ favorite: f('boolean')
31658
31850
  },
31659
31851
  accounts: {
31660
31852
  id: f('id'),
@@ -31665,6 +31857,8 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
31665
31857
  closed: f('boolean'),
31666
31858
  sort_order: f('float'),
31667
31859
  tombstone: f('boolean'),
31860
+ account_id: f('string'),
31861
+ official_name: f('string'),
31668
31862
  account_sync_source: f('string')
31669
31863
  },
31670
31864
  categories: {
@@ -31786,7 +31980,8 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
31786
31980
  category: f('string'),
31787
31981
  amount: f('integer'),
31788
31982
  carryover: f('integer'),
31789
- goal: f('integer')
31983
+ goal: f('integer'),
31984
+ long_goal: f('integer')
31790
31985
  },
31791
31986
  zero_budgets: {
31792
31987
  id: f('id'),
@@ -31794,7 +31989,8 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
31794
31989
  category: f('string'),
31795
31990
  amount: f('integer'),
31796
31991
  carryover: f('integer'),
31797
- goal: f('integer')
31992
+ goal: f('integer'),
31993
+ long_goal: f('integer')
31798
31994
  }
31799
31995
  };
31800
31996
  const schemaConfig = {
@@ -32179,7 +32375,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
32179
32375
  }
32180
32376
  return backups.map((backup) => ({
32181
32377
  ...backup,
32182
- date: backup.date ? date_fns__WEBPACK_IMPORTED_MODULE_6__["default"](backup.date, 'yyyy-MM-dd h:mm') : null
32378
+ date: backup.date ? date_fns__WEBPACK_IMPORTED_MODULE_6__["default"](backup.date, 'yyyy-MM-dd H:mm') : null
32183
32379
  }));
32184
32380
  }
32185
32381
  async function updateBackups(backups) {
@@ -32400,7 +32596,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
32400
32596
  amount
32401
32597
  });
32402
32598
  }
32403
- function setGoal({ month, category, goal }) {
32599
+ function setGoal({ month, category, goal, long_goal }) {
32404
32600
  const table = getBudgetTable();
32405
32601
  const existing = _db__WEBPACK_IMPORTED_MODULE_2__.firstSync(`SELECT id FROM ${table} WHERE month = ? AND category = ?`, [
32406
32602
  dbMonth(month),
@@ -32409,14 +32605,16 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
32409
32605
  if (existing) {
32410
32606
  return _db__WEBPACK_IMPORTED_MODULE_2__.update(table, {
32411
32607
  id: existing.id,
32412
- goal
32608
+ goal,
32609
+ long_goal
32413
32610
  });
32414
32611
  }
32415
32612
  return _db__WEBPACK_IMPORTED_MODULE_2__.insert(table, {
32416
32613
  id: `${dbMonth(month)}-${category}`,
32417
32614
  month: dbMonth(month),
32418
32615
  category,
32419
- goal
32616
+ goal,
32617
+ long_goal
32420
32618
  });
32421
32619
  }
32422
32620
  function setBuffer(month, amount) {
@@ -32921,6 +33119,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
32921
33119
  _sheet__WEBPACK_IMPORTED_MODULE_3__.get().set(`${sheetName}!budget-${budget.category}`, budget.amount || 0);
32922
33120
  _sheet__WEBPACK_IMPORTED_MODULE_3__.get().set(`${sheetName}!carryover-${budget.category}`, budget.carryover === 1 ? true : false);
32923
33121
  _sheet__WEBPACK_IMPORTED_MODULE_3__.get().set(`${sheetName}!goal-${budget.category}`, budget.goal);
33122
+ _sheet__WEBPACK_IMPORTED_MODULE_3__.get().set(`${sheetName}!long-goal-${budget.category}`, budget.long_goal);
32924
33123
  }
32925
33124
  }
32926
33125
  function triggerBudgetChanges(oldValues, newValues) {
@@ -33230,7 +33429,8 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
33230
33429
  await (0, _actions__WEBPACK_IMPORTED_MODULE_2__.setGoal)({
33231
33430
  category: category.id,
33232
33431
  month,
33233
- goal: budgeted - balance
33432
+ goal: budgeted - balance,
33433
+ long_goal: 0
33234
33434
  });
33235
33435
  num_sources += 1;
33236
33436
  }
@@ -33956,35 +34156,34 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
33956
34156
  /* harmony import */ var _goals_goalsSpend__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./goals/goalsSpend */ "./packages/loot-core/src/server/budget/goals/goalsSpend.ts");
33957
34157
  /* harmony import */ var _goals_goalsWeek__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./goals/goalsWeek */ "./packages/loot-core/src/server/budget/goals/goalsWeek.ts");
33958
34158
  // @ts-strict-ignore
34159
+ const TEMPLATE_PREFIX = '#template';
34160
+ const GOAL_PREFIX = '#goal';
33959
34161
  async function applyTemplate({ month }) {
33960
34162
  await storeTemplates();
33961
- const category_templates = await getTemplates(null);
33962
- await resetCategoryTargets({
33963
- month,
33964
- category: null
33965
- });
33966
- return processTemplate(month, false, category_templates);
34163
+ const category_templates = await getTemplates(null, 'template');
34164
+ const category_goals = await getTemplates(null, 'goal');
34165
+ const ret = await processTemplate(month, false, category_templates);
34166
+ await processGoals(category_goals, month);
34167
+ return ret;
33967
34168
  }
33968
34169
  async function overwriteTemplate({ month }) {
33969
34170
  await storeTemplates();
33970
- const category_templates = await getTemplates(null);
33971
- await resetCategoryTargets({
33972
- month,
33973
- category: null
33974
- });
33975
- return processTemplate(month, true, category_templates);
34171
+ const category_templates = await getTemplates(null, 'template');
34172
+ const category_goals = await getTemplates(null, 'goal');
34173
+ const ret = await processTemplate(month, true, category_templates);
34174
+ await processGoals(category_goals, month);
34175
+ return ret;
33976
34176
  }
33977
34177
  async function applySingleCategoryTemplate({ month, category }) {
33978
34178
  const categories = await _db__WEBPACK_IMPORTED_MODULE_2__.all(`SELECT * FROM v_categories WHERE id = ?`, [
33979
34179
  category
33980
34180
  ]);
33981
34181
  await storeTemplates();
33982
- const category_templates = await getTemplates(categories[0]);
33983
- await resetCategoryTargets({
33984
- month,
33985
- category: categories
33986
- });
33987
- return processTemplate(month, true, category_templates);
34182
+ const category_templates = await getTemplates(categories[0], 'template');
34183
+ const category_goals = await getTemplates(categories[0], 'goal');
34184
+ const ret = await processTemplate(month, true, category_templates, categories[0]);
34185
+ await processGoals(category_goals, month, categories[0]);
34186
+ return ret;
33988
34187
  }
33989
34188
  function runCheckTemplates() {
33990
34189
  return checkTemplates();
@@ -34028,13 +34227,14 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
34028
34227
  (0, _actions__WEBPACK_IMPORTED_MODULE_4__.setGoal)({
34029
34228
  category: element.category,
34030
34229
  goal: element.amount,
34031
- month
34230
+ month,
34231
+ long_goal: 0
34032
34232
  });
34033
34233
  });
34034
34234
  });
34035
34235
  }
34036
- async function resetCategoryTargets({ month, category }) {
34037
- let categories;
34236
+ async function resetCategoryTargets(month, category) {
34237
+ let categories = [];
34038
34238
  if (category === null) {
34039
34239
  categories = await getCategories();
34040
34240
  }
@@ -34042,13 +34242,14 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
34042
34242
  categories = category;
34043
34243
  }
34044
34244
  await (0, _sync__WEBPACK_IMPORTED_MODULE_3__.batchMessages)(async () => {
34045
- categories.forEach((element) => {
34245
+ for (let i = 0; i < categories.length; i++) {
34046
34246
  (0, _actions__WEBPACK_IMPORTED_MODULE_4__.setGoal)({
34047
- category: element.id,
34247
+ category: categories[i].id,
34048
34248
  goal: null,
34049
- month
34249
+ month,
34250
+ long_goal: null
34050
34251
  });
34051
- });
34252
+ }
34052
34253
  });
34053
34254
  }
34054
34255
  async function storeTemplates() {
@@ -34071,7 +34272,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
34071
34272
  }
34072
34273
  }
34073
34274
  }
34074
- async function getTemplates(category) {
34275
+ async function getTemplates(category, directive) {
34075
34276
  //retrieves template definitions from the database
34076
34277
  const goal_def = await _db__WEBPACK_IMPORTED_MODULE_2__.all('SELECT * FROM categories WHERE goal_def IS NOT NULL');
34077
34278
  const templates = [];
@@ -34079,24 +34280,41 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
34079
34280
  templates[goal_def[ll].id] = JSON.parse(goal_def[ll].goal_def);
34080
34281
  }
34081
34282
  if (category) {
34082
- const singleCategoryTemplate = {};
34283
+ const singleCategoryTemplate = [];
34083
34284
  if (templates[category.id] !== undefined) {
34084
- singleCategoryTemplate[category.id] = templates[category.id];
34285
+ singleCategoryTemplate[category.id] = templates[category.id].filter((t) => t.directive === directive);
34286
+ return singleCategoryTemplate;
34085
34287
  }
34288
+ singleCategoryTemplate[category.id] = undefined;
34086
34289
  return singleCategoryTemplate;
34087
34290
  }
34088
34291
  else {
34089
- return templates;
34292
+ const categories = await getCategories();
34293
+ const ret = [];
34294
+ for (let cc = 0; cc < categories.length; cc++) {
34295
+ const id = categories[cc].id;
34296
+ if (templates[id]) {
34297
+ ret[id] = templates[id];
34298
+ ret[id] = ret[id].filter((t) => t.directive === directive);
34299
+ }
34300
+ }
34301
+ return ret;
34090
34302
  }
34091
34303
  }
34092
- async function processTemplate(month, force, category_templates) {
34304
+ async function processTemplate(month, force, category_templates, category) {
34093
34305
  let num_applied = 0;
34094
34306
  let errors = [];
34095
34307
  const idealTemplate = [];
34096
34308
  const setToZero = [];
34097
34309
  let priority_list = [];
34098
- const categories = await getCategories();
34310
+ let categories = [];
34099
34311
  const categories_remove = [];
34312
+ if (category) {
34313
+ categories[0] = category;
34314
+ }
34315
+ else {
34316
+ categories = await getCategories();
34317
+ }
34100
34318
  //clears templated categories
34101
34319
  for (let c = 0; c < categories.length; c++) {
34102
34320
  const category = categories[c];
@@ -34117,13 +34335,12 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
34117
34335
  categories_remove.push(c);
34118
34336
  }
34119
34337
  else {
34120
- // if we are overwritting add this category to list to zero
34121
- setToZero.push({
34122
- category: category.id,
34123
- amount: 0,
34124
- isIncome: category.is_income,
34125
- isTemplate: template ? true : false
34126
- });
34338
+ // add all categories with a template to the list to unset budget
34339
+ if (template?.length > 0) {
34340
+ setToZero.push({
34341
+ category: category.id
34342
+ });
34343
+ }
34127
34344
  }
34128
34345
  }
34129
34346
  }
@@ -34133,11 +34350,12 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
34133
34350
  for (let i = categories_remove.length - 1; i >= 0; i--) {
34134
34351
  categories.splice(categories_remove[i], 1);
34135
34352
  }
34136
- // zero out the categories that need it
34353
+ // zero out budget and goal from categories that need it
34137
34354
  await setGoalBudget({
34138
34355
  month,
34139
- templateBudget: setToZero.filter((f) => f.isTemplate === true)
34356
+ templateBudget: setToZero
34140
34357
  });
34358
+ await resetCategoryTargets(month, categories);
34141
34359
  // sort and filter down to just the requested priorities
34142
34360
  priority_list = priority_list.sort(function (a, b) {
34143
34361
  return a - b;
@@ -34267,10 +34485,34 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
34267
34485
  }
34268
34486
  }
34269
34487
  }
34270
- const TEMPLATE_PREFIX = '#template';
34488
+ async function processGoals(goals, month, category) {
34489
+ let categories = [];
34490
+ if (category) {
34491
+ categories[0] = category;
34492
+ }
34493
+ else {
34494
+ categories = await getCategories();
34495
+ }
34496
+ for (let c = 0; c < categories.length; c++) {
34497
+ const cat_id = categories[c].id;
34498
+ const goal_lines = goals[cat_id];
34499
+ if (goal_lines?.length > 0) {
34500
+ await (0, _actions__WEBPACK_IMPORTED_MODULE_4__.setGoal)({
34501
+ month,
34502
+ category: cat_id,
34503
+ goal: (0, _shared_util__WEBPACK_IMPORTED_MODULE_1__.amountToInteger)(goal_lines[0].amount),
34504
+ long_goal: 1
34505
+ });
34506
+ }
34507
+ }
34508
+ }
34271
34509
  async function getCategoryTemplates(category) {
34272
34510
  const templates = {};
34273
- let notes = await _db__WEBPACK_IMPORTED_MODULE_2__.all(`SELECT * FROM notes WHERE lower(note) like '%${TEMPLATE_PREFIX}%'`);
34511
+ let notes = await _db__WEBPACK_IMPORTED_MODULE_2__.all(`
34512
+ SELECT * FROM notes
34513
+ WHERE lower(note) like '%${TEMPLATE_PREFIX}%'
34514
+ OR lower(note) like '%${GOAL_PREFIX}%'
34515
+ `);
34274
34516
  if (category)
34275
34517
  notes = notes.filter((n) => n.id === category.id);
34276
34518
  for (let n = 0; n < notes.length; n++) {
@@ -34278,11 +34520,11 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
34278
34520
  const template_lines = [];
34279
34521
  for (let l = 0; l < lines.length; l++) {
34280
34522
  const line = lines[l].trim();
34281
- if (!line.toLowerCase().startsWith(TEMPLATE_PREFIX))
34523
+ if (!line.toLowerCase().startsWith(TEMPLATE_PREFIX) && !line.toLowerCase().startsWith(GOAL_PREFIX)) {
34282
34524
  continue;
34283
- const expression = line.slice(TEMPLATE_PREFIX.length);
34525
+ }
34284
34526
  try {
34285
- const parsed = (0, _goal_template_pegjs__WEBPACK_IMPORTED_MODULE_5__.parse)(expression);
34527
+ const parsed = (0, _goal_template_pegjs__WEBPACK_IMPORTED_MODULE_5__.parse)(line);
34286
34528
  template_lines.push(parsed);
34287
34529
  }
34288
34530
  catch (e) {
@@ -35234,6 +35476,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
35234
35476
  /* harmony export */ getAccounts: () => ( /* binding */getAccounts),
35235
35477
  /* harmony export */ getCategories: () => ( /* binding */getCategories),
35236
35478
  /* harmony export */ getCategoriesGrouped: () => ( /* binding */getCategoriesGrouped),
35479
+ /* harmony export */ getCommonPayees: () => ( /* binding */getCommonPayees),
35237
35480
  /* harmony export */ getDatabase: () => ( /* binding */getDatabase),
35238
35481
  /* harmony export */ getDatabasePath: () => ( /* binding */getDatabasePath),
35239
35482
  /* harmony export */ getOrphanedPayees: () => ( /* binding */getOrphanedPayees),
@@ -35704,6 +35947,24 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
35704
35947
  LEFT JOIN accounts a ON (p.transfer_acct = a.id AND a.tombstone = 0)
35705
35948
  WHERE p.tombstone = 0 AND (p.transfer_acct IS NULL OR a.id IS NOT NULL)
35706
35949
  ORDER BY p.transfer_acct IS NULL DESC, p.name COLLATE NOCASE, a.offbudget, a.sort_order
35950
+ `);
35951
+ }
35952
+ function getCommonPayees() {
35953
+ const threeMonthsAgo = '20240201';
35954
+ const limit = 10;
35955
+ return all(`
35956
+ SELECT p.id as id, p.name as name, p.favorite as favorite,
35957
+ p.category as category, TRUE as common, NULL as transfer_acct,
35958
+ count(*) as c,
35959
+ max(t.date) as latest
35960
+ FROM payees p
35961
+ LEFT JOIN v_transactions t on t.payee == p.id
35962
+ WHERE LENGTH(p.name) > 0
35963
+ GROUP BY p.id
35964
+ HAVING latest > ${threeMonthsAgo}
35965
+ ORDER BY c DESC ,p.transfer_acct IS NULL DESC, p.name
35966
+ COLLATE NOCASE
35967
+ LIMIT ${limit}
35707
35968
  `);
35708
35969
  }
35709
35970
  function syncGetOrphanedPayees() {
@@ -37655,6 +37916,9 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
37655
37916
  });
37656
37917
  });
37657
37918
  });
37919
+ handlers['common-payees-get'] = async function () {
37920
+ return _db__WEBPACK_IMPORTED_MODULE_27__.getCommonPayees();
37921
+ };
37658
37922
  handlers['payees-get'] = async function () {
37659
37923
  return _db__WEBPACK_IMPORTED_MODULE_27__.getPayees();
37660
37924
  };
@@ -37773,6 +38037,13 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
37773
38037
  handlers['accounts-get'] = async function () {
37774
38038
  return _db__WEBPACK_IMPORTED_MODULE_27__.getAccounts();
37775
38039
  };
38040
+ handlers['account-balance'] = async function ({ id, cutoff }) {
38041
+ const { balance } = await _db__WEBPACK_IMPORTED_MODULE_27__.first('SELECT sum(amount) as balance FROM transactions WHERE acct = ? AND isParent = 0 AND tombstone = 0 AND date <= ?', [
38042
+ id,
38043
+ _db__WEBPACK_IMPORTED_MODULE_27__.toDateRepr((0, _shared_months__WEBPACK_IMPORTED_MODULE_11__.dayFromDate)(cutoff))
38044
+ ]);
38045
+ return balance ? balance : 0;
38046
+ };
37776
38047
  handlers['account-properties'] = async function ({ id }) {
37777
38048
  const { balance } = await _db__WEBPACK_IMPORTED_MODULE_27__.first('SELECT sum(amount) as balance FROM transactions WHERE acct = ? AND isParent = 0 AND tombstone = 0', [
37778
38049
  id
@@ -38172,7 +38443,8 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
38172
38443
  ]);
38173
38444
  const accounts = await _db__WEBPACK_IMPORTED_MODULE_27__.runQuery(`SELECT a.*, b.bank_id as bankId FROM accounts a
38174
38445
  LEFT JOIN banks b ON a.bank = b.id
38175
- WHERE a.tombstone = 0 AND a.closed = 0 ${id ? 'AND a.id = ?' : ''}`, id ? [
38446
+ WHERE a.tombstone = 0 AND a.closed = 0 ${id ? 'AND a.id = ?' : ''}
38447
+ ORDER BY a.offbudget, a.sort_order`, id ? [
38176
38448
  id
38177
38449
  ] : [], true);
38178
38450
  const errors = [];
@@ -38185,7 +38457,6 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
38185
38457
  try {
38186
38458
  console.group('Bank Sync operation for account:', acct.name);
38187
38459
  const res = await _accounts_sync__WEBPACK_IMPORTED_MODULE_18__.syncAccount(userId, userKey, acct.id, acct.account_id, acct.bankId);
38188
- console.groupEnd();
38189
38460
  const { added, updated } = res;
38190
38461
  newTransactions = newTransactions.concat(added);
38191
38462
  matchedTransactions = matchedTransactions.concat(updated);
@@ -38219,6 +38490,9 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
38219
38490
  (0, _platform_exceptions__WEBPACK_IMPORTED_MODULE_4__.captureException)(err);
38220
38491
  }
38221
38492
  }
38493
+ finally {
38494
+ console.groupEnd();
38495
+ }
38222
38496
  }
38223
38497
  }
38224
38498
  if (updatedAccounts.length > 0) {
@@ -38236,13 +38510,13 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
38236
38510
  updatedAccounts
38237
38511
  };
38238
38512
  };
38239
- handlers['transactions-import'] = (0, _mutators__WEBPACK_IMPORTED_MODULE_34__.mutator)(function ({ accountId, transactions }) {
38513
+ handlers['transactions-import'] = (0, _mutators__WEBPACK_IMPORTED_MODULE_34__.mutator)(function ({ accountId, transactions, isPreview }) {
38240
38514
  return (0, _undo__WEBPACK_IMPORTED_MODULE_48__.withUndo)(async () => {
38241
38515
  if (typeof accountId !== 'string') {
38242
38516
  throw (0, _errors__WEBPACK_IMPORTED_MODULE_30__.APIError)('transactions-import: accountId must be an id');
38243
38517
  }
38244
38518
  try {
38245
- return await _accounts_sync__WEBPACK_IMPORTED_MODULE_18__.reconcileTransactions(accountId, transactions);
38519
+ return await _accounts_sync__WEBPACK_IMPORTED_MODULE_18__.reconcileTransactions(accountId, transactions, false, isPreview);
38246
38520
  }
38247
38521
  catch (err) {
38248
38522
  if (err instanceof _errors__WEBPACK_IMPORTED_MODULE_30__.TransactionError) {
@@ -38253,7 +38527,8 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
38253
38527
  }
38254
38528
  ],
38255
38529
  added: [],
38256
- updated: []
38530
+ updated: [],
38531
+ updatedPreview: []
38257
38532
  };
38258
38533
  }
38259
38534
  throw err;
@@ -38315,13 +38590,6 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
38315
38590
  if ('maxMonths' in prefs) {
38316
38591
  await _platform_server_asyncStorage__WEBPACK_IMPORTED_MODULE_5__.setItem('max-months', '' + prefs.maxMonths);
38317
38592
  }
38318
- if ('autoUpdate' in prefs) {
38319
- await _platform_server_asyncStorage__WEBPACK_IMPORTED_MODULE_5__.setItem('auto-update', '' + prefs.autoUpdate);
38320
- process.parentPort.postMessage({
38321
- type: 'shouldAutoUpdate',
38322
- flag: prefs.autoUpdate
38323
- });
38324
- }
38325
38593
  if ('documentDir' in prefs) {
38326
38594
  if (await _platform_server_fs__WEBPACK_IMPORTED_MODULE_7__.exists(prefs.documentDir)) {
38327
38595
  await _platform_server_asyncStorage__WEBPACK_IMPORTED_MODULE_5__.setItem('document-dir', prefs.documentDir);
@@ -38336,10 +38604,9 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
38336
38604
  return 'ok';
38337
38605
  };
38338
38606
  handlers['load-global-prefs'] = async function () {
38339
- const [[, floatingSidebar], [, maxMonths], [, autoUpdate], [, documentDir], [, encryptKey], [, theme]] = await _platform_server_asyncStorage__WEBPACK_IMPORTED_MODULE_5__.multiGet([
38607
+ const [[, floatingSidebar], [, maxMonths], [, documentDir], [, encryptKey], [, theme]] = await _platform_server_asyncStorage__WEBPACK_IMPORTED_MODULE_5__.multiGet([
38340
38608
  'floating-sidebar',
38341
38609
  'max-months',
38342
- 'auto-update',
38343
38610
  'document-dir',
38344
38611
  'encrypt-key',
38345
38612
  'theme'
@@ -38347,7 +38614,6 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
38347
38614
  return {
38348
38615
  floatingSidebar: floatingSidebar === 'true' ? true : false,
38349
38616
  maxMonths: (0, _shared_util__WEBPACK_IMPORTED_MODULE_13__.stringToInteger)(maxMonths || ''),
38350
- autoUpdate: autoUpdate == null || autoUpdate === 'true' ? true : false,
38351
38617
  documentDir: documentDir || getDefaultDocumentDir(),
38352
38618
  keyId: encryptKey && JSON.parse(encryptKey).id,
38353
38619
  theme: theme === 'light' || theme === 'dark' || theme === 'auto' || theme === 'development' || theme === 'midnight' ? theme : 'auto'
@@ -39174,13 +39440,6 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
39174
39440
  }
39175
39441
  (0, _server_config__WEBPACK_IMPORTED_MODULE_42__.setServer)(url);
39176
39442
  _platform_server_connection__WEBPACK_IMPORTED_MODULE_6__.init(socketName, _main_app__WEBPACK_IMPORTED_MODULE_33__.app.handlers);
39177
- if (!isDev && !_platform__WEBPACK_IMPORTED_MODULE_36__.isMobile && !_platform__WEBPACK_IMPORTED_MODULE_36__.isWeb) {
39178
- const autoUpdate = await _platform_server_asyncStorage__WEBPACK_IMPORTED_MODULE_5__.getItem('auto-update');
39179
- process.parentPort.postMessage({
39180
- type: 'shouldAutoUpdate',
39181
- flag: autoUpdate == null || autoUpdate === 'true'
39182
- });
39183
- }
39184
39443
  // Allow running DB queries locally
39185
39444
  global.$query = _aql__WEBPACK_IMPORTED_MODULE_22__.runQuery;
39186
39445
  global.$q = _shared_query__WEBPACK_IMPORTED_MODULE_12__.q;
@@ -39908,8 +40167,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
39908
40167
  selectedCategories: row.selected_categories,
39909
40168
  graphType: row.graph_type,
39910
40169
  conditions: row.conditions,
39911
- conditionsOp: row.conditions_op,
39912
- data: row.metadata
40170
+ conditionsOp: row.conditions_op
39913
40171
  };
39914
40172
  },
39915
40173
  fromJS(report) {
@@ -39932,8 +40190,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
39932
40190
  selected_categories: report.selectedCategories,
39933
40191
  graph_type: report.graphType,
39934
40192
  conditions: report.conditions,
39935
- conditions_op: report.conditionsOp,
39936
- metadata: report.data
40193
+ conditions_op: report.conditionsOp
39937
40194
  };
39938
40195
  }
39939
40196
  };
@@ -39985,7 +40242,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
39985
40242
  if (nameExists) {
39986
40243
  throw new Error('There is already a filter named ' + item.name);
39987
40244
  }
39988
- await _db__WEBPACK_IMPORTED_MODULE_1__.insertWithSchema('custom_reports', reportModel.fromJS(item));
40245
+ await _db__WEBPACK_IMPORTED_MODULE_1__.updateWithSchema('custom_reports', reportModel.fromJS(item));
39989
40246
  }
39990
40247
  async function deleteReport(id) {
39991
40248
  await _db__WEBPACK_IMPORTED_MODULE_1__.delete_('custom_reports', id);
@@ -40033,8 +40290,8 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
40033
40290
  throw e;
40034
40291
  }
40035
40292
  return null;
40036
- }).filter((res) => typeof res === 'string');
40037
- return result.length ? result : null;
40293
+ });
40294
+ return result.filter((res) => typeof res === 'string').length ? result : null;
40038
40295
  }
40039
40296
  const conditionErrors = runValidation(rule.conditions, (cond) => new _accounts_rules__WEBPACK_IMPORTED_MODULE_1__.Condition(cond.op, cond.field, cond.value, cond.options, _shared_rules__WEBPACK_IMPORTED_MODULE_0__.FIELD_TYPES));
40040
40297
  const actionErrors = runValidation(rule.actions, (action) => action.op === 'set-split-amount' ? new _accounts_rules__WEBPACK_IMPORTED_MODULE_1__.Action(action.op, null, action.value, action.options, _shared_rules__WEBPACK_IMPORTED_MODULE_0__.FIELD_TYPES) : action.op === 'link-schedule' ? new _accounts_rules__WEBPACK_IMPORTED_MODULE_1__.Action(action.op, null, action.value, null, _shared_rules__WEBPACK_IMPORTED_MODULE_0__.FIELD_TYPES) : new _accounts_rules__WEBPACK_IMPORTED_MODULE_1__.Action(action.op, action.field, action.value, action.options, _shared_rules__WEBPACK_IMPORTED_MODULE_0__.FIELD_TYPES));
@@ -41189,6 +41446,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
41189
41446
  sheet.set(`${sheetName}!budget-${budget.category}`, budget.amount);
41190
41447
  sheet.set(`${sheetName}!carryover-${budget.category}`, budget.carryover === 1 ? true : false);
41191
41448
  sheet.set(`${sheetName}!goal-${budget.category}`, budget.goal);
41449
+ sheet.set(`${sheetName}!long-goal-${budget.category}`, budget.long_goal);
41192
41450
  }
41193
41451
  }
41194
41452
  // For zero-based budgets, load the buffered amounts
@@ -43989,6 +44247,22 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
43989
44247
  });
43990
44248
  /***/
43991
44249
  }),
44250
+ /***/ "./packages/loot-core/src/shared/normalisation.ts":
44251
+ /*!********************************************************!*\
44252
+ !*** ./packages/loot-core/src/shared/normalisation.ts ***!
44253
+ \********************************************************/
44254
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
44255
+ "use strict";
44256
+ __webpack_require__.r(__webpack_exports__);
44257
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
44258
+ /* harmony export */ getNormalisedString: () => ( /* binding */getNormalisedString)
44259
+ /* harmony export */
44260
+ });
44261
+ function getNormalisedString(value) {
44262
+ return value.toLowerCase().normalize('NFD').replace(/\p{Diacritic}/gu, '');
44263
+ }
44264
+ /***/
44265
+ }),
43992
44266
  /***/ "./packages/loot-core/src/shared/query.ts":
43993
44267
  /*!************************************************!*\
43994
44268
  !*** ./packages/loot-core/src/shared/query.ts ***!
@@ -45009,7 +45283,8 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
45009
45283
  return replaceTransactions(transactions, transaction.id, (trans) => {
45010
45284
  if (trans.is_parent) {
45011
45285
  const parent = trans.id === transaction.id ? transaction : trans;
45012
- const sub = trans.subtransactions?.map((t) => {
45286
+ const originalSubtransactions = parent.subtransactions ?? trans.subtransactions;
45287
+ const sub = originalSubtransactions?.map((t) => {
45013
45288
  // Make sure to update the children to reflect the updated
45014
45289
  // properties (if the parent updated)
45015
45290
  let child = t;
@@ -45358,13 +45633,13 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
45358
45633
  },
45359
45634
  {
45360
45635
  value: 'space-comma',
45361
- label: '1 000,33',
45362
- labelNoFraction: '1 000'
45636
+ label: '1\xa0000,33',
45637
+ labelNoFraction: '1\xa0000'
45363
45638
  },
45364
45639
  {
45365
- value: 'space-dot',
45366
- label: '1 000.33',
45367
- labelNoFraction: '1 000'
45640
+ value: 'apostrophe-dot',
45641
+ label: '1000.33',
45642
+ labelNoFraction: '1000'
45368
45643
  },
45369
45644
  {
45370
45645
  value: 'comma-dot-in',
@@ -45393,8 +45668,8 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
45393
45668
  regex = /[^-0-9,]/g;
45394
45669
  separator = ',';
45395
45670
  break;
45396
- case 'space-dot':
45397
- locale = 'dje';
45671
+ case 'apostrophe-dot':
45672
+ locale = 'de-CH';
45398
45673
  regex = /[^-0-9,.]/g;
45399
45674
  separator = '.';
45400
45675
  separatorRegex = /[,.]/g;
@@ -45451,6 +45726,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
45451
45726
  }
45452
45727
  function amountToCurrencyNoDecimal(n) {
45453
45728
  return getNumberFormat({
45729
+ ...numberFormatConfig,
45454
45730
  hideFraction: true
45455
45731
  }).formatter.format(n);
45456
45732
  }
@@ -51244,9 +51520,11 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
51244
51520
  var peg$c19 = "full";
51245
51521
  var peg$c20 = "-";
51246
51522
  var peg$c21 = "remainder";
51247
- var peg$c22 = " ";
51248
- var peg$c23 = ".";
51249
- var peg$c24 = "%";
51523
+ var peg$c22 = "#template";
51524
+ var peg$c23 = "#goal";
51525
+ var peg$c24 = " ";
51526
+ var peg$c25 = ".";
51527
+ var peg$c26 = "%";
51250
51528
  var peg$r0 = /^[0-9]/;
51251
51529
  var peg$r1 = /^[1-9]/;
51252
51530
  var peg$r2 = /^[^\r\n\t]/;
@@ -51273,58 +51551,62 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
51273
51551
  var peg$e20 = peg$literalExpectation("full", true);
51274
51552
  var peg$e21 = peg$literalExpectation("-", true);
51275
51553
  var peg$e22 = peg$literalExpectation("remainder", true);
51276
- var peg$e23 = peg$otherExpectation("space");
51277
- var peg$e24 = peg$literalExpectation(" ", false);
51278
- var peg$e25 = peg$otherExpectation("digit");
51279
- var peg$e26 = peg$classExpectation([["0", "9"]], false, false);
51280
- var peg$e27 = peg$otherExpectation("number");
51281
- var peg$e28 = peg$classExpectation([["1", "9"]], false, false);
51282
- var peg$e29 = peg$otherExpectation("amount");
51283
- var peg$e30 = peg$literalExpectation(".", false);
51284
- var peg$e31 = peg$otherExpectation("percentage");
51285
- var peg$e32 = peg$literalExpectation("%", false);
51286
- var peg$e33 = peg$otherExpectation("year");
51287
- var peg$e34 = peg$otherExpectation("month");
51288
- var peg$e35 = peg$literalExpectation("-", false);
51289
- var peg$e36 = peg$otherExpectation("day");
51290
- var peg$e37 = peg$otherExpectation("currency symbol");
51291
- var peg$e38 = peg$anyExpectation();
51292
- var peg$e39 = peg$otherExpectation("Name");
51293
- var peg$e40 = peg$classExpectation(["\r", "\n", "\t"], true, false);
51294
- var peg$f0 = function (priority, percentOf, category) { return { type: 'percentage', percent: +percentOf.percent, previous: percentOf.prev, category, priority: +priority }; };
51295
- var peg$f1 = function (priority, amount, weeks, starting, limit) { return { type: 'week', amount, weeks, starting, limit, priority: +priority }; };
51296
- var peg$f2 = function (priority, amount, month, from, repeat) {
51554
+ var peg$e23 = peg$literalExpectation("#template", false);
51555
+ var peg$e24 = peg$literalExpectation("#goal", false);
51556
+ var peg$e25 = peg$otherExpectation("space");
51557
+ var peg$e26 = peg$literalExpectation(" ", false);
51558
+ var peg$e27 = peg$otherExpectation("digit");
51559
+ var peg$e28 = peg$classExpectation([["0", "9"]], false, false);
51560
+ var peg$e29 = peg$otherExpectation("number");
51561
+ var peg$e30 = peg$classExpectation([["1", "9"]], false, false);
51562
+ var peg$e31 = peg$otherExpectation("amount");
51563
+ var peg$e32 = peg$literalExpectation(".", false);
51564
+ var peg$e33 = peg$otherExpectation("percentage");
51565
+ var peg$e34 = peg$literalExpectation("%", false);
51566
+ var peg$e35 = peg$otherExpectation("year");
51567
+ var peg$e36 = peg$otherExpectation("month");
51568
+ var peg$e37 = peg$literalExpectation("-", false);
51569
+ var peg$e38 = peg$otherExpectation("day");
51570
+ var peg$e39 = peg$otherExpectation("currency symbol");
51571
+ var peg$e40 = peg$anyExpectation();
51572
+ var peg$e41 = peg$otherExpectation("Name");
51573
+ var peg$e42 = peg$classExpectation(["\r", "\n", "\t"], true, false);
51574
+ var peg$f0 = function (template, percentOf, category) { return { type: 'percentage', percent: +percentOf.percent, previous: percentOf.prev, category, priority: template.priority, directive: template.directive }; };
51575
+ var peg$f1 = function (template, amount, weeks, starting, limit) { return { type: 'week', amount, weeks, starting, limit, priority: template.priority, directive: template.directive }; };
51576
+ var peg$f2 = function (template, amount, month, from, repeat) {
51297
51577
  return {
51298
51578
  type: from ? 'spend' : 'by',
51299
51579
  amount,
51300
51580
  month,
51301
51581
  ...(repeat ? repeat[3] : {}),
51302
51582
  from,
51303
- priority: +priority
51583
+ priority: template.priority, directive: template.directive
51304
51584
  };
51305
51585
  };
51306
- var peg$f3 = function (priority, monthly, limit) { return { type: 'simple', monthly, limit, priority: +priority }; };
51307
- var peg$f4 = function (priority, limit) { return { type: 'simple', limit, priority: +priority }; };
51308
- var peg$f5 = function (priority, full, name) { return { type: 'schedule', name, priority: +priority, full }; };
51309
- var peg$f6 = function (priority, remainder) { return { type: 'remainder', priority: null, weight: remainder }; };
51310
- var peg$f7 = function (priority, amount) { return { type: 'average', amount: +amount, priority: +priority }; };
51311
- var peg$f8 = function () { return { annual: false }; };
51312
- var peg$f9 = function (months) { return { annual: false, repeat: +months }; };
51313
- var peg$f10 = function () { return { annual: true }; };
51314
- var peg$f11 = function (years) { return { annual: true, repeat: +years }; };
51315
- var peg$f12 = function (amount) { return { amount: amount, hold: true }; };
51316
- var peg$f13 = function (amount) { return { amount: amount, hold: false }; };
51317
- var peg$f14 = function (percent) { return { percent: percent, prev: true }; };
51318
- var peg$f15 = function (percent) { return { percent: percent, prev: false }; };
51319
- var peg$f16 = function () { return null; };
51320
- var peg$f17 = function (n) { return +n; };
51321
- var peg$f18 = function (month) { return month; };
51322
- var peg$f19 = function () { return true; };
51323
- var peg$f20 = function (number) { return number; };
51324
- var peg$f21 = function (weight) { return +weight || 1; };
51325
- var peg$f22 = function (amount) { return +amount; };
51326
- var peg$f23 = function (percent) { return +percent; };
51327
- var peg$f24 = function (symbol) { return /\p{Sc}/u.test(symbol); };
51586
+ var peg$f3 = function (template, monthly, limit) { return { type: 'simple', monthly, limit, priority: template.priority, directive: template.directive }; };
51587
+ var peg$f4 = function (template, limit) { return { type: 'simple', limit, priority: template.priority, directive: template.directive }; };
51588
+ var peg$f5 = function (template, full, name) { return { type: 'schedule', name, priority: template.priority, directive: template.directive, full }; };
51589
+ var peg$f6 = function (template, remainder, limit) { return { type: 'remainder', priority: null, directive: template.directive, weight: remainder, limit }; };
51590
+ var peg$f7 = function (template, amount) { return { type: 'average', amount: +amount, priority: template.priority, directive: template.directive }; };
51591
+ var peg$f8 = function (goal, amount) { return { type: 'simple', amount: amount, priority: null, directive: 'goal' }; };
51592
+ var peg$f9 = function () { return { annual: false }; };
51593
+ var peg$f10 = function (months) { return { annual: false, repeat: +months }; };
51594
+ var peg$f11 = function () { return { annual: true }; };
51595
+ var peg$f12 = function (years) { return { annual: true, repeat: +years }; };
51596
+ var peg$f13 = function (amount) { return { amount: amount, hold: true }; };
51597
+ var peg$f14 = function (amount) { return { amount: amount, hold: false }; };
51598
+ var peg$f15 = function (percent) { return { percent: percent, prev: true }; };
51599
+ var peg$f16 = function (percent) { return { percent: percent, prev: false }; };
51600
+ var peg$f17 = function () { return null; };
51601
+ var peg$f18 = function (n) { return +n; };
51602
+ var peg$f19 = function (month) { return month; };
51603
+ var peg$f20 = function () { return true; };
51604
+ var peg$f21 = function (number) { return number; };
51605
+ var peg$f22 = function (weight) { return +weight || 1; };
51606
+ var peg$f23 = function (priority) { return { priority: +priority, directive: 'template' }; };
51607
+ var peg$f24 = function (amount) { return +amount; };
51608
+ var peg$f25 = function (percent) { return +percent; };
51609
+ var peg$f26 = function (symbol) { return /\p{Sc}/u.test(symbol); };
51328
51610
  var peg$currPos = 0;
51329
51611
  var peg$savedPos = 0;
51330
51612
  var peg$posDetailsCache = [{ line: 1, column: 1 }];
@@ -51452,20 +51734,26 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
51452
51734
  function peg$parseexpr() {
51453
51735
  var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13;
51454
51736
  s0 = peg$currPos;
51455
- s1 = peg$parsepriority();
51456
- if (s1 === peg$FAILED) {
51457
- s1 = null;
51458
- }
51459
- s2 = peg$parse_();
51460
- if (s2 === peg$FAILED) {
51461
- s2 = null;
51462
- }
51463
- s3 = peg$parsepercentOf();
51464
- if (s3 !== peg$FAILED) {
51465
- s4 = peg$parsename();
51466
- if (s4 !== peg$FAILED) {
51467
- peg$savedPos = s0;
51468
- s0 = peg$f0(s1, s3, s4);
51737
+ s1 = peg$parsetemplate();
51738
+ if (s1 !== peg$FAILED) {
51739
+ s2 = peg$parse_();
51740
+ if (s2 !== peg$FAILED) {
51741
+ s3 = peg$parsepercentOf();
51742
+ if (s3 !== peg$FAILED) {
51743
+ s4 = peg$parsename();
51744
+ if (s4 !== peg$FAILED) {
51745
+ peg$savedPos = s0;
51746
+ s0 = peg$f0(s1, s3, s4);
51747
+ }
51748
+ else {
51749
+ peg$currPos = s0;
51750
+ s0 = peg$FAILED;
51751
+ }
51752
+ }
51753
+ else {
51754
+ peg$currPos = s0;
51755
+ s0 = peg$FAILED;
51756
+ }
51469
51757
  }
51470
51758
  else {
51471
51759
  peg$currPos = s0;
@@ -51478,38 +51766,44 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
51478
51766
  }
51479
51767
  if (s0 === peg$FAILED) {
51480
51768
  s0 = peg$currPos;
51481
- s1 = peg$parsepriority();
51482
- if (s1 === peg$FAILED) {
51483
- s1 = null;
51484
- }
51485
- s2 = peg$parse_();
51486
- if (s2 === peg$FAILED) {
51487
- s2 = null;
51488
- }
51489
- s3 = peg$parseamount();
51490
- if (s3 !== peg$FAILED) {
51491
- s4 = peg$parse_();
51492
- if (s4 !== peg$FAILED) {
51493
- s5 = peg$parserepeatEvery();
51494
- if (s5 !== peg$FAILED) {
51495
- s6 = peg$parse_();
51496
- if (s6 !== peg$FAILED) {
51497
- s7 = peg$parseweekCount();
51498
- if (s7 !== peg$FAILED) {
51499
- s8 = peg$parse_();
51500
- if (s8 !== peg$FAILED) {
51501
- s9 = peg$parsestarting();
51502
- if (s9 !== peg$FAILED) {
51503
- s10 = peg$parse_();
51504
- if (s10 !== peg$FAILED) {
51505
- s11 = peg$parsedate();
51506
- if (s11 !== peg$FAILED) {
51507
- s12 = peg$parselimit();
51508
- if (s12 === peg$FAILED) {
51509
- s12 = null;
51769
+ s1 = peg$parsetemplate();
51770
+ if (s1 !== peg$FAILED) {
51771
+ s2 = peg$parse_();
51772
+ if (s2 !== peg$FAILED) {
51773
+ s3 = peg$parseamount();
51774
+ if (s3 !== peg$FAILED) {
51775
+ s4 = peg$parse_();
51776
+ if (s4 !== peg$FAILED) {
51777
+ s5 = peg$parserepeatEvery();
51778
+ if (s5 !== peg$FAILED) {
51779
+ s6 = peg$parse_();
51780
+ if (s6 !== peg$FAILED) {
51781
+ s7 = peg$parseweekCount();
51782
+ if (s7 !== peg$FAILED) {
51783
+ s8 = peg$parse_();
51784
+ if (s8 !== peg$FAILED) {
51785
+ s9 = peg$parsestarting();
51786
+ if (s9 !== peg$FAILED) {
51787
+ s10 = peg$parse_();
51788
+ if (s10 !== peg$FAILED) {
51789
+ s11 = peg$parsedate();
51790
+ if (s11 !== peg$FAILED) {
51791
+ s12 = peg$parselimit();
51792
+ if (s12 === peg$FAILED) {
51793
+ s12 = null;
51794
+ }
51795
+ peg$savedPos = s0;
51796
+ s0 = peg$f1(s1, s3, s7, s11, s12);
51797
+ }
51798
+ else {
51799
+ peg$currPos = s0;
51800
+ s0 = peg$FAILED;
51801
+ }
51802
+ }
51803
+ else {
51804
+ peg$currPos = s0;
51805
+ s0 = peg$FAILED;
51510
51806
  }
51511
- peg$savedPos = s0;
51512
- s0 = peg$f1(s1, s3, s7, s11, s12);
51513
51807
  }
51514
51808
  else {
51515
51809
  peg$currPos = s0;
@@ -51557,39 +51851,45 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
51557
51851
  }
51558
51852
  if (s0 === peg$FAILED) {
51559
51853
  s0 = peg$currPos;
51560
- s1 = peg$parsepriority();
51561
- if (s1 === peg$FAILED) {
51562
- s1 = null;
51563
- }
51564
- s2 = peg$parse_();
51565
- if (s2 === peg$FAILED) {
51566
- s2 = null;
51567
- }
51568
- s3 = peg$parseamount();
51569
- if (s3 !== peg$FAILED) {
51570
- s4 = peg$parse_();
51571
- if (s4 !== peg$FAILED) {
51572
- s5 = peg$parseby();
51573
- if (s5 !== peg$FAILED) {
51574
- s6 = peg$parse_();
51575
- if (s6 !== peg$FAILED) {
51576
- s7 = peg$parsemonth();
51577
- if (s7 !== peg$FAILED) {
51578
- s8 = peg$parsespendFrom();
51579
- if (s8 === peg$FAILED) {
51580
- s8 = null;
51581
- }
51582
- s9 = peg$currPos;
51583
- s10 = peg$parse_();
51584
- if (s10 !== peg$FAILED) {
51585
- s11 = peg$parserepeatEvery();
51586
- if (s11 !== peg$FAILED) {
51587
- s12 = peg$parse_();
51588
- if (s12 !== peg$FAILED) {
51589
- s13 = peg$parserepeat();
51590
- if (s13 !== peg$FAILED) {
51591
- s10 = [s10, s11, s12, s13];
51592
- s9 = s10;
51854
+ s1 = peg$parsetemplate();
51855
+ if (s1 !== peg$FAILED) {
51856
+ s2 = peg$parse_();
51857
+ if (s2 !== peg$FAILED) {
51858
+ s3 = peg$parseamount();
51859
+ if (s3 !== peg$FAILED) {
51860
+ s4 = peg$parse_();
51861
+ if (s4 !== peg$FAILED) {
51862
+ s5 = peg$parseby();
51863
+ if (s5 !== peg$FAILED) {
51864
+ s6 = peg$parse_();
51865
+ if (s6 !== peg$FAILED) {
51866
+ s7 = peg$parsemonth();
51867
+ if (s7 !== peg$FAILED) {
51868
+ s8 = peg$parsespendFrom();
51869
+ if (s8 === peg$FAILED) {
51870
+ s8 = null;
51871
+ }
51872
+ s9 = peg$currPos;
51873
+ s10 = peg$parse_();
51874
+ if (s10 !== peg$FAILED) {
51875
+ s11 = peg$parserepeatEvery();
51876
+ if (s11 !== peg$FAILED) {
51877
+ s12 = peg$parse_();
51878
+ if (s12 !== peg$FAILED) {
51879
+ s13 = peg$parserepeat();
51880
+ if (s13 !== peg$FAILED) {
51881
+ s10 = [s10, s11, s12, s13];
51882
+ s9 = s10;
51883
+ }
51884
+ else {
51885
+ peg$currPos = s9;
51886
+ s9 = peg$FAILED;
51887
+ }
51888
+ }
51889
+ else {
51890
+ peg$currPos = s9;
51891
+ s9 = peg$FAILED;
51892
+ }
51593
51893
  }
51594
51894
  else {
51595
51895
  peg$currPos = s9;
@@ -51600,21 +51900,21 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
51600
51900
  peg$currPos = s9;
51601
51901
  s9 = peg$FAILED;
51602
51902
  }
51903
+ if (s9 === peg$FAILED) {
51904
+ s9 = null;
51905
+ }
51906
+ peg$savedPos = s0;
51907
+ s0 = peg$f2(s1, s3, s7, s8, s9);
51603
51908
  }
51604
51909
  else {
51605
- peg$currPos = s9;
51606
- s9 = peg$FAILED;
51910
+ peg$currPos = s0;
51911
+ s0 = peg$FAILED;
51607
51912
  }
51608
51913
  }
51609
51914
  else {
51610
- peg$currPos = s9;
51611
- s9 = peg$FAILED;
51612
- }
51613
- if (s9 === peg$FAILED) {
51614
- s9 = null;
51915
+ peg$currPos = s0;
51916
+ s0 = peg$FAILED;
51615
51917
  }
51616
- peg$savedPos = s0;
51617
- s0 = peg$f2(s1, s3, s7, s8, s9);
51618
51918
  }
51619
51919
  else {
51620
51920
  peg$currPos = s0;
@@ -51642,22 +51942,28 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
51642
51942
  }
51643
51943
  if (s0 === peg$FAILED) {
51644
51944
  s0 = peg$currPos;
51645
- s1 = peg$parsepriority();
51646
- if (s1 === peg$FAILED) {
51647
- s1 = null;
51648
- }
51649
- s2 = peg$parse_();
51650
- if (s2 === peg$FAILED) {
51651
- s2 = null;
51652
- }
51653
- s3 = peg$parseamount();
51654
- if (s3 !== peg$FAILED) {
51655
- s4 = peg$parselimit();
51656
- if (s4 === peg$FAILED) {
51657
- s4 = null;
51945
+ s1 = peg$parsetemplate();
51946
+ if (s1 !== peg$FAILED) {
51947
+ s2 = peg$parse_();
51948
+ if (s2 !== peg$FAILED) {
51949
+ s3 = peg$parseamount();
51950
+ if (s3 !== peg$FAILED) {
51951
+ s4 = peg$parselimit();
51952
+ if (s4 === peg$FAILED) {
51953
+ s4 = null;
51954
+ }
51955
+ peg$savedPos = s0;
51956
+ s0 = peg$f3(s1, s3, s4);
51957
+ }
51958
+ else {
51959
+ peg$currPos = s0;
51960
+ s0 = peg$FAILED;
51961
+ }
51962
+ }
51963
+ else {
51964
+ peg$currPos = s0;
51965
+ s0 = peg$FAILED;
51658
51966
  }
51659
- peg$savedPos = s0;
51660
- s0 = peg$f3(s1, s3, s4);
51661
51967
  }
51662
51968
  else {
51663
51969
  peg$currPos = s0;
@@ -51665,18 +51971,24 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
51665
51971
  }
51666
51972
  if (s0 === peg$FAILED) {
51667
51973
  s0 = peg$currPos;
51668
- s1 = peg$parsepriority();
51669
- if (s1 === peg$FAILED) {
51670
- s1 = null;
51671
- }
51672
- s2 = peg$parse_();
51673
- if (s2 === peg$FAILED) {
51674
- s2 = null;
51675
- }
51676
- s3 = peg$parselimit();
51677
- if (s3 !== peg$FAILED) {
51678
- peg$savedPos = s0;
51679
- s0 = peg$f4(s1, s3);
51974
+ s1 = peg$parsetemplate();
51975
+ if (s1 !== peg$FAILED) {
51976
+ s2 = peg$parse_();
51977
+ if (s2 !== peg$FAILED) {
51978
+ s3 = peg$parselimit();
51979
+ if (s3 !== peg$FAILED) {
51980
+ peg$savedPos = s0;
51981
+ s0 = peg$f4(s1, s3);
51982
+ }
51983
+ else {
51984
+ peg$currPos = s0;
51985
+ s0 = peg$FAILED;
51986
+ }
51987
+ }
51988
+ else {
51989
+ peg$currPos = s0;
51990
+ s0 = peg$FAILED;
51991
+ }
51680
51992
  }
51681
51993
  else {
51682
51994
  peg$currPos = s0;
@@ -51684,26 +51996,32 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
51684
51996
  }
51685
51997
  if (s0 === peg$FAILED) {
51686
51998
  s0 = peg$currPos;
51687
- s1 = peg$parsepriority();
51688
- if (s1 === peg$FAILED) {
51689
- s1 = null;
51690
- }
51691
- s2 = peg$parse_();
51692
- if (s2 === peg$FAILED) {
51693
- s2 = null;
51694
- }
51695
- s3 = peg$parseschedule();
51696
- if (s3 !== peg$FAILED) {
51697
- s4 = peg$parse_();
51698
- if (s4 !== peg$FAILED) {
51699
- s5 = peg$parsefull();
51700
- if (s5 === peg$FAILED) {
51701
- s5 = null;
51702
- }
51703
- s6 = peg$parsename();
51704
- if (s6 !== peg$FAILED) {
51705
- peg$savedPos = s0;
51706
- s0 = peg$f5(s1, s5, s6);
51999
+ s1 = peg$parsetemplate();
52000
+ if (s1 !== peg$FAILED) {
52001
+ s2 = peg$parse_();
52002
+ if (s2 !== peg$FAILED) {
52003
+ s3 = peg$parseschedule();
52004
+ if (s3 !== peg$FAILED) {
52005
+ s4 = peg$parse_();
52006
+ if (s4 !== peg$FAILED) {
52007
+ s5 = peg$parsefull();
52008
+ if (s5 === peg$FAILED) {
52009
+ s5 = null;
52010
+ }
52011
+ s6 = peg$parsename();
52012
+ if (s6 !== peg$FAILED) {
52013
+ peg$savedPos = s0;
52014
+ s0 = peg$f5(s1, s5, s6);
52015
+ }
52016
+ else {
52017
+ peg$currPos = s0;
52018
+ s0 = peg$FAILED;
52019
+ }
52020
+ }
52021
+ else {
52022
+ peg$currPos = s0;
52023
+ s0 = peg$FAILED;
52024
+ }
51707
52025
  }
51708
52026
  else {
51709
52027
  peg$currPos = s0;
@@ -51721,18 +52039,28 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
51721
52039
  }
51722
52040
  if (s0 === peg$FAILED) {
51723
52041
  s0 = peg$currPos;
51724
- s1 = peg$parsepriority();
51725
- if (s1 === peg$FAILED) {
51726
- s1 = null;
51727
- }
51728
- s2 = peg$parse_();
51729
- if (s2 === peg$FAILED) {
51730
- s2 = null;
51731
- }
51732
- s3 = peg$parseremainder();
51733
- if (s3 !== peg$FAILED) {
51734
- peg$savedPos = s0;
51735
- s0 = peg$f6(s1, s3);
52042
+ s1 = peg$parsetemplate();
52043
+ if (s1 !== peg$FAILED) {
52044
+ s2 = peg$parse_();
52045
+ if (s2 !== peg$FAILED) {
52046
+ s3 = peg$parseremainder();
52047
+ if (s3 !== peg$FAILED) {
52048
+ s4 = peg$parselimit();
52049
+ if (s4 === peg$FAILED) {
52050
+ s4 = null;
52051
+ }
52052
+ peg$savedPos = s0;
52053
+ s0 = peg$f6(s1, s3, s4);
52054
+ }
52055
+ else {
52056
+ peg$currPos = s0;
52057
+ s0 = peg$FAILED;
52058
+ }
52059
+ }
52060
+ else {
52061
+ peg$currPos = s0;
52062
+ s0 = peg$FAILED;
52063
+ }
51736
52064
  }
51737
52065
  else {
51738
52066
  peg$currPos = s0;
@@ -51740,46 +52068,52 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
51740
52068
  }
51741
52069
  if (s0 === peg$FAILED) {
51742
52070
  s0 = peg$currPos;
51743
- s1 = peg$parsepriority();
51744
- if (s1 === peg$FAILED) {
51745
- s1 = null;
51746
- }
51747
- s2 = peg$parse_();
51748
- if (s2 === peg$FAILED) {
51749
- s2 = null;
51750
- }
51751
- if (input.substr(peg$currPos, 7).toLowerCase() === peg$c0) {
51752
- s3 = input.substr(peg$currPos, 7);
51753
- peg$currPos += 7;
51754
- }
51755
- else {
51756
- s3 = peg$FAILED;
51757
- if (peg$silentFails === 0) {
51758
- peg$fail(peg$e0);
51759
- }
51760
- }
51761
- if (s3 !== peg$FAILED) {
51762
- s4 = peg$parse_();
51763
- if (s4 !== peg$FAILED) {
51764
- s5 = peg$parsepositive();
51765
- if (s5 !== peg$FAILED) {
51766
- s6 = peg$parse_();
51767
- if (s6 !== peg$FAILED) {
51768
- if (input.substr(peg$currPos, 6).toLowerCase() === peg$c1) {
51769
- s7 = input.substr(peg$currPos, 6);
51770
- peg$currPos += 6;
51771
- }
51772
- else {
51773
- s7 = peg$FAILED;
51774
- if (peg$silentFails === 0) {
51775
- peg$fail(peg$e1);
52071
+ s1 = peg$parsetemplate();
52072
+ if (s1 !== peg$FAILED) {
52073
+ s2 = peg$parse_();
52074
+ if (s2 !== peg$FAILED) {
52075
+ if (input.substr(peg$currPos, 7).toLowerCase() === peg$c0) {
52076
+ s3 = input.substr(peg$currPos, 7);
52077
+ peg$currPos += 7;
52078
+ }
52079
+ else {
52080
+ s3 = peg$FAILED;
52081
+ if (peg$silentFails === 0) {
52082
+ peg$fail(peg$e0);
52083
+ }
52084
+ }
52085
+ if (s3 !== peg$FAILED) {
52086
+ s4 = peg$parse_();
52087
+ if (s4 !== peg$FAILED) {
52088
+ s5 = peg$parsepositive();
52089
+ if (s5 !== peg$FAILED) {
52090
+ s6 = peg$parse_();
52091
+ if (s6 !== peg$FAILED) {
52092
+ if (input.substr(peg$currPos, 6).toLowerCase() === peg$c1) {
52093
+ s7 = input.substr(peg$currPos, 6);
52094
+ peg$currPos += 6;
52095
+ }
52096
+ else {
52097
+ s7 = peg$FAILED;
52098
+ if (peg$silentFails === 0) {
52099
+ peg$fail(peg$e1);
52100
+ }
52101
+ }
52102
+ if (s7 === peg$FAILED) {
52103
+ s7 = null;
52104
+ }
52105
+ peg$savedPos = s0;
52106
+ s0 = peg$f7(s1, s5);
52107
+ }
52108
+ else {
52109
+ peg$currPos = s0;
52110
+ s0 = peg$FAILED;
51776
52111
  }
51777
52112
  }
51778
- if (s7 === peg$FAILED) {
51779
- s7 = null;
52113
+ else {
52114
+ peg$currPos = s0;
52115
+ s0 = peg$FAILED;
51780
52116
  }
51781
- peg$savedPos = s0;
51782
- s0 = peg$f7(s1, s5);
51783
52117
  }
51784
52118
  else {
51785
52119
  peg$currPos = s0;
@@ -51800,6 +52134,25 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
51800
52134
  peg$currPos = s0;
51801
52135
  s0 = peg$FAILED;
51802
52136
  }
52137
+ if (s0 === peg$FAILED) {
52138
+ s0 = peg$currPos;
52139
+ s1 = peg$parsegoal();
52140
+ if (s1 !== peg$FAILED) {
52141
+ s2 = peg$parseamount();
52142
+ if (s2 !== peg$FAILED) {
52143
+ peg$savedPos = s0;
52144
+ s0 = peg$f8(s1, s2);
52145
+ }
52146
+ else {
52147
+ peg$currPos = s0;
52148
+ s0 = peg$FAILED;
52149
+ }
52150
+ }
52151
+ else {
52152
+ peg$currPos = s0;
52153
+ s0 = peg$FAILED;
52154
+ }
52155
+ }
51803
52156
  }
51804
52157
  }
51805
52158
  }
@@ -51825,7 +52178,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
51825
52178
  }
51826
52179
  if (s1 !== peg$FAILED) {
51827
52180
  peg$savedPos = s0;
51828
- s1 = peg$f8();
52181
+ s1 = peg$f9();
51829
52182
  }
51830
52183
  s0 = s1;
51831
52184
  if (s0 === peg$FAILED) {
@@ -51846,7 +52199,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
51846
52199
  }
51847
52200
  if (s3 !== peg$FAILED) {
51848
52201
  peg$savedPos = s0;
51849
- s0 = peg$f9(s1);
52202
+ s0 = peg$f10(s1);
51850
52203
  }
51851
52204
  else {
51852
52205
  peg$currPos = s0;
@@ -51876,7 +52229,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
51876
52229
  }
51877
52230
  if (s1 !== peg$FAILED) {
51878
52231
  peg$savedPos = s0;
51879
- s1 = peg$f10();
52232
+ s1 = peg$f11();
51880
52233
  }
51881
52234
  s0 = s1;
51882
52235
  if (s0 === peg$FAILED) {
@@ -51897,7 +52250,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
51897
52250
  }
51898
52251
  if (s3 !== peg$FAILED) {
51899
52252
  peg$savedPos = s0;
51900
- s0 = peg$f11(s1);
52253
+ s0 = peg$f12(s1);
51901
52254
  }
51902
52255
  else {
51903
52256
  peg$currPos = s0;
@@ -51952,7 +52305,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
51952
52305
  }
51953
52306
  if (s6 !== peg$FAILED) {
51954
52307
  peg$savedPos = s0;
51955
- s0 = peg$f12(s4);
52308
+ s0 = peg$f13(s4);
51956
52309
  }
51957
52310
  else {
51958
52311
  peg$currPos = s0;
@@ -51991,7 +52344,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
51991
52344
  s4 = peg$parseamount();
51992
52345
  if (s4 !== peg$FAILED) {
51993
52346
  peg$savedPos = s0;
51994
- s0 = peg$f13(s4);
52347
+ s0 = peg$f14(s4);
51995
52348
  }
51996
52349
  else {
51997
52350
  peg$currPos = s0;
@@ -52035,7 +52388,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
52035
52388
  s6 = peg$parse_();
52036
52389
  if (s6 !== peg$FAILED) {
52037
52390
  peg$savedPos = s0;
52038
- s0 = peg$f14(s1);
52391
+ s0 = peg$f15(s1);
52039
52392
  }
52040
52393
  else {
52041
52394
  peg$currPos = s0;
@@ -52077,7 +52430,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
52077
52430
  s4 = peg$parse_();
52078
52431
  if (s4 !== peg$FAILED) {
52079
52432
  peg$savedPos = s0;
52080
- s0 = peg$f15(s1);
52433
+ s0 = peg$f16(s1);
52081
52434
  }
52082
52435
  else {
52083
52436
  peg$currPos = s0;
@@ -52107,7 +52460,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
52107
52460
  s1 = peg$parseweek();
52108
52461
  if (s1 !== peg$FAILED) {
52109
52462
  peg$savedPos = s0;
52110
- s1 = peg$f16();
52463
+ s1 = peg$f17();
52111
52464
  }
52112
52465
  s0 = s1;
52113
52466
  if (s0 === peg$FAILED) {
@@ -52119,7 +52472,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
52119
52472
  s3 = peg$parseweeks();
52120
52473
  if (s3 !== peg$FAILED) {
52121
52474
  peg$savedPos = s0;
52122
- s0 = peg$f17(s1);
52475
+ s0 = peg$f18(s1);
52123
52476
  }
52124
52477
  else {
52125
52478
  peg$currPos = s0;
@@ -52172,7 +52525,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
52172
52525
  s6 = peg$parsemonth();
52173
52526
  if (s6 !== peg$FAILED) {
52174
52527
  peg$savedPos = s0;
52175
- s0 = peg$f18(s6);
52528
+ s0 = peg$f19(s6);
52176
52529
  }
52177
52530
  else {
52178
52531
  peg$currPos = s0;
@@ -52398,7 +52751,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
52398
52751
  s2 = peg$parse_();
52399
52752
  if (s2 !== peg$FAILED) {
52400
52753
  peg$savedPos = s0;
52401
- s0 = peg$f19();
52754
+ s0 = peg$f20();
52402
52755
  }
52403
52756
  else {
52404
52757
  peg$currPos = s0;
@@ -52412,7 +52765,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
52412
52765
  return s0;
52413
52766
  }
52414
52767
  function peg$parsepriority() {
52415
- var s0, s1, s2, s3;
52768
+ var s0, s1, s2;
52416
52769
  s0 = peg$currPos;
52417
52770
  if (input.substr(peg$currPos, 1).toLowerCase() === peg$c20) {
52418
52771
  s1 = input.charAt(peg$currPos);
@@ -52427,15 +52780,8 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
52427
52780
  if (s1 !== peg$FAILED) {
52428
52781
  s2 = peg$parsenumber();
52429
52782
  if (s2 !== peg$FAILED) {
52430
- s3 = peg$parse_();
52431
- if (s3 !== peg$FAILED) {
52432
- peg$savedPos = s0;
52433
- s0 = peg$f20(s2);
52434
- }
52435
- else {
52436
- peg$currPos = s0;
52437
- s0 = peg$FAILED;
52438
- }
52783
+ peg$savedPos = s0;
52784
+ s0 = peg$f21(s2);
52439
52785
  }
52440
52786
  else {
52441
52787
  peg$currPos = s0;
@@ -52471,7 +52817,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
52471
52817
  s3 = null;
52472
52818
  }
52473
52819
  peg$savedPos = s0;
52474
- s0 = peg$f21(s3);
52820
+ s0 = peg$f22(s3);
52475
52821
  }
52476
52822
  else {
52477
52823
  peg$currPos = s0;
@@ -52479,31 +52825,72 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
52479
52825
  }
52480
52826
  return s0;
52481
52827
  }
52828
+ function peg$parsetemplate() {
52829
+ var s0, s1, s2;
52830
+ s0 = peg$currPos;
52831
+ if (input.substr(peg$currPos, 9) === peg$c22) {
52832
+ s1 = peg$c22;
52833
+ peg$currPos += 9;
52834
+ }
52835
+ else {
52836
+ s1 = peg$FAILED;
52837
+ if (peg$silentFails === 0) {
52838
+ peg$fail(peg$e23);
52839
+ }
52840
+ }
52841
+ if (s1 !== peg$FAILED) {
52842
+ s2 = peg$parsepriority();
52843
+ if (s2 === peg$FAILED) {
52844
+ s2 = null;
52845
+ }
52846
+ peg$savedPos = s0;
52847
+ s0 = peg$f23(s2);
52848
+ }
52849
+ else {
52850
+ peg$currPos = s0;
52851
+ s0 = peg$FAILED;
52852
+ }
52853
+ return s0;
52854
+ }
52855
+ function peg$parsegoal() {
52856
+ var s0;
52857
+ if (input.substr(peg$currPos, 5) === peg$c23) {
52858
+ s0 = peg$c23;
52859
+ peg$currPos += 5;
52860
+ }
52861
+ else {
52862
+ s0 = peg$FAILED;
52863
+ if (peg$silentFails === 0) {
52864
+ peg$fail(peg$e24);
52865
+ }
52866
+ }
52867
+ return s0;
52868
+ }
52482
52869
  function peg$parse_() {
52483
52870
  var s0, s1;
52484
52871
  peg$silentFails++;
52485
52872
  s0 = [];
52486
52873
  if (input.charCodeAt(peg$currPos) === 32) {
52487
- s1 = peg$c22;
52874
+ s1 = peg$c24;
52488
52875
  peg$currPos++;
52489
52876
  }
52490
52877
  else {
52491
52878
  s1 = peg$FAILED;
52492
52879
  if (peg$silentFails === 0) {
52493
- peg$fail(peg$e24);
52880
+ peg$fail(peg$e26);
52494
52881
  }
52495
52882
  }
52496
52883
  if (s1 !== peg$FAILED) {
52497
52884
  while (s1 !== peg$FAILED) {
52498
52885
  s0.push(s1);
52499
52886
  if (input.charCodeAt(peg$currPos) === 32) {
52500
- s1 = peg$c22;
52887
+ s1 = peg$c24;
52501
52888
  peg$currPos++;
52502
52889
  }
52503
52890
  else {
52504
52891
  s1 = peg$FAILED;
52505
52892
  if (peg$silentFails === 0) {
52506
- peg$fail(peg$e24);
52893
+ peg$fail(peg$e26);
52507
52894
  }
52508
52895
  }
52509
52896
  }
@@ -52515,7 +52902,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
52515
52902
  if (s0 === peg$FAILED) {
52516
52903
  s1 = peg$FAILED;
52517
52904
  if (peg$silentFails === 0) {
52518
- peg$fail(peg$e23);
52905
+ peg$fail(peg$e25);
52519
52906
  }
52520
52907
  }
52521
52908
  return s0;
@@ -52530,14 +52917,14 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
52530
52917
  else {
52531
52918
  s0 = peg$FAILED;
52532
52919
  if (peg$silentFails === 0) {
52533
- peg$fail(peg$e26);
52920
+ peg$fail(peg$e28);
52534
52921
  }
52535
52922
  }
52536
52923
  peg$silentFails--;
52537
52924
  if (s0 === peg$FAILED) {
52538
52925
  s1 = peg$FAILED;
52539
52926
  if (peg$silentFails === 0) {
52540
- peg$fail(peg$e25);
52927
+ peg$fail(peg$e27);
52541
52928
  }
52542
52929
  }
52543
52930
  return s0;
@@ -52567,7 +52954,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
52567
52954
  if (s0 === peg$FAILED) {
52568
52955
  s1 = peg$FAILED;
52569
52956
  if (peg$silentFails === 0) {
52570
- peg$fail(peg$e27);
52957
+ peg$fail(peg$e29);
52571
52958
  }
52572
52959
  }
52573
52960
  return s0;
@@ -52583,7 +52970,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
52583
52970
  else {
52584
52971
  s2 = peg$FAILED;
52585
52972
  if (peg$silentFails === 0) {
52586
- peg$fail(peg$e28);
52973
+ peg$fail(peg$e30);
52587
52974
  }
52588
52975
  }
52589
52976
  if (s2 !== peg$FAILED) {
@@ -52595,7 +52982,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
52595
52982
  else {
52596
52983
  s4 = peg$FAILED;
52597
52984
  if (peg$silentFails === 0) {
52598
- peg$fail(peg$e26);
52985
+ peg$fail(peg$e28);
52599
52986
  }
52600
52987
  }
52601
52988
  while (s4 !== peg$FAILED) {
@@ -52607,7 +52994,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
52607
52994
  else {
52608
52995
  s4 = peg$FAILED;
52609
52996
  if (peg$silentFails === 0) {
52610
- peg$fail(peg$e26);
52997
+ peg$fail(peg$e28);
52611
52998
  }
52612
52999
  }
52613
53000
  }
@@ -52654,13 +53041,13 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
52654
53041
  if (s5 !== peg$FAILED) {
52655
53042
  s6 = peg$currPos;
52656
53043
  if (input.charCodeAt(peg$currPos) === 46) {
52657
- s7 = peg$c23;
53044
+ s7 = peg$c25;
52658
53045
  peg$currPos++;
52659
53046
  }
52660
53047
  else {
52661
53048
  s7 = peg$FAILED;
52662
53049
  if (peg$silentFails === 0) {
52663
- peg$fail(peg$e30);
53050
+ peg$fail(peg$e32);
52664
53051
  }
52665
53052
  }
52666
53053
  if (s7 !== peg$FAILED) {
@@ -52706,7 +53093,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
52706
53093
  }
52707
53094
  if (s3 !== peg$FAILED) {
52708
53095
  peg$savedPos = s0;
52709
- s0 = peg$f22(s3);
53096
+ s0 = peg$f24(s3);
52710
53097
  }
52711
53098
  else {
52712
53099
  peg$currPos = s0;
@@ -52716,7 +53103,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
52716
53103
  if (s0 === peg$FAILED) {
52717
53104
  s1 = peg$FAILED;
52718
53105
  if (peg$silentFails === 0) {
52719
- peg$fail(peg$e29);
53106
+ peg$fail(peg$e31);
52720
53107
  }
52721
53108
  }
52722
53109
  return s0;
@@ -52741,13 +53128,13 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
52741
53128
  if (s3 !== peg$FAILED) {
52742
53129
  s4 = peg$currPos;
52743
53130
  if (input.charCodeAt(peg$currPos) === 46) {
52744
- s5 = peg$c23;
53131
+ s5 = peg$c25;
52745
53132
  peg$currPos++;
52746
53133
  }
52747
53134
  else {
52748
53135
  s5 = peg$FAILED;
52749
53136
  if (peg$silentFails === 0) {
52750
- peg$fail(peg$e30);
53137
+ peg$fail(peg$e32);
52751
53138
  }
52752
53139
  }
52753
53140
  if (s5 !== peg$FAILED) {
@@ -52794,18 +53181,18 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
52794
53181
  s2 = null;
52795
53182
  }
52796
53183
  if (input.charCodeAt(peg$currPos) === 37) {
52797
- s3 = peg$c24;
53184
+ s3 = peg$c26;
52798
53185
  peg$currPos++;
52799
53186
  }
52800
53187
  else {
52801
53188
  s3 = peg$FAILED;
52802
53189
  if (peg$silentFails === 0) {
52803
- peg$fail(peg$e32);
53190
+ peg$fail(peg$e34);
52804
53191
  }
52805
53192
  }
52806
53193
  if (s3 !== peg$FAILED) {
52807
53194
  peg$savedPos = s0;
52808
- s0 = peg$f23(s1);
53195
+ s0 = peg$f25(s1);
52809
53196
  }
52810
53197
  else {
52811
53198
  peg$currPos = s0;
@@ -52820,7 +53207,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
52820
53207
  if (s0 === peg$FAILED) {
52821
53208
  s1 = peg$FAILED;
52822
53209
  if (peg$silentFails === 0) {
52823
- peg$fail(peg$e31);
53210
+ peg$fail(peg$e33);
52824
53211
  }
52825
53212
  }
52826
53213
  return s0;
@@ -52870,7 +53257,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
52870
53257
  if (s0 === peg$FAILED) {
52871
53258
  s1 = peg$FAILED;
52872
53259
  if (peg$silentFails === 0) {
52873
- peg$fail(peg$e33);
53260
+ peg$fail(peg$e35);
52874
53261
  }
52875
53262
  }
52876
53263
  return s0;
@@ -52889,7 +53276,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
52889
53276
  else {
52890
53277
  s3 = peg$FAILED;
52891
53278
  if (peg$silentFails === 0) {
52892
- peg$fail(peg$e35);
53279
+ peg$fail(peg$e37);
52893
53280
  }
52894
53281
  }
52895
53282
  if (s3 !== peg$FAILED) {
@@ -52929,7 +53316,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
52929
53316
  if (s0 === peg$FAILED) {
52930
53317
  s1 = peg$FAILED;
52931
53318
  if (peg$silentFails === 0) {
52932
- peg$fail(peg$e34);
53319
+ peg$fail(peg$e36);
52933
53320
  }
52934
53321
  }
52935
53322
  return s0;
@@ -52965,7 +53352,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
52965
53352
  if (s0 === peg$FAILED) {
52966
53353
  s1 = peg$FAILED;
52967
53354
  if (peg$silentFails === 0) {
52968
- peg$fail(peg$e36);
53355
+ peg$fail(peg$e38);
52969
53356
  }
52970
53357
  }
52971
53358
  return s0;
@@ -52983,7 +53370,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
52983
53370
  else {
52984
53371
  s3 = peg$FAILED;
52985
53372
  if (peg$silentFails === 0) {
52986
- peg$fail(peg$e35);
53373
+ peg$fail(peg$e37);
52987
53374
  }
52988
53375
  }
52989
53376
  if (s3 !== peg$FAILED) {
@@ -53025,12 +53412,12 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
53025
53412
  else {
53026
53413
  s1 = peg$FAILED;
53027
53414
  if (peg$silentFails === 0) {
53028
- peg$fail(peg$e38);
53415
+ peg$fail(peg$e40);
53029
53416
  }
53030
53417
  }
53031
53418
  if (s1 !== peg$FAILED) {
53032
53419
  peg$savedPos = peg$currPos;
53033
- s2 = peg$f24(s1);
53420
+ s2 = peg$f26(s1);
53034
53421
  if (s2) {
53035
53422
  s2 = undefined;
53036
53423
  }
@@ -53054,7 +53441,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
53054
53441
  if (s0 === peg$FAILED) {
53055
53442
  s1 = peg$FAILED;
53056
53443
  if (peg$silentFails === 0) {
53057
- peg$fail(peg$e37);
53444
+ peg$fail(peg$e39);
53058
53445
  }
53059
53446
  }
53060
53447
  return s0;
@@ -53071,7 +53458,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
53071
53458
  else {
53072
53459
  s2 = peg$FAILED;
53073
53460
  if (peg$silentFails === 0) {
53074
- peg$fail(peg$e40);
53461
+ peg$fail(peg$e42);
53075
53462
  }
53076
53463
  }
53077
53464
  if (s2 !== peg$FAILED) {
@@ -53084,7 +53471,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
53084
53471
  else {
53085
53472
  s2 = peg$FAILED;
53086
53473
  if (peg$silentFails === 0) {
53087
- peg$fail(peg$e40);
53474
+ peg$fail(peg$e42);
53088
53475
  }
53089
53476
  }
53090
53477
  }
@@ -53102,7 +53489,7 @@ CREATE TABLE kvcache_key (id INTEGER PRIMARY KEY, key REAL);
53102
53489
  if (s0 === peg$FAILED) {
53103
53490
  s1 = peg$FAILED;
53104
53491
  if (peg$silentFails === 0) {
53105
- peg$fail(peg$e39);
53492
+ peg$fail(peg$e41);
53106
53493
  }
53107
53494
  }
53108
53495
  return s0;