@actual-app/api 4.1.6 → 5.0.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.
package/app/bundle.api.js CHANGED
@@ -39849,6 +39849,15 @@ async function loadBudget(budgetId) {
39849
39849
  });
39850
39850
  }
39851
39851
 
39852
+ async function downloadBudget(syncId, {
39853
+ password
39854
+ } = {}) {
39855
+ return send('api/download-budget', {
39856
+ syncId,
39857
+ password
39858
+ });
39859
+ }
39860
+
39852
39861
  async function batchBudgetUpdates(func) {
39853
39862
  await send('api/batch-budget-start');
39854
39863
 
@@ -40077,6 +40086,7 @@ module.exports = {
40077
40086
  runQuery,
40078
40087
  q,
40079
40088
  loadBudget,
40089
+ downloadBudget,
40080
40090
  batchBudgetUpdates,
40081
40091
  getBudgetMonths,
40082
40092
  getBudgetMonth,
@@ -42644,7 +42654,7 @@ async function parseOFX(filepath) {
42644
42654
 
42645
42655
  await initModule();
42646
42656
  let errors = [];
42647
- let contents = await _platform_server_fs__WEBPACK_IMPORTED_MODULE_1___default.a.readFile(filepath);
42657
+ let contents = await _platform_server_fs__WEBPACK_IMPORTED_MODULE_1___default.a.readFile(filepath, 'binary');
42648
42658
  let data;
42649
42659
 
42650
42660
  try {
@@ -45709,20 +45719,21 @@ const payeeRuleModel = _objectSpread(_objectSpread({}, _models__WEBPACK_IMPORTED
45709
45719
 
45710
45720
  "use strict";
45711
45721
  __webpack_require__.r(__webpack_exports__);
45712
- /* harmony import */ var _shared_months__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../shared/months */ "./packages/loot-core/src/shared/months.js");
45713
- /* harmony import */ var _shared_query__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../shared/query */ "./packages/loot-core/src/shared/query.js");
45714
- /* harmony import */ var _shared_transactions__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../shared/transactions */ "./packages/loot-core/src/shared/transactions.js");
45715
- /* harmony import */ var _shared_util__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../shared/util */ "./packages/loot-core/src/shared/util.js");
45716
- /* harmony import */ var _accounts_sync__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./accounts/sync */ "./packages/loot-core/src/server/accounts/sync.js");
45717
- /* harmony import */ var _api_models__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./api-models */ "./packages/loot-core/src/server/api-models.js");
45718
- /* harmony import */ var _aql__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./aql */ "./packages/loot-core/src/server/aql/index.js");
45719
- /* harmony import */ var _cloud_storage__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./cloud-storage */ "./packages/loot-core/src/server/cloud-storage.js");
45720
- /* harmony import */ var _crdt__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./crdt */ "./packages/loot-core/src/server/crdt/index.js");
45721
- /* harmony import */ var _db__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./db */ "./packages/loot-core/src/server/db/index.js");
45722
- /* harmony import */ var _mutators__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./mutators */ "./packages/loot-core/src/server/mutators.js");
45723
- /* harmony import */ var _prefs__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./prefs */ "./packages/loot-core/src/server/prefs.js");
45724
- /* harmony import */ var _sheet__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./sheet */ "./packages/loot-core/src/server/sheet.js");
45725
- /* harmony import */ var _sync__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./sync */ "./packages/loot-core/src/server/sync/index.js");
45722
+ /* harmony import */ var _shared_errors__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../shared/errors */ "./packages/loot-core/src/shared/errors.js");
45723
+ /* harmony import */ var _shared_months__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../shared/months */ "./packages/loot-core/src/shared/months.js");
45724
+ /* harmony import */ var _shared_query__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../shared/query */ "./packages/loot-core/src/shared/query.js");
45725
+ /* harmony import */ var _shared_transactions__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../shared/transactions */ "./packages/loot-core/src/shared/transactions.js");
45726
+ /* harmony import */ var _shared_util__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../shared/util */ "./packages/loot-core/src/shared/util.js");
45727
+ /* harmony import */ var _accounts_sync__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./accounts/sync */ "./packages/loot-core/src/server/accounts/sync.js");
45728
+ /* harmony import */ var _api_models__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./api-models */ "./packages/loot-core/src/server/api-models.js");
45729
+ /* harmony import */ var _aql__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./aql */ "./packages/loot-core/src/server/aql/index.js");
45730
+ /* harmony import */ var _cloud_storage__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./cloud-storage */ "./packages/loot-core/src/server/cloud-storage.js");
45731
+ /* harmony import */ var _crdt__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./crdt */ "./packages/loot-core/src/server/crdt/index.js");
45732
+ /* harmony import */ var _db__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./db */ "./packages/loot-core/src/server/db/index.js");
45733
+ /* harmony import */ var _mutators__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./mutators */ "./packages/loot-core/src/server/mutators.js");
45734
+ /* harmony import */ var _prefs__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./prefs */ "./packages/loot-core/src/server/prefs.js");
45735
+ /* harmony import */ var _sheet__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./sheet */ "./packages/loot-core/src/server/sheet.js");
45736
+ /* harmony import */ var _sync__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./sync */ "./packages/loot-core/src/server/sync/index.js");
45726
45737
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
45727
45738
 
45728
45739
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
@@ -45744,6 +45755,7 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
45744
45755
 
45745
45756
 
45746
45757
 
45758
+
45747
45759
  const connection = __webpack_require__(/*! ../platform/server/connection */ "./packages/loot-core/src/platform/server/connection/index.api.js");
45748
45760
 
45749
45761
  let IMPORT_MODE = false; // This is duplicate from main.js...
@@ -45762,10 +45774,10 @@ function APIError(msg, meta) {
45762
45774
 
45763
45775
  function withMutation(handler) {
45764
45776
  return args => {
45765
- return Object(_mutators__WEBPACK_IMPORTED_MODULE_10__["runMutator"])(async () => {
45766
- let latestTimestamp = Object(_crdt__WEBPACK_IMPORTED_MODULE_8__["getClock"])().timestamp.toString();
45777
+ return Object(_mutators__WEBPACK_IMPORTED_MODULE_11__["runMutator"])(async () => {
45778
+ let latestTimestamp = Object(_crdt__WEBPACK_IMPORTED_MODULE_9__["getClock"])().timestamp.toString();
45767
45779
  let result = await handler(args);
45768
- let rows = await _db__WEBPACK_IMPORTED_MODULE_9__["all"]('SELECT DISTINCT dataset FROM messages_crdt WHERE timestamp > ?', [latestTimestamp]); // Only send the sync event if anybody else is connected
45780
+ let rows = await _db__WEBPACK_IMPORTED_MODULE_10__["all"]('SELECT DISTINCT dataset FROM messages_crdt WHERE timestamp > ?', [latestTimestamp]); // Only send the sync event if anybody else is connected
45769
45781
 
45770
45782
  if (connection.getNumClients() > 1) {
45771
45783
  connection.send('sync-event', {
@@ -45793,7 +45805,7 @@ async function validateMonth(month) {
45793
45805
  start = _await$handlers$getB.start,
45794
45806
  end = _await$handlers$getB.end;
45795
45807
 
45796
- let range = _shared_months__WEBPACK_IMPORTED_MODULE_0__["range"](start, end);
45808
+ let range = _shared_months__WEBPACK_IMPORTED_MODULE_1__["range"](start, end);
45797
45809
 
45798
45810
  if (!range.includes(month)) {
45799
45811
  throw APIError('No budget exists for month: ' + month);
@@ -45806,7 +45818,7 @@ async function validateExpenseCategory(debug, id) {
45806
45818
  throw APIError(`${debug}: category id is required`);
45807
45819
  }
45808
45820
 
45809
- let row = await _db__WEBPACK_IMPORTED_MODULE_9__["first"]('SELECT is_income FROM categories WHERE id = ?', [id]);
45821
+ let row = await _db__WEBPACK_IMPORTED_MODULE_10__["first"]('SELECT is_income FROM categories WHERE id = ?', [id]);
45810
45822
 
45811
45823
  if (!row) {
45812
45824
  throw APIError(`${debug}: category "${id}" does not exist`);
@@ -45828,7 +45840,7 @@ handlers['api/batch-budget-start'] = async function () {
45828
45840
 
45829
45841
 
45830
45842
  if (IMPORT_MODE) {
45831
- _db__WEBPACK_IMPORTED_MODULE_9__["asyncTransaction"](() => {
45843
+ _db__WEBPACK_IMPORTED_MODULE_10__["asyncTransaction"](() => {
45832
45844
  return new Promise((resolve, reject) => {
45833
45845
  batchPromise = {
45834
45846
  resolve,
@@ -45837,7 +45849,7 @@ handlers['api/batch-budget-start'] = async function () {
45837
45849
  });
45838
45850
  });
45839
45851
  } else {
45840
- Object(_sync__WEBPACK_IMPORTED_MODULE_13__["batchMessages"])(() => {
45852
+ Object(_sync__WEBPACK_IMPORTED_MODULE_14__["batchMessages"])(() => {
45841
45853
  return new Promise((resolve, reject) => {
45842
45854
  batchPromise = {
45843
45855
  resolve,
@@ -45860,7 +45872,7 @@ handlers['api/batch-budget-end'] = async function () {
45860
45872
  handlers['api/load-budget'] = async function ({
45861
45873
  id
45862
45874
  }) {
45863
- let _ref = _prefs__WEBPACK_IMPORTED_MODULE_11__["getPrefs"]() || {},
45875
+ let _ref = _prefs__WEBPACK_IMPORTED_MODULE_12__["getPrefs"]() || {},
45864
45876
  currentId = _ref.id;
45865
45877
 
45866
45878
  if (currentId !== id) {
@@ -45875,15 +45887,69 @@ handlers['api/load-budget'] = async function ({
45875
45887
  connection.send('finish-load');
45876
45888
  } else {
45877
45889
  connection.send('show-budgets');
45890
+ throw new Error(Object(_shared_errors__WEBPACK_IMPORTED_MODULE_0__["getSyncError"])(error, id));
45891
+ }
45892
+ }
45893
+ };
45878
45894
 
45879
- if (error === 'out-of-sync-migrations' || error === 'out-of-sync-data') {
45880
- throw new Error('This budget cannot be loaded with this version of the app.');
45881
- } else if (error === 'budget-not-found') {
45882
- throw new Error('Budget "' + id + '" not found. Check the id of your budget in the "Advanced" section of the settings page.');
45883
- } else {
45884
- throw new Error('We had an unknown problem opening "' + id + '".');
45895
+ handlers['api/download-budget'] = async function ({
45896
+ syncId,
45897
+ password
45898
+ }) {
45899
+ let _ref2 = _prefs__WEBPACK_IMPORTED_MODULE_12__["getPrefs"]() || {},
45900
+ currentId = _ref2.id;
45901
+
45902
+ if (currentId) {
45903
+ await handlers['close-budget']();
45904
+ }
45905
+
45906
+ let localBudget = (await handlers['get-budgets']()).find(b => b.groupId === syncId);
45907
+
45908
+ if (localBudget) {
45909
+ await handlers['load-budget']({
45910
+ id: localBudget.id
45911
+ });
45912
+ let result = await handlers['sync-budget']({
45913
+ id: localBudget.id
45914
+ });
45915
+
45916
+ if (result.error) {
45917
+ throw new Error(Object(_shared_errors__WEBPACK_IMPORTED_MODULE_0__["getSyncError"])(result.error, localBudget.id));
45918
+ }
45919
+ } else {
45920
+ let files = await handlers['get-remote-files']();
45921
+ let file = files.find(f => f.groupId === syncId);
45922
+
45923
+ if (!file) {
45924
+ throw new Error(`Budget "${syncId}" not found. Check the sync id of your budget in the "Advanced" section of the settings page.`);
45925
+ }
45926
+
45927
+ if (file.encryptKeyId && !password) {
45928
+ throw new Error(`File ${file.name} is encrypted. Please provide a password.`);
45929
+ }
45930
+
45931
+ if (password) {
45932
+ let result = await handlers['key-test']({
45933
+ fileId: file.fileId,
45934
+ password
45935
+ });
45936
+
45937
+ if (result.error) {
45938
+ throw new Error(Object(_shared_errors__WEBPACK_IMPORTED_MODULE_0__["getTestKeyError"])(result.error));
45885
45939
  }
45886
45940
  }
45941
+
45942
+ let result = await handlers['download-budget']({
45943
+ fileId: file.fileId
45944
+ });
45945
+
45946
+ if (result.error) {
45947
+ throw new Error(Object(_shared_errors__WEBPACK_IMPORTED_MODULE_0__["getDownloadError"])(result.error, result.id));
45948
+ }
45949
+
45950
+ await handlers['load-budget']({
45951
+ id: result.id
45952
+ });
45887
45953
  }
45888
45954
  };
45889
45955
 
@@ -45898,20 +45964,20 @@ handlers['api/start-import'] = async function ({
45898
45964
  avoidUpload: true
45899
45965
  }); // Clear out the default expense categories
45900
45966
 
45901
- await _db__WEBPACK_IMPORTED_MODULE_9__["runQuery"]('DELETE FROM categories WHERE is_income = 0');
45902
- await _db__WEBPACK_IMPORTED_MODULE_9__["runQuery"]('DELETE FROM category_groups WHERE is_income = 0'); // Turn syncing off
45967
+ await _db__WEBPACK_IMPORTED_MODULE_10__["runQuery"]('DELETE FROM categories WHERE is_income = 0');
45968
+ await _db__WEBPACK_IMPORTED_MODULE_10__["runQuery"]('DELETE FROM category_groups WHERE is_income = 0'); // Turn syncing off
45903
45969
 
45904
- Object(_sync__WEBPACK_IMPORTED_MODULE_13__["setSyncingMode"])('import');
45970
+ Object(_sync__WEBPACK_IMPORTED_MODULE_14__["setSyncingMode"])('import');
45905
45971
  connection.send('start-import');
45906
45972
  IMPORT_MODE = true;
45907
45973
  };
45908
45974
 
45909
45975
  handlers['api/finish-import'] = async function () {
45910
- _sheet__WEBPACK_IMPORTED_MODULE_12__["get"]().markCacheDirty(); // We always need to fully reload the app. Importing doesn't touch
45976
+ _sheet__WEBPACK_IMPORTED_MODULE_13__["get"]().markCacheDirty(); // We always need to fully reload the app. Importing doesn't touch
45911
45977
  // the spreadsheet, but we can't just recreate the spreadsheet
45912
45978
  // either; there is other internal state that isn't created
45913
45979
 
45914
- let _prefs$getPrefs = _prefs__WEBPACK_IMPORTED_MODULE_11__["getPrefs"](),
45980
+ let _prefs$getPrefs = _prefs__WEBPACK_IMPORTED_MODULE_12__["getPrefs"](),
45915
45981
  id = _prefs$getPrefs.id;
45916
45982
 
45917
45983
  await handlers['close-budget']();
@@ -45919,15 +45985,15 @@ handlers['api/finish-import'] = async function () {
45919
45985
  id
45920
45986
  });
45921
45987
  await handlers['get-budget-bounds']();
45922
- await _sheet__WEBPACK_IMPORTED_MODULE_12__["waitOnSpreadsheet"]();
45923
- await _cloud_storage__WEBPACK_IMPORTED_MODULE_7__["upload"]().catch(err => {});
45988
+ await _sheet__WEBPACK_IMPORTED_MODULE_13__["waitOnSpreadsheet"]();
45989
+ await _cloud_storage__WEBPACK_IMPORTED_MODULE_8__["upload"]().catch(err => {});
45924
45990
  connection.send('finish-import');
45925
45991
  IMPORT_MODE = false;
45926
45992
  };
45927
45993
 
45928
45994
  handlers['api/abort-import'] = async function () {
45929
45995
  if (IMPORT_MODE) {
45930
- let _prefs$getPrefs2 = _prefs__WEBPACK_IMPORTED_MODULE_11__["getPrefs"](),
45996
+ let _prefs$getPrefs2 = _prefs__WEBPACK_IMPORTED_MODULE_12__["getPrefs"](),
45931
45997
  id = _prefs$getPrefs2.id;
45932
45998
 
45933
45999
  await handlers['close-budget']();
@@ -45943,7 +46009,7 @@ handlers['api/abort-import'] = async function () {
45943
46009
  handlers['api/query'] = async function ({
45944
46010
  query
45945
46011
  }) {
45946
- return Object(_aql__WEBPACK_IMPORTED_MODULE_6__["runQuery"])(query);
46012
+ return Object(_aql__WEBPACK_IMPORTED_MODULE_7__["runQuery"])(query);
45947
46013
  };
45948
46014
 
45949
46015
  handlers['api/budget-months'] = async function () {
@@ -45951,18 +46017,18 @@ handlers['api/budget-months'] = async function () {
45951
46017
  start = _await$handlers$getB2.start,
45952
46018
  end = _await$handlers$getB2.end;
45953
46019
 
45954
- return _shared_months__WEBPACK_IMPORTED_MODULE_0__["range"](start, end);
46020
+ return _shared_months__WEBPACK_IMPORTED_MODULE_1__["range"](start, end);
45955
46021
  };
45956
46022
 
45957
46023
  handlers['api/budget-month'] = async function ({
45958
46024
  month
45959
46025
  }) {
45960
46026
  await validateMonth(month);
45961
- let groups = await _db__WEBPACK_IMPORTED_MODULE_9__["getCategoriesGrouped"]();
45962
- let sheetName = _shared_months__WEBPACK_IMPORTED_MODULE_0__["sheetForMonth"](month);
46027
+ let groups = await _db__WEBPACK_IMPORTED_MODULE_10__["getCategoriesGrouped"]();
46028
+ let sheetName = _shared_months__WEBPACK_IMPORTED_MODULE_1__["sheetForMonth"](month);
45963
46029
 
45964
46030
  function value(name) {
45965
- let v = _sheet__WEBPACK_IMPORTED_MODULE_12__["get"]().getCellValue(sheetName, name);
46031
+ let v = _sheet__WEBPACK_IMPORTED_MODULE_13__["get"]().getCellValue(sheetName, name);
45966
46032
  return v === '' ? 0 : v;
45967
46033
  } // This is duplicated from main.js because the return format is
45968
46034
  // different (for now)
@@ -45981,19 +46047,19 @@ handlers['api/budget-month'] = async function ({
45981
46047
  totalBalance: value('total-leftover'),
45982
46048
  categoryGroups: groups.map(group => {
45983
46049
  if (group.is_income) {
45984
- return _objectSpread(_objectSpread({}, _api_models__WEBPACK_IMPORTED_MODULE_5__["categoryGroupModel"].toExternal(group)), {}, {
46050
+ return _objectSpread(_objectSpread({}, _api_models__WEBPACK_IMPORTED_MODULE_6__["categoryGroupModel"].toExternal(group)), {}, {
45985
46051
  received: value('total-income'),
45986
- categories: group.categories.map(cat => _objectSpread(_objectSpread({}, _api_models__WEBPACK_IMPORTED_MODULE_5__["categoryModel"].toExternal(cat)), {}, {
46052
+ categories: group.categories.map(cat => _objectSpread(_objectSpread({}, _api_models__WEBPACK_IMPORTED_MODULE_6__["categoryModel"].toExternal(cat)), {}, {
45987
46053
  received: value(`sum-amount-${cat.id}`)
45988
46054
  }))
45989
46055
  });
45990
46056
  }
45991
46057
 
45992
- return _objectSpread(_objectSpread({}, _api_models__WEBPACK_IMPORTED_MODULE_5__["categoryGroupModel"].toExternal(group)), {}, {
46058
+ return _objectSpread(_objectSpread({}, _api_models__WEBPACK_IMPORTED_MODULE_6__["categoryGroupModel"].toExternal(group)), {}, {
45993
46059
  budgeted: value(`group-budget-${group.id}`),
45994
46060
  spent: value(`group-sum-amount-${group.id}`),
45995
46061
  balance: value(`group-leftover-${group.id}`),
45996
- categories: group.categories.map(cat => _objectSpread(_objectSpread({}, _api_models__WEBPACK_IMPORTED_MODULE_5__["categoryModel"].toExternal(cat)), {}, {
46062
+ categories: group.categories.map(cat => _objectSpread(_objectSpread({}, _api_models__WEBPACK_IMPORTED_MODULE_6__["categoryModel"].toExternal(cat)), {}, {
45997
46063
  budgeted: value(`budget-${cat.id}`),
45998
46064
  spent: value(`sum-amount-${cat.id}`),
45999
46065
  balance: value(`leftover-${cat.id}`),
@@ -46054,7 +46120,7 @@ handlers['api/transactions-add'] = withMutation(async function ({
46054
46120
  accountId,
46055
46121
  transactions
46056
46122
  }) {
46057
- await Object(_accounts_sync__WEBPACK_IMPORTED_MODULE_4__["addTransactions"])(accountId, transactions, {
46123
+ await Object(_accounts_sync__WEBPACK_IMPORTED_MODULE_5__["addTransactions"])(accountId, transactions, {
46058
46124
  runTransfers: false
46059
46125
  });
46060
46126
  return 'ok';
@@ -46065,7 +46131,7 @@ handlers['api/transactions-get'] = async function ({
46065
46131
  startDate,
46066
46132
  endDate
46067
46133
  }) {
46068
- let _await$aqlQuery = await Object(_aql__WEBPACK_IMPORTED_MODULE_6__["runQuery"])(Object(_shared_query__WEBPACK_IMPORTED_MODULE_1__["default"])('transactions').filter({
46134
+ let _await$aqlQuery = await Object(_aql__WEBPACK_IMPORTED_MODULE_7__["runQuery"])(Object(_shared_query__WEBPACK_IMPORTED_MODULE_2__["default"])('transactions').filter({
46069
46135
  $and: [accountId && {
46070
46136
  account: accountId
46071
46137
  }, startDate && {
@@ -46096,20 +46162,20 @@ handlers['api/transaction-update'] = withMutation(async function ({
46096
46162
  id,
46097
46163
  fields
46098
46164
  }) {
46099
- let _await$aqlQuery2 = await Object(_aql__WEBPACK_IMPORTED_MODULE_6__["runQuery"])(Object(_shared_query__WEBPACK_IMPORTED_MODULE_1__["default"])('transactions').filter({
46165
+ let _await$aqlQuery2 = await Object(_aql__WEBPACK_IMPORTED_MODULE_7__["runQuery"])(Object(_shared_query__WEBPACK_IMPORTED_MODULE_2__["default"])('transactions').filter({
46100
46166
  id
46101
46167
  }).select('*').options({
46102
46168
  splits: 'grouped'
46103
46169
  })),
46104
46170
  data = _await$aqlQuery2.data;
46105
46171
 
46106
- let transactions = Object(_shared_transactions__WEBPACK_IMPORTED_MODULE_2__["ungroupTransactions"])(data);
46172
+ let transactions = Object(_shared_transactions__WEBPACK_IMPORTED_MODULE_3__["ungroupTransactions"])(data);
46107
46173
 
46108
46174
  if (transactions.length === 0) {
46109
46175
  return [];
46110
46176
  }
46111
46177
 
46112
- let _updateTransaction = Object(_shared_transactions__WEBPACK_IMPORTED_MODULE_2__["updateTransaction"])(transactions, fields),
46178
+ let _updateTransaction = Object(_shared_transactions__WEBPACK_IMPORTED_MODULE_3__["updateTransaction"])(transactions, fields),
46113
46179
  diff = _updateTransaction.diff;
46114
46180
 
46115
46181
  return handlers['transactions-batch-update'](diff);
@@ -46117,28 +46183,28 @@ handlers['api/transaction-update'] = withMutation(async function ({
46117
46183
  handlers['api/transaction-delete'] = withMutation(async function ({
46118
46184
  id
46119
46185
  }) {
46120
- let _await$aqlQuery3 = await Object(_aql__WEBPACK_IMPORTED_MODULE_6__["runQuery"])(Object(_shared_query__WEBPACK_IMPORTED_MODULE_1__["default"])('transactions').filter({
46186
+ let _await$aqlQuery3 = await Object(_aql__WEBPACK_IMPORTED_MODULE_7__["runQuery"])(Object(_shared_query__WEBPACK_IMPORTED_MODULE_2__["default"])('transactions').filter({
46121
46187
  id
46122
46188
  }).select('*').options({
46123
46189
  splits: 'grouped'
46124
46190
  })),
46125
46191
  data = _await$aqlQuery3.data;
46126
46192
 
46127
- let transactions = Object(_shared_transactions__WEBPACK_IMPORTED_MODULE_2__["ungroupTransactions"])(data);
46193
+ let transactions = Object(_shared_transactions__WEBPACK_IMPORTED_MODULE_3__["ungroupTransactions"])(data);
46128
46194
 
46129
46195
  if (transactions.length === 0) {
46130
46196
  return [];
46131
46197
  }
46132
46198
 
46133
- let _deleteTransaction = Object(_shared_transactions__WEBPACK_IMPORTED_MODULE_2__["deleteTransaction"])(transactions, id),
46199
+ let _deleteTransaction = Object(_shared_transactions__WEBPACK_IMPORTED_MODULE_3__["deleteTransaction"])(transactions, id),
46134
46200
  diff = _deleteTransaction.diff;
46135
46201
 
46136
46202
  return handlers['transactions-batch-update'](diff);
46137
46203
  });
46138
46204
 
46139
46205
  handlers['api/accounts-get'] = async function () {
46140
- let accounts = await _db__WEBPACK_IMPORTED_MODULE_9__["getAccounts"]();
46141
- return accounts.map(account => _api_models__WEBPACK_IMPORTED_MODULE_5__["accountModel"].toExternal(account));
46206
+ let accounts = await _db__WEBPACK_IMPORTED_MODULE_10__["getAccounts"]();
46207
+ return accounts.map(account => _api_models__WEBPACK_IMPORTED_MODULE_6__["accountModel"].toExternal(account));
46142
46208
  };
46143
46209
 
46144
46210
  handlers['api/account-create'] = withMutation(async function ({
@@ -46152,16 +46218,16 @@ handlers['api/account-create'] = withMutation(async function ({
46152
46218
  closed: account.closed,
46153
46219
  // Current the API expects an amount but it really should expect
46154
46220
  // an integer
46155
- balance: initialBalance != null ? Object(_shared_util__WEBPACK_IMPORTED_MODULE_3__["integerToAmount"])(initialBalance) : null
46221
+ balance: initialBalance != null ? Object(_shared_util__WEBPACK_IMPORTED_MODULE_4__["integerToAmount"])(initialBalance) : null
46156
46222
  });
46157
46223
  });
46158
46224
  handlers['api/account-update'] = withMutation(async function ({
46159
46225
  id,
46160
46226
  fields
46161
46227
  }) {
46162
- return _db__WEBPACK_IMPORTED_MODULE_9__["updateAccount"](_objectSpread({
46228
+ return _db__WEBPACK_IMPORTED_MODULE_10__["updateAccount"](_objectSpread({
46163
46229
  id
46164
- }, _api_models__WEBPACK_IMPORTED_MODULE_5__["accountModel"].fromExternal(fields)));
46230
+ }, _api_models__WEBPACK_IMPORTED_MODULE_6__["accountModel"].fromExternal(fields)));
46165
46231
  });
46166
46232
  handlers['api/account-close'] = withMutation(async function ({
46167
46233
  id,
@@ -46194,7 +46260,7 @@ handlers['api/categories-get'] = async function ({
46194
46260
  grouped
46195
46261
  } = {}) {
46196
46262
  let result = await handlers['get-categories']();
46197
- return grouped ? result.grouped.map(_api_models__WEBPACK_IMPORTED_MODULE_5__["categoryGroupModel"].toExternal) : result.list.map(_api_models__WEBPACK_IMPORTED_MODULE_5__["categoryModel"].toExternal);
46263
+ return grouped ? result.grouped.map(_api_models__WEBPACK_IMPORTED_MODULE_6__["categoryGroupModel"].toExternal) : result.list.map(_api_models__WEBPACK_IMPORTED_MODULE_6__["categoryModel"].toExternal);
46198
46264
  };
46199
46265
 
46200
46266
  handlers['api/category-group-create'] = withMutation(async function ({
@@ -46210,7 +46276,7 @@ handlers['api/category-group-update'] = withMutation(async function ({
46210
46276
  }) {
46211
46277
  return handlers['category-group-update'](_objectSpread({
46212
46278
  id
46213
- }, _api_models__WEBPACK_IMPORTED_MODULE_5__["categoryGroupModel"].fromExternal(fields)));
46279
+ }, _api_models__WEBPACK_IMPORTED_MODULE_6__["categoryGroupModel"].fromExternal(fields)));
46214
46280
  });
46215
46281
  handlers['api/category-group-delete'] = withMutation(async function ({
46216
46282
  id,
@@ -46236,7 +46302,7 @@ handlers['api/category-update'] = withMutation(async function ({
46236
46302
  }) {
46237
46303
  return handlers['category-update'](_objectSpread({
46238
46304
  id
46239
- }, _api_models__WEBPACK_IMPORTED_MODULE_5__["categoryModel"].fromExternal(fields)));
46305
+ }, _api_models__WEBPACK_IMPORTED_MODULE_6__["categoryModel"].fromExternal(fields)));
46240
46306
  });
46241
46307
  handlers['api/category-delete'] = withMutation(async function ({
46242
46308
  id,
@@ -46250,7 +46316,7 @@ handlers['api/category-delete'] = withMutation(async function ({
46250
46316
 
46251
46317
  handlers['api/payees-get'] = async function () {
46252
46318
  let payees = await handlers['payees-get']();
46253
- return payees.map(_api_models__WEBPACK_IMPORTED_MODULE_5__["payeeModel"].toExternal);
46319
+ return payees.map(_api_models__WEBPACK_IMPORTED_MODULE_6__["payeeModel"].toExternal);
46254
46320
  };
46255
46321
 
46256
46322
  handlers['api/payee-create'] = withMutation(async function ({
@@ -46267,7 +46333,7 @@ handlers['api/payee-update'] = withMutation(async function ({
46267
46333
  return handlers['payees-batch-change']({
46268
46334
  updated: [_objectSpread({
46269
46335
  id
46270
- }, _api_models__WEBPACK_IMPORTED_MODULE_5__["payeeModel"].fromExternal(fields))]
46336
+ }, _api_models__WEBPACK_IMPORTED_MODULE_6__["payeeModel"].fromExternal(fields))]
46271
46337
  });
46272
46338
  });
46273
46339
  handlers['api/payee-delete'] = withMutation(async function ({
@@ -46286,7 +46352,7 @@ handlers['api/payee-rules-get'] = async function ({
46286
46352
  let rules = await handlers['payees-get-rules']({
46287
46353
  id: payeeId
46288
46354
  });
46289
- return rules.map(_api_models__WEBPACK_IMPORTED_MODULE_5__["payeeRuleModel"].toExternal);
46355
+ return rules.map(_api_models__WEBPACK_IMPORTED_MODULE_6__["payeeRuleModel"].toExternal);
46290
46356
  };
46291
46357
 
46292
46358
  handlers['api/payee-rule-create'] = withMutation(async function ({
@@ -46305,7 +46371,7 @@ handlers['api/payee-rule-update'] = withMutation(async function ({
46305
46371
  }) {
46306
46372
  return handlers['payees-update-rule'](_objectSpread({
46307
46373
  id
46308
- }, _api_models__WEBPACK_IMPORTED_MODULE_5__["payeeRuleModel"].fromExternal(fields)));
46374
+ }, _api_models__WEBPACK_IMPORTED_MODULE_6__["payeeRuleModel"].fromExternal(fields)));
46309
46375
  });
46310
46376
  handlers['api/payee-rule-delete'] = withMutation(async function ({
46311
46377
  id
@@ -49633,98 +49699,1586 @@ async function createBudget(months) {
49633
49699
  meta.createdMonths = meta.createdMonths || new Set();
49634
49700
  let budgetType = getBudgetType();
49635
49701
 
49636
- if (budgetType === 'rollover') {
49637
- _rollover__WEBPACK_IMPORTED_MODULE_7__["createBudget"](meta, categories, months);
49702
+ if (budgetType === 'rollover') {
49703
+ _rollover__WEBPACK_IMPORTED_MODULE_7__["createBudget"](meta, categories, months);
49704
+ }
49705
+
49706
+ months.forEach(month => {
49707
+ if (!meta.createdMonths.has(month)) {
49708
+ let prevMonth = _shared_months__WEBPACK_IMPORTED_MODULE_0__["prevMonth"](month);
49709
+
49710
+ let _monthUtils$bounds2 = _shared_months__WEBPACK_IMPORTED_MODULE_0__["bounds"](month),
49711
+ start = _monthUtils$bounds2.start,
49712
+ end = _monthUtils$bounds2.end;
49713
+
49714
+ let sheetName = _shared_months__WEBPACK_IMPORTED_MODULE_0__["sheetForMonth"](month, budgetType);
49715
+ let prevSheetName = _shared_months__WEBPACK_IMPORTED_MODULE_0__["sheetForMonth"](prevMonth, budgetType);
49716
+ categories.forEach(cat => {
49717
+ createCategory(cat, sheetName, prevSheetName, start, end);
49718
+ });
49719
+ groups.forEach(group => {
49720
+ createCategoryGroup(group, sheetName);
49721
+ });
49722
+
49723
+ if (budgetType === 'rollover') {
49724
+ _rollover__WEBPACK_IMPORTED_MODULE_7__["createSummary"](groups, categories, prevSheetName, sheetName);
49725
+ } else {
49726
+ _report__WEBPACK_IMPORTED_MODULE_6__["createSummary"](groups, categories, sheetName);
49727
+ }
49728
+
49729
+ meta.createdMonths.add(month);
49730
+ }
49731
+ });
49732
+ _sheet__WEBPACK_IMPORTED_MODULE_3__["get"]().setMeta(meta);
49733
+ _sheet__WEBPACK_IMPORTED_MODULE_3__["endTransaction"](); // Wait for the spreadsheet to finish computing. Normally this won't
49734
+ // do anything (as values are cached) but on first run this need to
49735
+ // show the loading screen while it initially sets up.
49736
+
49737
+ await _sheet__WEBPACK_IMPORTED_MODULE_3__["waitOnSpreadsheet"]();
49738
+ }
49739
+ async function createAllBudgets() {
49740
+ let earliestTransaction = await _db__WEBPACK_IMPORTED_MODULE_2__["first"]('SELECT * FROM transactions WHERE isChild=0 AND date IS NOT NULL ORDER BY date ASC LIMIT 1');
49741
+ let earliestDate = earliestTransaction && _db__WEBPACK_IMPORTED_MODULE_2__["fromDateRepr"](earliestTransaction.date);
49742
+ let currentMonth = _shared_months__WEBPACK_IMPORTED_MODULE_0__["currentMonth"](); // Get the range based off of the earliest transaction and the
49743
+ // current month. If no transactions currently exist the current
49744
+ // month is also used as the starting month
49745
+
49746
+ let _getBudgetRange = getBudgetRange(earliestDate || currentMonth, currentMonth),
49747
+ start = _getBudgetRange.start,
49748
+ end = _getBudgetRange.end,
49749
+ range = _getBudgetRange.range;
49750
+
49751
+ let meta = _sheet__WEBPACK_IMPORTED_MODULE_3__["get"]().meta();
49752
+ let createdMonths = meta.createdMonths || new Set();
49753
+ let newMonths = range.filter(m => !createdMonths.has(m));
49754
+
49755
+ if (newMonths.length > 0) {
49756
+ await createBudget(range);
49757
+ }
49758
+
49759
+ return {
49760
+ start,
49761
+ end
49762
+ };
49763
+ }
49764
+ async function setType(type) {
49765
+ let meta = _sheet__WEBPACK_IMPORTED_MODULE_3__["get"]().meta();
49766
+
49767
+ if (type === meta.budgetType) {
49768
+ return;
49769
+ }
49770
+
49771
+ meta.budgetType = type;
49772
+ meta.createdMonths = new Set(); // Go through and force all the cells to be recomputed
49773
+
49774
+ let nodes = _sheet__WEBPACK_IMPORTED_MODULE_3__["get"]().getNodes();
49775
+ _db__WEBPACK_IMPORTED_MODULE_2__["transaction"](() => {
49776
+ for (let name of nodes.keys()) {
49777
+ let _name$split = name.split('!'),
49778
+ _name$split2 = _slicedToArray(_name$split, 2),
49779
+ sheetName = _name$split2[0],
49780
+ cellName = _name$split2[1];
49781
+
49782
+ if (sheetName.match(/^budget\d+/)) {
49783
+ _sheet__WEBPACK_IMPORTED_MODULE_3__["get"]().deleteCell(sheetName, cellName);
49784
+ }
49785
+ }
49786
+ });
49787
+ _sheet__WEBPACK_IMPORTED_MODULE_3__["get"]().startCacheBarrier();
49788
+ _sheet__WEBPACK_IMPORTED_MODULE_3__["loadUserBudgets"](_db__WEBPACK_IMPORTED_MODULE_2__);
49789
+ let bounds = await createAllBudgets();
49790
+ _sheet__WEBPACK_IMPORTED_MODULE_3__["get"]().endCacheBarrier();
49791
+ return bounds;
49792
+ }
49793
+
49794
+ /***/ }),
49795
+
49796
+ /***/ "./packages/loot-core/src/server/budget/goal-template.pegjs":
49797
+ /*!******************************************************************!*\
49798
+ !*** ./packages/loot-core/src/server/budget/goal-template.pegjs ***!
49799
+ \******************************************************************/
49800
+ /*! no static exports found */
49801
+ /***/ (function(module, exports, __webpack_require__) {
49802
+
49803
+ "use strict";
49804
+ /*
49805
+ * Generated by PEG.js 0.10.0.
49806
+ *
49807
+ * http://pegjs.org/
49808
+ */
49809
+
49810
+
49811
+
49812
+ function peg$subclass(child, parent) {
49813
+ function ctor() { this.constructor = child; }
49814
+ ctor.prototype = parent.prototype;
49815
+ child.prototype = new ctor();
49816
+ }
49817
+
49818
+ function peg$SyntaxError(message, expected, found, location) {
49819
+ this.message = message;
49820
+ this.expected = expected;
49821
+ this.found = found;
49822
+ this.location = location;
49823
+ this.name = "SyntaxError";
49824
+
49825
+ if (typeof Error.captureStackTrace === "function") {
49826
+ Error.captureStackTrace(this, peg$SyntaxError);
49827
+ }
49828
+ }
49829
+
49830
+ peg$subclass(peg$SyntaxError, Error);
49831
+
49832
+ peg$SyntaxError.buildMessage = function(expected, found) {
49833
+ var DESCRIBE_EXPECTATION_FNS = {
49834
+ literal: function(expectation) {
49835
+ return "\"" + literalEscape(expectation.text) + "\"";
49836
+ },
49837
+
49838
+ "class": function(expectation) {
49839
+ var escapedParts = "",
49840
+ i;
49841
+
49842
+ for (i = 0; i < expectation.parts.length; i++) {
49843
+ escapedParts += expectation.parts[i] instanceof Array
49844
+ ? classEscape(expectation.parts[i][0]) + "-" + classEscape(expectation.parts[i][1])
49845
+ : classEscape(expectation.parts[i]);
49846
+ }
49847
+
49848
+ return "[" + (expectation.inverted ? "^" : "") + escapedParts + "]";
49849
+ },
49850
+
49851
+ any: function(expectation) {
49852
+ return "any character";
49853
+ },
49854
+
49855
+ end: function(expectation) {
49856
+ return "end of input";
49857
+ },
49858
+
49859
+ other: function(expectation) {
49860
+ return expectation.description;
49861
+ }
49862
+ };
49863
+
49864
+ function hex(ch) {
49865
+ return ch.charCodeAt(0).toString(16).toUpperCase();
49866
+ }
49867
+
49868
+ function literalEscape(s) {
49869
+ return s
49870
+ .replace(/\\/g, '\\\\')
49871
+ .replace(/"/g, '\\"')
49872
+ .replace(/\0/g, '\\0')
49873
+ .replace(/\t/g, '\\t')
49874
+ .replace(/\n/g, '\\n')
49875
+ .replace(/\r/g, '\\r')
49876
+ .replace(/[\x00-\x0F]/g, function(ch) { return '\\x0' + hex(ch); })
49877
+ .replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return '\\x' + hex(ch); });
49878
+ }
49879
+
49880
+ function classEscape(s) {
49881
+ return s
49882
+ .replace(/\\/g, '\\\\')
49883
+ .replace(/\]/g, '\\]')
49884
+ .replace(/\^/g, '\\^')
49885
+ .replace(/-/g, '\\-')
49886
+ .replace(/\0/g, '\\0')
49887
+ .replace(/\t/g, '\\t')
49888
+ .replace(/\n/g, '\\n')
49889
+ .replace(/\r/g, '\\r')
49890
+ .replace(/[\x00-\x0F]/g, function(ch) { return '\\x0' + hex(ch); })
49891
+ .replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return '\\x' + hex(ch); });
49892
+ }
49893
+
49894
+ function describeExpectation(expectation) {
49895
+ return DESCRIBE_EXPECTATION_FNS[expectation.type](expectation);
49896
+ }
49897
+
49898
+ function describeExpected(expected) {
49899
+ var descriptions = new Array(expected.length),
49900
+ i, j;
49901
+
49902
+ for (i = 0; i < expected.length; i++) {
49903
+ descriptions[i] = describeExpectation(expected[i]);
49904
+ }
49905
+
49906
+ descriptions.sort();
49907
+
49908
+ if (descriptions.length > 0) {
49909
+ for (i = 1, j = 1; i < descriptions.length; i++) {
49910
+ if (descriptions[i - 1] !== descriptions[i]) {
49911
+ descriptions[j] = descriptions[i];
49912
+ j++;
49913
+ }
49914
+ }
49915
+ descriptions.length = j;
49916
+ }
49917
+
49918
+ switch (descriptions.length) {
49919
+ case 1:
49920
+ return descriptions[0];
49921
+
49922
+ case 2:
49923
+ return descriptions[0] + " or " + descriptions[1];
49924
+
49925
+ default:
49926
+ return descriptions.slice(0, -1).join(", ")
49927
+ + ", or "
49928
+ + descriptions[descriptions.length - 1];
49929
+ }
49930
+ }
49931
+
49932
+ function describeFound(found) {
49933
+ return found ? "\"" + literalEscape(found) + "\"" : "end of input";
49934
+ }
49935
+
49936
+ return "Expected " + describeExpected(expected) + " but " + describeFound(found) + " found.";
49937
+ };
49938
+
49939
+ function peg$parse(input, options) {
49940
+ options = options !== void 0 ? options : {};
49941
+
49942
+ var peg$FAILED = {},
49943
+
49944
+ peg$startRuleFunctions = { expr: peg$parseexpr },
49945
+ peg$startRuleFunction = peg$parseexpr,
49946
+
49947
+ peg$c0 = /^[^\n]/,
49948
+ peg$c1 = peg$classExpectation(["\n"], true, false),
49949
+ peg$c2 = function(percent, category) { return { type: 'percentage', percent: +percent, category } },
49950
+ peg$c3 = function(amount, weeks, starting, limit) { return { type: 'week', amount, weeks, starting, limit } },
49951
+ peg$c4 = function(amount, month, from, repeat) { return {
49952
+ type: from ? 'spend' : 'by',
49953
+ amount,
49954
+ month,
49955
+ ...(repeat ? repeat[3] : {}),
49956
+ from
49957
+ } },
49958
+ peg$c5 = function(monthly, limit) { return { type: 'simple', monthly, limit } },
49959
+ peg$c6 = function(limit) { return { type: 'simple', limit } },
49960
+ peg$c7 = peg$otherExpectation("repeat interval"),
49961
+ peg$c8 = "month",
49962
+ peg$c9 = peg$literalExpectation("month", false),
49963
+ peg$c10 = function() { return { annual: false } },
49964
+ peg$c11 = "months",
49965
+ peg$c12 = peg$literalExpectation("months", false),
49966
+ peg$c13 = function(months) { return { annual: false, repeat: +months } },
49967
+ peg$c14 = "year",
49968
+ peg$c15 = peg$literalExpectation("year", false),
49969
+ peg$c16 = function() { return { annual: true } },
49970
+ peg$c17 = "years",
49971
+ peg$c18 = peg$literalExpectation("years", false),
49972
+ peg$c19 = function(years) { return { annual: true, repeat: +years } },
49973
+ peg$c20 = function(amount) { return amount },
49974
+ peg$c21 = function() { return null },
49975
+ peg$c22 = function(n) { return +n },
49976
+ peg$c23 = "spend",
49977
+ peg$c24 = peg$literalExpectation("spend", false),
49978
+ peg$c25 = "from",
49979
+ peg$c26 = peg$literalExpectation("from", false),
49980
+ peg$c27 = function(month) { return month },
49981
+ peg$c28 = "week",
49982
+ peg$c29 = peg$literalExpectation("week", false),
49983
+ peg$c30 = "weeks",
49984
+ peg$c31 = peg$literalExpectation("weeks", false),
49985
+ peg$c32 = "by",
49986
+ peg$c33 = peg$literalExpectation("by", false),
49987
+ peg$c34 = "of",
49988
+ peg$c35 = peg$literalExpectation("of", false),
49989
+ peg$c36 = "repeat",
49990
+ peg$c37 = peg$literalExpectation("repeat", false),
49991
+ peg$c38 = "every",
49992
+ peg$c39 = peg$literalExpectation("every", false),
49993
+ peg$c40 = "starting",
49994
+ peg$c41 = peg$literalExpectation("starting", false),
49995
+ peg$c42 = "up",
49996
+ peg$c43 = peg$literalExpectation("up", false),
49997
+ peg$c44 = "to",
49998
+ peg$c45 = peg$literalExpectation("to", false),
49999
+ peg$c46 = peg$otherExpectation("space"),
50000
+ peg$c47 = " ",
50001
+ peg$c48 = peg$literalExpectation(" ", false),
50002
+ peg$c49 = peg$otherExpectation("digit"),
50003
+ peg$c50 = /^[0-9]/,
50004
+ peg$c51 = peg$classExpectation([["0", "9"]], false, false),
50005
+ peg$c52 = peg$otherExpectation("number"),
50006
+ peg$c53 = peg$otherExpectation("amount"),
50007
+ peg$c54 = ".",
50008
+ peg$c55 = peg$literalExpectation(".", false),
50009
+ peg$c56 = function(amount) { return +amount },
50010
+ peg$c57 = peg$otherExpectation("percentage"),
50011
+ peg$c58 = "%",
50012
+ peg$c59 = peg$literalExpectation("%", false),
50013
+ peg$c60 = function(percent) { return +percent },
50014
+ peg$c61 = peg$otherExpectation("year"),
50015
+ peg$c62 = peg$otherExpectation("month"),
50016
+ peg$c63 = "-",
50017
+ peg$c64 = peg$literalExpectation("-", false),
50018
+ peg$c65 = peg$otherExpectation("day"),
50019
+ peg$c66 = peg$otherExpectation("currency symbol"),
50020
+ peg$c67 = peg$anyExpectation(),
50021
+ peg$c68 = function(symbol) { return /\p{Sc}/u.test(symbol) },
50022
+
50023
+ peg$currPos = 0,
50024
+ peg$savedPos = 0,
50025
+ peg$posDetailsCache = [{ line: 1, column: 1 }],
50026
+ peg$maxFailPos = 0,
50027
+ peg$maxFailExpected = [],
50028
+ peg$silentFails = 0,
50029
+
50030
+ peg$result;
50031
+
50032
+ if ("startRule" in options) {
50033
+ if (!(options.startRule in peg$startRuleFunctions)) {
50034
+ throw new Error("Can't start parsing from rule \"" + options.startRule + "\".");
50035
+ }
50036
+
50037
+ peg$startRuleFunction = peg$startRuleFunctions[options.startRule];
50038
+ }
50039
+
50040
+ function text() {
50041
+ return input.substring(peg$savedPos, peg$currPos);
50042
+ }
50043
+
50044
+ function location() {
50045
+ return peg$computeLocation(peg$savedPos, peg$currPos);
50046
+ }
50047
+
50048
+ function expected(description, location) {
50049
+ location = location !== void 0 ? location : peg$computeLocation(peg$savedPos, peg$currPos)
50050
+
50051
+ throw peg$buildStructuredError(
50052
+ [peg$otherExpectation(description)],
50053
+ input.substring(peg$savedPos, peg$currPos),
50054
+ location
50055
+ );
50056
+ }
50057
+
50058
+ function error(message, location) {
50059
+ location = location !== void 0 ? location : peg$computeLocation(peg$savedPos, peg$currPos)
50060
+
50061
+ throw peg$buildSimpleError(message, location);
50062
+ }
50063
+
50064
+ function peg$literalExpectation(text, ignoreCase) {
50065
+ return { type: "literal", text: text, ignoreCase: ignoreCase };
50066
+ }
50067
+
50068
+ function peg$classExpectation(parts, inverted, ignoreCase) {
50069
+ return { type: "class", parts: parts, inverted: inverted, ignoreCase: ignoreCase };
50070
+ }
50071
+
50072
+ function peg$anyExpectation() {
50073
+ return { type: "any" };
50074
+ }
50075
+
50076
+ function peg$endExpectation() {
50077
+ return { type: "end" };
50078
+ }
50079
+
50080
+ function peg$otherExpectation(description) {
50081
+ return { type: "other", description: description };
50082
+ }
50083
+
50084
+ function peg$computePosDetails(pos) {
50085
+ var details = peg$posDetailsCache[pos], p;
50086
+
50087
+ if (details) {
50088
+ return details;
50089
+ } else {
50090
+ p = pos - 1;
50091
+ while (!peg$posDetailsCache[p]) {
50092
+ p--;
50093
+ }
50094
+
50095
+ details = peg$posDetailsCache[p];
50096
+ details = {
50097
+ line: details.line,
50098
+ column: details.column
50099
+ };
50100
+
50101
+ while (p < pos) {
50102
+ if (input.charCodeAt(p) === 10) {
50103
+ details.line++;
50104
+ details.column = 1;
50105
+ } else {
50106
+ details.column++;
50107
+ }
50108
+
50109
+ p++;
50110
+ }
50111
+
50112
+ peg$posDetailsCache[pos] = details;
50113
+ return details;
50114
+ }
50115
+ }
50116
+
50117
+ function peg$computeLocation(startPos, endPos) {
50118
+ var startPosDetails = peg$computePosDetails(startPos),
50119
+ endPosDetails = peg$computePosDetails(endPos);
50120
+
50121
+ return {
50122
+ start: {
50123
+ offset: startPos,
50124
+ line: startPosDetails.line,
50125
+ column: startPosDetails.column
50126
+ },
50127
+ end: {
50128
+ offset: endPos,
50129
+ line: endPosDetails.line,
50130
+ column: endPosDetails.column
50131
+ }
50132
+ };
50133
+ }
50134
+
50135
+ function peg$fail(expected) {
50136
+ if (peg$currPos < peg$maxFailPos) { return; }
50137
+
50138
+ if (peg$currPos > peg$maxFailPos) {
50139
+ peg$maxFailPos = peg$currPos;
50140
+ peg$maxFailExpected = [];
50141
+ }
50142
+
50143
+ peg$maxFailExpected.push(expected);
50144
+ }
50145
+
50146
+ function peg$buildSimpleError(message, location) {
50147
+ return new peg$SyntaxError(message, null, null, location);
50148
+ }
50149
+
50150
+ function peg$buildStructuredError(expected, found, location) {
50151
+ return new peg$SyntaxError(
50152
+ peg$SyntaxError.buildMessage(expected, found),
50153
+ expected,
50154
+ found,
50155
+ location
50156
+ );
50157
+ }
50158
+
50159
+ function peg$parseexpr() {
50160
+ var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11;
50161
+
50162
+ s0 = peg$currPos;
50163
+ s1 = peg$parsepercent();
50164
+ if (s1 !== peg$FAILED) {
50165
+ s2 = peg$parse_();
50166
+ if (s2 !== peg$FAILED) {
50167
+ s3 = peg$parseof();
50168
+ if (s3 !== peg$FAILED) {
50169
+ s4 = peg$parse_();
50170
+ if (s4 !== peg$FAILED) {
50171
+ s5 = peg$currPos;
50172
+ s6 = [];
50173
+ if (peg$c0.test(input.charAt(peg$currPos))) {
50174
+ s7 = input.charAt(peg$currPos);
50175
+ peg$currPos++;
50176
+ } else {
50177
+ s7 = peg$FAILED;
50178
+ if (peg$silentFails === 0) { peg$fail(peg$c1); }
50179
+ }
50180
+ while (s7 !== peg$FAILED) {
50181
+ s6.push(s7);
50182
+ if (peg$c0.test(input.charAt(peg$currPos))) {
50183
+ s7 = input.charAt(peg$currPos);
50184
+ peg$currPos++;
50185
+ } else {
50186
+ s7 = peg$FAILED;
50187
+ if (peg$silentFails === 0) { peg$fail(peg$c1); }
50188
+ }
50189
+ }
50190
+ if (s6 !== peg$FAILED) {
50191
+ s5 = input.substring(s5, peg$currPos);
50192
+ } else {
50193
+ s5 = s6;
50194
+ }
50195
+ if (s5 !== peg$FAILED) {
50196
+ peg$savedPos = s0;
50197
+ s1 = peg$c2(s1, s5);
50198
+ s0 = s1;
50199
+ } else {
50200
+ peg$currPos = s0;
50201
+ s0 = peg$FAILED;
50202
+ }
50203
+ } else {
50204
+ peg$currPos = s0;
50205
+ s0 = peg$FAILED;
50206
+ }
50207
+ } else {
50208
+ peg$currPos = s0;
50209
+ s0 = peg$FAILED;
50210
+ }
50211
+ } else {
50212
+ peg$currPos = s0;
50213
+ s0 = peg$FAILED;
50214
+ }
50215
+ } else {
50216
+ peg$currPos = s0;
50217
+ s0 = peg$FAILED;
50218
+ }
50219
+ if (s0 === peg$FAILED) {
50220
+ s0 = peg$currPos;
50221
+ s1 = peg$parseamount();
50222
+ if (s1 !== peg$FAILED) {
50223
+ s2 = peg$parse_();
50224
+ if (s2 !== peg$FAILED) {
50225
+ s3 = peg$parserepeatEvery();
50226
+ if (s3 !== peg$FAILED) {
50227
+ s4 = peg$parse_();
50228
+ if (s4 !== peg$FAILED) {
50229
+ s5 = peg$parseweekCount();
50230
+ if (s5 !== peg$FAILED) {
50231
+ s6 = peg$parse_();
50232
+ if (s6 !== peg$FAILED) {
50233
+ s7 = peg$parsestarting();
50234
+ if (s7 !== peg$FAILED) {
50235
+ s8 = peg$parse_();
50236
+ if (s8 !== peg$FAILED) {
50237
+ s9 = peg$parsedate();
50238
+ if (s9 !== peg$FAILED) {
50239
+ s10 = peg$parselimit();
50240
+ if (s10 === peg$FAILED) {
50241
+ s10 = null;
50242
+ }
50243
+ if (s10 !== peg$FAILED) {
50244
+ peg$savedPos = s0;
50245
+ s1 = peg$c3(s1, s5, s9, s10);
50246
+ s0 = s1;
50247
+ } else {
50248
+ peg$currPos = s0;
50249
+ s0 = peg$FAILED;
50250
+ }
50251
+ } else {
50252
+ peg$currPos = s0;
50253
+ s0 = peg$FAILED;
50254
+ }
50255
+ } else {
50256
+ peg$currPos = s0;
50257
+ s0 = peg$FAILED;
50258
+ }
50259
+ } else {
50260
+ peg$currPos = s0;
50261
+ s0 = peg$FAILED;
50262
+ }
50263
+ } else {
50264
+ peg$currPos = s0;
50265
+ s0 = peg$FAILED;
50266
+ }
50267
+ } else {
50268
+ peg$currPos = s0;
50269
+ s0 = peg$FAILED;
50270
+ }
50271
+ } else {
50272
+ peg$currPos = s0;
50273
+ s0 = peg$FAILED;
50274
+ }
50275
+ } else {
50276
+ peg$currPos = s0;
50277
+ s0 = peg$FAILED;
50278
+ }
50279
+ } else {
50280
+ peg$currPos = s0;
50281
+ s0 = peg$FAILED;
50282
+ }
50283
+ } else {
50284
+ peg$currPos = s0;
50285
+ s0 = peg$FAILED;
50286
+ }
50287
+ if (s0 === peg$FAILED) {
50288
+ s0 = peg$currPos;
50289
+ s1 = peg$parseamount();
50290
+ if (s1 !== peg$FAILED) {
50291
+ s2 = peg$parse_();
50292
+ if (s2 !== peg$FAILED) {
50293
+ s3 = peg$parseby();
50294
+ if (s3 !== peg$FAILED) {
50295
+ s4 = peg$parse_();
50296
+ if (s4 !== peg$FAILED) {
50297
+ s5 = peg$parsemonth();
50298
+ if (s5 !== peg$FAILED) {
50299
+ s6 = peg$parsespendFrom();
50300
+ if (s6 === peg$FAILED) {
50301
+ s6 = null;
50302
+ }
50303
+ if (s6 !== peg$FAILED) {
50304
+ s7 = peg$currPos;
50305
+ s8 = peg$parse_();
50306
+ if (s8 !== peg$FAILED) {
50307
+ s9 = peg$parserepeatEvery();
50308
+ if (s9 !== peg$FAILED) {
50309
+ s10 = peg$parse_();
50310
+ if (s10 !== peg$FAILED) {
50311
+ s11 = peg$parserepeat();
50312
+ if (s11 !== peg$FAILED) {
50313
+ s8 = [s8, s9, s10, s11];
50314
+ s7 = s8;
50315
+ } else {
50316
+ peg$currPos = s7;
50317
+ s7 = peg$FAILED;
50318
+ }
50319
+ } else {
50320
+ peg$currPos = s7;
50321
+ s7 = peg$FAILED;
50322
+ }
50323
+ } else {
50324
+ peg$currPos = s7;
50325
+ s7 = peg$FAILED;
50326
+ }
50327
+ } else {
50328
+ peg$currPos = s7;
50329
+ s7 = peg$FAILED;
50330
+ }
50331
+ if (s7 === peg$FAILED) {
50332
+ s7 = null;
50333
+ }
50334
+ if (s7 !== peg$FAILED) {
50335
+ peg$savedPos = s0;
50336
+ s1 = peg$c4(s1, s5, s6, s7);
50337
+ s0 = s1;
50338
+ } else {
50339
+ peg$currPos = s0;
50340
+ s0 = peg$FAILED;
50341
+ }
50342
+ } else {
50343
+ peg$currPos = s0;
50344
+ s0 = peg$FAILED;
50345
+ }
50346
+ } else {
50347
+ peg$currPos = s0;
50348
+ s0 = peg$FAILED;
50349
+ }
50350
+ } else {
50351
+ peg$currPos = s0;
50352
+ s0 = peg$FAILED;
50353
+ }
50354
+ } else {
50355
+ peg$currPos = s0;
50356
+ s0 = peg$FAILED;
50357
+ }
50358
+ } else {
50359
+ peg$currPos = s0;
50360
+ s0 = peg$FAILED;
50361
+ }
50362
+ } else {
50363
+ peg$currPos = s0;
50364
+ s0 = peg$FAILED;
50365
+ }
50366
+ if (s0 === peg$FAILED) {
50367
+ s0 = peg$currPos;
50368
+ s1 = peg$parseamount();
50369
+ if (s1 !== peg$FAILED) {
50370
+ s2 = peg$parselimit();
50371
+ if (s2 === peg$FAILED) {
50372
+ s2 = null;
50373
+ }
50374
+ if (s2 !== peg$FAILED) {
50375
+ peg$savedPos = s0;
50376
+ s1 = peg$c5(s1, s2);
50377
+ s0 = s1;
50378
+ } else {
50379
+ peg$currPos = s0;
50380
+ s0 = peg$FAILED;
50381
+ }
50382
+ } else {
50383
+ peg$currPos = s0;
50384
+ s0 = peg$FAILED;
50385
+ }
50386
+ if (s0 === peg$FAILED) {
50387
+ s0 = peg$currPos;
50388
+ s1 = peg$parseupTo();
50389
+ if (s1 !== peg$FAILED) {
50390
+ s2 = peg$parse_();
50391
+ if (s2 !== peg$FAILED) {
50392
+ s3 = peg$parseamount();
50393
+ if (s3 !== peg$FAILED) {
50394
+ peg$savedPos = s0;
50395
+ s1 = peg$c6(s3);
50396
+ s0 = s1;
50397
+ } else {
50398
+ peg$currPos = s0;
50399
+ s0 = peg$FAILED;
50400
+ }
50401
+ } else {
50402
+ peg$currPos = s0;
50403
+ s0 = peg$FAILED;
50404
+ }
50405
+ } else {
50406
+ peg$currPos = s0;
50407
+ s0 = peg$FAILED;
50408
+ }
50409
+ }
50410
+ }
50411
+ }
50412
+ }
50413
+
50414
+ return s0;
50415
+ }
50416
+
50417
+ function peg$parserepeat() {
50418
+ var s0, s1, s2, s3;
50419
+
50420
+ peg$silentFails++;
50421
+ s0 = peg$currPos;
50422
+ if (input.substr(peg$currPos, 5) === peg$c8) {
50423
+ s1 = peg$c8;
50424
+ peg$currPos += 5;
50425
+ } else {
50426
+ s1 = peg$FAILED;
50427
+ if (peg$silentFails === 0) { peg$fail(peg$c9); }
50428
+ }
50429
+ if (s1 !== peg$FAILED) {
50430
+ peg$savedPos = s0;
50431
+ s1 = peg$c10();
50432
+ }
50433
+ s0 = s1;
50434
+ if (s0 === peg$FAILED) {
50435
+ s0 = peg$currPos;
50436
+ s1 = peg$parsed();
50437
+ if (s1 !== peg$FAILED) {
50438
+ s2 = peg$parse_();
50439
+ if (s2 !== peg$FAILED) {
50440
+ if (input.substr(peg$currPos, 6) === peg$c11) {
50441
+ s3 = peg$c11;
50442
+ peg$currPos += 6;
50443
+ } else {
50444
+ s3 = peg$FAILED;
50445
+ if (peg$silentFails === 0) { peg$fail(peg$c12); }
50446
+ }
50447
+ if (s3 !== peg$FAILED) {
50448
+ peg$savedPos = s0;
50449
+ s1 = peg$c13(s1);
50450
+ s0 = s1;
50451
+ } else {
50452
+ peg$currPos = s0;
50453
+ s0 = peg$FAILED;
50454
+ }
50455
+ } else {
50456
+ peg$currPos = s0;
50457
+ s0 = peg$FAILED;
50458
+ }
50459
+ } else {
50460
+ peg$currPos = s0;
50461
+ s0 = peg$FAILED;
50462
+ }
50463
+ if (s0 === peg$FAILED) {
50464
+ s0 = peg$currPos;
50465
+ if (input.substr(peg$currPos, 4) === peg$c14) {
50466
+ s1 = peg$c14;
50467
+ peg$currPos += 4;
50468
+ } else {
50469
+ s1 = peg$FAILED;
50470
+ if (peg$silentFails === 0) { peg$fail(peg$c15); }
50471
+ }
50472
+ if (s1 !== peg$FAILED) {
50473
+ peg$savedPos = s0;
50474
+ s1 = peg$c16();
50475
+ }
50476
+ s0 = s1;
50477
+ if (s0 === peg$FAILED) {
50478
+ s0 = peg$currPos;
50479
+ s1 = peg$parsed();
50480
+ if (s1 !== peg$FAILED) {
50481
+ s2 = peg$parse_();
50482
+ if (s2 !== peg$FAILED) {
50483
+ if (input.substr(peg$currPos, 5) === peg$c17) {
50484
+ s3 = peg$c17;
50485
+ peg$currPos += 5;
50486
+ } else {
50487
+ s3 = peg$FAILED;
50488
+ if (peg$silentFails === 0) { peg$fail(peg$c18); }
50489
+ }
50490
+ if (s3 !== peg$FAILED) {
50491
+ peg$savedPos = s0;
50492
+ s1 = peg$c19(s1);
50493
+ s0 = s1;
50494
+ } else {
50495
+ peg$currPos = s0;
50496
+ s0 = peg$FAILED;
50497
+ }
50498
+ } else {
50499
+ peg$currPos = s0;
50500
+ s0 = peg$FAILED;
50501
+ }
50502
+ } else {
50503
+ peg$currPos = s0;
50504
+ s0 = peg$FAILED;
50505
+ }
50506
+ }
50507
+ }
50508
+ }
50509
+ peg$silentFails--;
50510
+ if (s0 === peg$FAILED) {
50511
+ s1 = peg$FAILED;
50512
+ if (peg$silentFails === 0) { peg$fail(peg$c7); }
50513
+ }
50514
+
50515
+ return s0;
50516
+ }
50517
+
50518
+ function peg$parselimit() {
50519
+ var s0, s1, s2, s3, s4;
50520
+
50521
+ s0 = peg$currPos;
50522
+ s1 = peg$parse_();
50523
+ if (s1 !== peg$FAILED) {
50524
+ s2 = peg$parseupTo();
50525
+ if (s2 === peg$FAILED) {
50526
+ s2 = null;
50527
+ }
50528
+ if (s2 !== peg$FAILED) {
50529
+ s3 = peg$parse_();
50530
+ if (s3 !== peg$FAILED) {
50531
+ s4 = peg$parseamount();
50532
+ if (s4 !== peg$FAILED) {
50533
+ peg$savedPos = s0;
50534
+ s1 = peg$c20(s4);
50535
+ s0 = s1;
50536
+ } else {
50537
+ peg$currPos = s0;
50538
+ s0 = peg$FAILED;
50539
+ }
50540
+ } else {
50541
+ peg$currPos = s0;
50542
+ s0 = peg$FAILED;
50543
+ }
50544
+ } else {
50545
+ peg$currPos = s0;
50546
+ s0 = peg$FAILED;
50547
+ }
50548
+ } else {
50549
+ peg$currPos = s0;
50550
+ s0 = peg$FAILED;
50551
+ }
50552
+
50553
+ return s0;
50554
+ }
50555
+
50556
+ function peg$parseweekCount() {
50557
+ var s0, s1, s2, s3;
50558
+
50559
+ s0 = peg$currPos;
50560
+ s1 = peg$parseweek();
50561
+ if (s1 !== peg$FAILED) {
50562
+ peg$savedPos = s0;
50563
+ s1 = peg$c21();
50564
+ }
50565
+ s0 = s1;
50566
+ if (s0 === peg$FAILED) {
50567
+ s0 = peg$currPos;
50568
+ s1 = peg$parsenumber();
50569
+ if (s1 !== peg$FAILED) {
50570
+ s2 = peg$parse_();
50571
+ if (s2 !== peg$FAILED) {
50572
+ s3 = peg$parseweeks();
50573
+ if (s3 !== peg$FAILED) {
50574
+ peg$savedPos = s0;
50575
+ s1 = peg$c22(s1);
50576
+ s0 = s1;
50577
+ } else {
50578
+ peg$currPos = s0;
50579
+ s0 = peg$FAILED;
50580
+ }
50581
+ } else {
50582
+ peg$currPos = s0;
50583
+ s0 = peg$FAILED;
50584
+ }
50585
+ } else {
50586
+ peg$currPos = s0;
50587
+ s0 = peg$FAILED;
50588
+ }
50589
+ }
50590
+
50591
+ return s0;
50592
+ }
50593
+
50594
+ function peg$parsespendFrom() {
50595
+ var s0, s1, s2, s3, s4, s5, s6;
50596
+
50597
+ s0 = peg$currPos;
50598
+ s1 = peg$parse_();
50599
+ if (s1 !== peg$FAILED) {
50600
+ if (input.substr(peg$currPos, 5) === peg$c23) {
50601
+ s2 = peg$c23;
50602
+ peg$currPos += 5;
50603
+ } else {
50604
+ s2 = peg$FAILED;
50605
+ if (peg$silentFails === 0) { peg$fail(peg$c24); }
50606
+ }
50607
+ if (s2 !== peg$FAILED) {
50608
+ s3 = peg$parse_();
50609
+ if (s3 !== peg$FAILED) {
50610
+ if (input.substr(peg$currPos, 4) === peg$c25) {
50611
+ s4 = peg$c25;
50612
+ peg$currPos += 4;
50613
+ } else {
50614
+ s4 = peg$FAILED;
50615
+ if (peg$silentFails === 0) { peg$fail(peg$c26); }
50616
+ }
50617
+ if (s4 !== peg$FAILED) {
50618
+ s5 = peg$parse_();
50619
+ if (s5 !== peg$FAILED) {
50620
+ s6 = peg$parsemonth();
50621
+ if (s6 !== peg$FAILED) {
50622
+ peg$savedPos = s0;
50623
+ s1 = peg$c27(s6);
50624
+ s0 = s1;
50625
+ } else {
50626
+ peg$currPos = s0;
50627
+ s0 = peg$FAILED;
50628
+ }
50629
+ } else {
50630
+ peg$currPos = s0;
50631
+ s0 = peg$FAILED;
50632
+ }
50633
+ } else {
50634
+ peg$currPos = s0;
50635
+ s0 = peg$FAILED;
50636
+ }
50637
+ } else {
50638
+ peg$currPos = s0;
50639
+ s0 = peg$FAILED;
50640
+ }
50641
+ } else {
50642
+ peg$currPos = s0;
50643
+ s0 = peg$FAILED;
50644
+ }
50645
+ } else {
50646
+ peg$currPos = s0;
50647
+ s0 = peg$FAILED;
50648
+ }
50649
+
50650
+ return s0;
50651
+ }
50652
+
50653
+ function peg$parseweek() {
50654
+ var s0;
50655
+
50656
+ if (input.substr(peg$currPos, 4) === peg$c28) {
50657
+ s0 = peg$c28;
50658
+ peg$currPos += 4;
50659
+ } else {
50660
+ s0 = peg$FAILED;
50661
+ if (peg$silentFails === 0) { peg$fail(peg$c29); }
50662
+ }
50663
+
50664
+ return s0;
50665
+ }
50666
+
50667
+ function peg$parseweeks() {
50668
+ var s0;
50669
+
50670
+ if (input.substr(peg$currPos, 5) === peg$c30) {
50671
+ s0 = peg$c30;
50672
+ peg$currPos += 5;
50673
+ } else {
50674
+ s0 = peg$FAILED;
50675
+ if (peg$silentFails === 0) { peg$fail(peg$c31); }
50676
+ }
50677
+
50678
+ return s0;
50679
+ }
50680
+
50681
+ function peg$parseby() {
50682
+ var s0;
50683
+
50684
+ if (input.substr(peg$currPos, 2) === peg$c32) {
50685
+ s0 = peg$c32;
50686
+ peg$currPos += 2;
50687
+ } else {
50688
+ s0 = peg$FAILED;
50689
+ if (peg$silentFails === 0) { peg$fail(peg$c33); }
50690
+ }
50691
+
50692
+ return s0;
50693
+ }
50694
+
50695
+ function peg$parseof() {
50696
+ var s0;
50697
+
50698
+ if (input.substr(peg$currPos, 2) === peg$c34) {
50699
+ s0 = peg$c34;
50700
+ peg$currPos += 2;
50701
+ } else {
50702
+ s0 = peg$FAILED;
50703
+ if (peg$silentFails === 0) { peg$fail(peg$c35); }
50704
+ }
50705
+
50706
+ return s0;
50707
+ }
50708
+
50709
+ function peg$parserepeatEvery() {
50710
+ var s0, s1, s2, s3;
50711
+
50712
+ s0 = peg$currPos;
50713
+ if (input.substr(peg$currPos, 6) === peg$c36) {
50714
+ s1 = peg$c36;
50715
+ peg$currPos += 6;
50716
+ } else {
50717
+ s1 = peg$FAILED;
50718
+ if (peg$silentFails === 0) { peg$fail(peg$c37); }
50719
+ }
50720
+ if (s1 !== peg$FAILED) {
50721
+ s2 = peg$parse_();
50722
+ if (s2 !== peg$FAILED) {
50723
+ if (input.substr(peg$currPos, 5) === peg$c38) {
50724
+ s3 = peg$c38;
50725
+ peg$currPos += 5;
50726
+ } else {
50727
+ s3 = peg$FAILED;
50728
+ if (peg$silentFails === 0) { peg$fail(peg$c39); }
50729
+ }
50730
+ if (s3 !== peg$FAILED) {
50731
+ s1 = [s1, s2, s3];
50732
+ s0 = s1;
50733
+ } else {
50734
+ peg$currPos = s0;
50735
+ s0 = peg$FAILED;
50736
+ }
50737
+ } else {
50738
+ peg$currPos = s0;
50739
+ s0 = peg$FAILED;
50740
+ }
50741
+ } else {
50742
+ peg$currPos = s0;
50743
+ s0 = peg$FAILED;
50744
+ }
50745
+
50746
+ return s0;
50747
+ }
50748
+
50749
+ function peg$parsestarting() {
50750
+ var s0;
50751
+
50752
+ if (input.substr(peg$currPos, 8) === peg$c40) {
50753
+ s0 = peg$c40;
50754
+ peg$currPos += 8;
50755
+ } else {
50756
+ s0 = peg$FAILED;
50757
+ if (peg$silentFails === 0) { peg$fail(peg$c41); }
50758
+ }
50759
+
50760
+ return s0;
50761
+ }
50762
+
50763
+ function peg$parseupTo() {
50764
+ var s0, s1, s2, s3;
50765
+
50766
+ s0 = peg$currPos;
50767
+ if (input.substr(peg$currPos, 2) === peg$c42) {
50768
+ s1 = peg$c42;
50769
+ peg$currPos += 2;
50770
+ } else {
50771
+ s1 = peg$FAILED;
50772
+ if (peg$silentFails === 0) { peg$fail(peg$c43); }
50773
+ }
50774
+ if (s1 !== peg$FAILED) {
50775
+ s2 = peg$parse_();
50776
+ if (s2 !== peg$FAILED) {
50777
+ if (input.substr(peg$currPos, 2) === peg$c44) {
50778
+ s3 = peg$c44;
50779
+ peg$currPos += 2;
50780
+ } else {
50781
+ s3 = peg$FAILED;
50782
+ if (peg$silentFails === 0) { peg$fail(peg$c45); }
50783
+ }
50784
+ if (s3 !== peg$FAILED) {
50785
+ s1 = [s1, s2, s3];
50786
+ s0 = s1;
50787
+ } else {
50788
+ peg$currPos = s0;
50789
+ s0 = peg$FAILED;
50790
+ }
50791
+ } else {
50792
+ peg$currPos = s0;
50793
+ s0 = peg$FAILED;
50794
+ }
50795
+ } else {
50796
+ peg$currPos = s0;
50797
+ s0 = peg$FAILED;
50798
+ }
50799
+
50800
+ return s0;
50801
+ }
50802
+
50803
+ function peg$parse_() {
50804
+ var s0, s1;
50805
+
50806
+ peg$silentFails++;
50807
+ s0 = [];
50808
+ if (input.charCodeAt(peg$currPos) === 32) {
50809
+ s1 = peg$c47;
50810
+ peg$currPos++;
50811
+ } else {
50812
+ s1 = peg$FAILED;
50813
+ if (peg$silentFails === 0) { peg$fail(peg$c48); }
50814
+ }
50815
+ if (s1 !== peg$FAILED) {
50816
+ while (s1 !== peg$FAILED) {
50817
+ s0.push(s1);
50818
+ if (input.charCodeAt(peg$currPos) === 32) {
50819
+ s1 = peg$c47;
50820
+ peg$currPos++;
50821
+ } else {
50822
+ s1 = peg$FAILED;
50823
+ if (peg$silentFails === 0) { peg$fail(peg$c48); }
50824
+ }
50825
+ }
50826
+ } else {
50827
+ s0 = peg$FAILED;
50828
+ }
50829
+ peg$silentFails--;
50830
+ if (s0 === peg$FAILED) {
50831
+ s1 = peg$FAILED;
50832
+ if (peg$silentFails === 0) { peg$fail(peg$c46); }
50833
+ }
50834
+
50835
+ return s0;
50836
+ }
50837
+
50838
+ function peg$parsed() {
50839
+ var s0, s1;
50840
+
50841
+ peg$silentFails++;
50842
+ if (peg$c50.test(input.charAt(peg$currPos))) {
50843
+ s0 = input.charAt(peg$currPos);
50844
+ peg$currPos++;
50845
+ } else {
50846
+ s0 = peg$FAILED;
50847
+ if (peg$silentFails === 0) { peg$fail(peg$c51); }
50848
+ }
50849
+ peg$silentFails--;
50850
+ if (s0 === peg$FAILED) {
50851
+ s1 = peg$FAILED;
50852
+ if (peg$silentFails === 0) { peg$fail(peg$c49); }
50853
+ }
50854
+
50855
+ return s0;
50856
+ }
50857
+
50858
+ function peg$parsenumber() {
50859
+ var s0, s1, s2;
50860
+
50861
+ peg$silentFails++;
50862
+ s0 = peg$currPos;
50863
+ s1 = [];
50864
+ s2 = peg$parsed();
50865
+ if (s2 !== peg$FAILED) {
50866
+ while (s2 !== peg$FAILED) {
50867
+ s1.push(s2);
50868
+ s2 = peg$parsed();
50869
+ }
50870
+ } else {
50871
+ s1 = peg$FAILED;
50872
+ }
50873
+ if (s1 !== peg$FAILED) {
50874
+ s0 = input.substring(s0, peg$currPos);
50875
+ } else {
50876
+ s0 = s1;
50877
+ }
50878
+ peg$silentFails--;
50879
+ if (s0 === peg$FAILED) {
50880
+ s1 = peg$FAILED;
50881
+ if (peg$silentFails === 0) { peg$fail(peg$c52); }
50882
+ }
50883
+
50884
+ return s0;
50885
+ }
50886
+
50887
+ function peg$parseamount() {
50888
+ var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9;
50889
+
50890
+ peg$silentFails++;
50891
+ s0 = peg$currPos;
50892
+ s1 = peg$parsecurrencySymbol();
50893
+ if (s1 === peg$FAILED) {
50894
+ s1 = null;
50895
+ }
50896
+ if (s1 !== peg$FAILED) {
50897
+ s2 = peg$parse_();
50898
+ if (s2 === peg$FAILED) {
50899
+ s2 = null;
50900
+ }
50901
+ if (s2 !== peg$FAILED) {
50902
+ s3 = peg$currPos;
50903
+ s4 = peg$currPos;
50904
+ s5 = [];
50905
+ s6 = peg$parsed();
50906
+ if (s6 !== peg$FAILED) {
50907
+ while (s6 !== peg$FAILED) {
50908
+ s5.push(s6);
50909
+ s6 = peg$parsed();
50910
+ }
50911
+ } else {
50912
+ s5 = peg$FAILED;
50913
+ }
50914
+ if (s5 !== peg$FAILED) {
50915
+ s6 = peg$currPos;
50916
+ if (input.charCodeAt(peg$currPos) === 46) {
50917
+ s7 = peg$c54;
50918
+ peg$currPos++;
50919
+ } else {
50920
+ s7 = peg$FAILED;
50921
+ if (peg$silentFails === 0) { peg$fail(peg$c55); }
50922
+ }
50923
+ if (s7 !== peg$FAILED) {
50924
+ s8 = peg$parsed();
50925
+ if (s8 !== peg$FAILED) {
50926
+ s9 = peg$parsed();
50927
+ if (s9 !== peg$FAILED) {
50928
+ s7 = [s7, s8, s9];
50929
+ s6 = s7;
50930
+ } else {
50931
+ peg$currPos = s6;
50932
+ s6 = peg$FAILED;
50933
+ }
50934
+ } else {
50935
+ peg$currPos = s6;
50936
+ s6 = peg$FAILED;
50937
+ }
50938
+ } else {
50939
+ peg$currPos = s6;
50940
+ s6 = peg$FAILED;
50941
+ }
50942
+ if (s6 === peg$FAILED) {
50943
+ s6 = null;
50944
+ }
50945
+ if (s6 !== peg$FAILED) {
50946
+ s5 = [s5, s6];
50947
+ s4 = s5;
50948
+ } else {
50949
+ peg$currPos = s4;
50950
+ s4 = peg$FAILED;
50951
+ }
50952
+ } else {
50953
+ peg$currPos = s4;
50954
+ s4 = peg$FAILED;
50955
+ }
50956
+ if (s4 !== peg$FAILED) {
50957
+ s3 = input.substring(s3, peg$currPos);
50958
+ } else {
50959
+ s3 = s4;
50960
+ }
50961
+ if (s3 !== peg$FAILED) {
50962
+ peg$savedPos = s0;
50963
+ s1 = peg$c56(s3);
50964
+ s0 = s1;
50965
+ } else {
50966
+ peg$currPos = s0;
50967
+ s0 = peg$FAILED;
50968
+ }
50969
+ } else {
50970
+ peg$currPos = s0;
50971
+ s0 = peg$FAILED;
50972
+ }
50973
+ } else {
50974
+ peg$currPos = s0;
50975
+ s0 = peg$FAILED;
50976
+ }
50977
+ peg$silentFails--;
50978
+ if (s0 === peg$FAILED) {
50979
+ s1 = peg$FAILED;
50980
+ if (peg$silentFails === 0) { peg$fail(peg$c53); }
50981
+ }
50982
+
50983
+ return s0;
50984
+ }
50985
+
50986
+ function peg$parsepercent() {
50987
+ var s0, s1, s2, s3;
50988
+
50989
+ peg$silentFails++;
50990
+ s0 = peg$currPos;
50991
+ s1 = peg$currPos;
50992
+ s2 = [];
50993
+ s3 = peg$parsed();
50994
+ if (s3 !== peg$FAILED) {
50995
+ while (s3 !== peg$FAILED) {
50996
+ s2.push(s3);
50997
+ s3 = peg$parsed();
50998
+ }
50999
+ } else {
51000
+ s2 = peg$FAILED;
51001
+ }
51002
+ if (s2 !== peg$FAILED) {
51003
+ s1 = input.substring(s1, peg$currPos);
51004
+ } else {
51005
+ s1 = s2;
51006
+ }
51007
+ if (s1 !== peg$FAILED) {
51008
+ s2 = peg$parse_();
51009
+ if (s2 === peg$FAILED) {
51010
+ s2 = null;
51011
+ }
51012
+ if (s2 !== peg$FAILED) {
51013
+ if (input.charCodeAt(peg$currPos) === 37) {
51014
+ s3 = peg$c58;
51015
+ peg$currPos++;
51016
+ } else {
51017
+ s3 = peg$FAILED;
51018
+ if (peg$silentFails === 0) { peg$fail(peg$c59); }
51019
+ }
51020
+ if (s3 !== peg$FAILED) {
51021
+ peg$savedPos = s0;
51022
+ s1 = peg$c60(s1);
51023
+ s0 = s1;
51024
+ } else {
51025
+ peg$currPos = s0;
51026
+ s0 = peg$FAILED;
51027
+ }
51028
+ } else {
51029
+ peg$currPos = s0;
51030
+ s0 = peg$FAILED;
51031
+ }
51032
+ } else {
51033
+ peg$currPos = s0;
51034
+ s0 = peg$FAILED;
51035
+ }
51036
+ peg$silentFails--;
51037
+ if (s0 === peg$FAILED) {
51038
+ s1 = peg$FAILED;
51039
+ if (peg$silentFails === 0) { peg$fail(peg$c57); }
51040
+ }
51041
+
51042
+ return s0;
51043
+ }
51044
+
51045
+ function peg$parseyear() {
51046
+ var s0, s1, s2, s3, s4, s5;
51047
+
51048
+ peg$silentFails++;
51049
+ s0 = peg$currPos;
51050
+ s1 = peg$currPos;
51051
+ s2 = peg$parsed();
51052
+ if (s2 !== peg$FAILED) {
51053
+ s3 = peg$parsed();
51054
+ if (s3 !== peg$FAILED) {
51055
+ s4 = peg$parsed();
51056
+ if (s4 !== peg$FAILED) {
51057
+ s5 = peg$parsed();
51058
+ if (s5 !== peg$FAILED) {
51059
+ s2 = [s2, s3, s4, s5];
51060
+ s1 = s2;
51061
+ } else {
51062
+ peg$currPos = s1;
51063
+ s1 = peg$FAILED;
51064
+ }
51065
+ } else {
51066
+ peg$currPos = s1;
51067
+ s1 = peg$FAILED;
51068
+ }
51069
+ } else {
51070
+ peg$currPos = s1;
51071
+ s1 = peg$FAILED;
51072
+ }
51073
+ } else {
51074
+ peg$currPos = s1;
51075
+ s1 = peg$FAILED;
51076
+ }
51077
+ if (s1 !== peg$FAILED) {
51078
+ s0 = input.substring(s0, peg$currPos);
51079
+ } else {
51080
+ s0 = s1;
51081
+ }
51082
+ peg$silentFails--;
51083
+ if (s0 === peg$FAILED) {
51084
+ s1 = peg$FAILED;
51085
+ if (peg$silentFails === 0) { peg$fail(peg$c61); }
51086
+ }
51087
+
51088
+ return s0;
51089
+ }
51090
+
51091
+ function peg$parsemonth() {
51092
+ var s0, s1, s2, s3, s4, s5;
51093
+
51094
+ peg$silentFails++;
51095
+ s0 = peg$currPos;
51096
+ s1 = peg$currPos;
51097
+ s2 = peg$parseyear();
51098
+ if (s2 !== peg$FAILED) {
51099
+ if (input.charCodeAt(peg$currPos) === 45) {
51100
+ s3 = peg$c63;
51101
+ peg$currPos++;
51102
+ } else {
51103
+ s3 = peg$FAILED;
51104
+ if (peg$silentFails === 0) { peg$fail(peg$c64); }
51105
+ }
51106
+ if (s3 !== peg$FAILED) {
51107
+ s4 = peg$parsed();
51108
+ if (s4 !== peg$FAILED) {
51109
+ s5 = peg$parsed();
51110
+ if (s5 !== peg$FAILED) {
51111
+ s2 = [s2, s3, s4, s5];
51112
+ s1 = s2;
51113
+ } else {
51114
+ peg$currPos = s1;
51115
+ s1 = peg$FAILED;
51116
+ }
51117
+ } else {
51118
+ peg$currPos = s1;
51119
+ s1 = peg$FAILED;
51120
+ }
51121
+ } else {
51122
+ peg$currPos = s1;
51123
+ s1 = peg$FAILED;
51124
+ }
51125
+ } else {
51126
+ peg$currPos = s1;
51127
+ s1 = peg$FAILED;
51128
+ }
51129
+ if (s1 !== peg$FAILED) {
51130
+ s0 = input.substring(s0, peg$currPos);
51131
+ } else {
51132
+ s0 = s1;
51133
+ }
51134
+ peg$silentFails--;
51135
+ if (s0 === peg$FAILED) {
51136
+ s1 = peg$FAILED;
51137
+ if (peg$silentFails === 0) { peg$fail(peg$c62); }
51138
+ }
51139
+
51140
+ return s0;
49638
51141
  }
49639
51142
 
49640
- months.forEach(month => {
49641
- if (!meta.createdMonths.has(month)) {
49642
- let prevMonth = _shared_months__WEBPACK_IMPORTED_MODULE_0__["prevMonth"](month);
49643
-
49644
- let _monthUtils$bounds2 = _shared_months__WEBPACK_IMPORTED_MODULE_0__["bounds"](month),
49645
- start = _monthUtils$bounds2.start,
49646
- end = _monthUtils$bounds2.end;
49647
-
49648
- let sheetName = _shared_months__WEBPACK_IMPORTED_MODULE_0__["sheetForMonth"](month, budgetType);
49649
- let prevSheetName = _shared_months__WEBPACK_IMPORTED_MODULE_0__["sheetForMonth"](prevMonth, budgetType);
49650
- categories.forEach(cat => {
49651
- createCategory(cat, sheetName, prevSheetName, start, end);
49652
- });
49653
- groups.forEach(group => {
49654
- createCategoryGroup(group, sheetName);
49655
- });
51143
+ function peg$parseday() {
51144
+ var s0, s1, s2, s3;
49656
51145
 
49657
- if (budgetType === 'rollover') {
49658
- _rollover__WEBPACK_IMPORTED_MODULE_7__["createSummary"](groups, categories, prevSheetName, sheetName);
51146
+ peg$silentFails++;
51147
+ s0 = peg$currPos;
51148
+ s1 = peg$currPos;
51149
+ s2 = peg$parsed();
51150
+ if (s2 !== peg$FAILED) {
51151
+ s3 = peg$parsed();
51152
+ if (s3 !== peg$FAILED) {
51153
+ s2 = [s2, s3];
51154
+ s1 = s2;
49659
51155
  } else {
49660
- _report__WEBPACK_IMPORTED_MODULE_6__["createSummary"](groups, categories, sheetName);
51156
+ peg$currPos = s1;
51157
+ s1 = peg$FAILED;
49661
51158
  }
49662
-
49663
- meta.createdMonths.add(month);
51159
+ } else {
51160
+ peg$currPos = s1;
51161
+ s1 = peg$FAILED;
51162
+ }
51163
+ if (s1 !== peg$FAILED) {
51164
+ s0 = input.substring(s0, peg$currPos);
51165
+ } else {
51166
+ s0 = s1;
51167
+ }
51168
+ peg$silentFails--;
51169
+ if (s0 === peg$FAILED) {
51170
+ s1 = peg$FAILED;
51171
+ if (peg$silentFails === 0) { peg$fail(peg$c65); }
49664
51172
  }
49665
- });
49666
- _sheet__WEBPACK_IMPORTED_MODULE_3__["get"]().setMeta(meta);
49667
- _sheet__WEBPACK_IMPORTED_MODULE_3__["endTransaction"](); // Wait for the spreadsheet to finish computing. Normally this won't
49668
- // do anything (as values are cached) but on first run this need to
49669
- // show the loading screen while it initially sets up.
49670
51173
 
49671
- await _sheet__WEBPACK_IMPORTED_MODULE_3__["waitOnSpreadsheet"]();
49672
- }
49673
- async function createAllBudgets() {
49674
- let earliestTransaction = await _db__WEBPACK_IMPORTED_MODULE_2__["first"]('SELECT * FROM transactions WHERE isChild=0 AND date IS NOT NULL ORDER BY date ASC LIMIT 1');
49675
- let earliestDate = earliestTransaction && _db__WEBPACK_IMPORTED_MODULE_2__["fromDateRepr"](earliestTransaction.date);
49676
- let currentMonth = _shared_months__WEBPACK_IMPORTED_MODULE_0__["currentMonth"](); // Get the range based off of the earliest transaction and the
49677
- // current month. If no transactions currently exist the current
49678
- // month is also used as the starting month
51174
+ return s0;
51175
+ }
49679
51176
 
49680
- let _getBudgetRange = getBudgetRange(earliestDate || currentMonth, currentMonth),
49681
- start = _getBudgetRange.start,
49682
- end = _getBudgetRange.end,
49683
- range = _getBudgetRange.range;
51177
+ function peg$parsedate() {
51178
+ var s0, s1, s2, s3, s4;
49684
51179
 
49685
- let meta = _sheet__WEBPACK_IMPORTED_MODULE_3__["get"]().meta();
49686
- let createdMonths = meta.createdMonths || new Set();
49687
- let newMonths = range.filter(m => !createdMonths.has(m));
51180
+ s0 = peg$currPos;
51181
+ s1 = peg$currPos;
51182
+ s2 = peg$parsemonth();
51183
+ if (s2 !== peg$FAILED) {
51184
+ if (input.charCodeAt(peg$currPos) === 45) {
51185
+ s3 = peg$c63;
51186
+ peg$currPos++;
51187
+ } else {
51188
+ s3 = peg$FAILED;
51189
+ if (peg$silentFails === 0) { peg$fail(peg$c64); }
51190
+ }
51191
+ if (s3 !== peg$FAILED) {
51192
+ s4 = peg$parseday();
51193
+ if (s4 !== peg$FAILED) {
51194
+ s2 = [s2, s3, s4];
51195
+ s1 = s2;
51196
+ } else {
51197
+ peg$currPos = s1;
51198
+ s1 = peg$FAILED;
51199
+ }
51200
+ } else {
51201
+ peg$currPos = s1;
51202
+ s1 = peg$FAILED;
51203
+ }
51204
+ } else {
51205
+ peg$currPos = s1;
51206
+ s1 = peg$FAILED;
51207
+ }
51208
+ if (s1 !== peg$FAILED) {
51209
+ s0 = input.substring(s0, peg$currPos);
51210
+ } else {
51211
+ s0 = s1;
51212
+ }
49688
51213
 
49689
- if (newMonths.length > 0) {
49690
- await createBudget(range);
51214
+ return s0;
49691
51215
  }
49692
51216
 
49693
- return {
49694
- start,
49695
- end
49696
- };
49697
- }
49698
- async function setType(type) {
49699
- let meta = _sheet__WEBPACK_IMPORTED_MODULE_3__["get"]().meta();
51217
+ function peg$parsecurrencySymbol() {
51218
+ var s0, s1, s2;
49700
51219
 
49701
- if (type === meta.budgetType) {
49702
- return;
49703
- }
51220
+ peg$silentFails++;
51221
+ s0 = peg$currPos;
51222
+ if (input.length > peg$currPos) {
51223
+ s1 = input.charAt(peg$currPos);
51224
+ peg$currPos++;
51225
+ } else {
51226
+ s1 = peg$FAILED;
51227
+ if (peg$silentFails === 0) { peg$fail(peg$c67); }
51228
+ }
51229
+ if (s1 !== peg$FAILED) {
51230
+ peg$savedPos = peg$currPos;
51231
+ s2 = peg$c68(s1);
51232
+ if (s2) {
51233
+ s2 = void 0;
51234
+ } else {
51235
+ s2 = peg$FAILED;
51236
+ }
51237
+ if (s2 !== peg$FAILED) {
51238
+ s1 = [s1, s2];
51239
+ s0 = s1;
51240
+ } else {
51241
+ peg$currPos = s0;
51242
+ s0 = peg$FAILED;
51243
+ }
51244
+ } else {
51245
+ peg$currPos = s0;
51246
+ s0 = peg$FAILED;
51247
+ }
51248
+ peg$silentFails--;
51249
+ if (s0 === peg$FAILED) {
51250
+ s1 = peg$FAILED;
51251
+ if (peg$silentFails === 0) { peg$fail(peg$c66); }
51252
+ }
49704
51253
 
49705
- meta.budgetType = type;
49706
- meta.createdMonths = new Set(); // Go through and force all the cells to be recomputed
51254
+ return s0;
51255
+ }
49707
51256
 
49708
- let nodes = _sheet__WEBPACK_IMPORTED_MODULE_3__["get"]().getNodes();
49709
- _db__WEBPACK_IMPORTED_MODULE_2__["transaction"](() => {
49710
- for (let name of nodes.keys()) {
49711
- let _name$split = name.split('!'),
49712
- _name$split2 = _slicedToArray(_name$split, 2),
49713
- sheetName = _name$split2[0],
49714
- cellName = _name$split2[1];
51257
+ peg$result = peg$startRuleFunction();
49715
51258
 
49716
- if (sheetName.match(/^budget\d+/)) {
49717
- _sheet__WEBPACK_IMPORTED_MODULE_3__["get"]().deleteCell(sheetName, cellName);
49718
- }
51259
+ if (peg$result !== peg$FAILED && peg$currPos === input.length) {
51260
+ return peg$result;
51261
+ } else {
51262
+ if (peg$result !== peg$FAILED && peg$currPos < input.length) {
51263
+ peg$fail(peg$endExpectation());
49719
51264
  }
49720
- });
49721
- _sheet__WEBPACK_IMPORTED_MODULE_3__["get"]().startCacheBarrier();
49722
- _sheet__WEBPACK_IMPORTED_MODULE_3__["loadUserBudgets"](_db__WEBPACK_IMPORTED_MODULE_2__);
49723
- let bounds = await createAllBudgets();
49724
- _sheet__WEBPACK_IMPORTED_MODULE_3__["get"]().endCacheBarrier();
49725
- return bounds;
51265
+
51266
+ throw peg$buildStructuredError(
51267
+ peg$maxFailExpected,
51268
+ peg$maxFailPos < input.length ? input.charAt(peg$maxFailPos) : null,
51269
+ peg$maxFailPos < input.length
51270
+ ? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1)
51271
+ : peg$computeLocation(peg$maxFailPos, peg$maxFailPos)
51272
+ );
51273
+ }
49726
51274
  }
49727
51275
 
51276
+ module.exports = {
51277
+ SyntaxError: peg$SyntaxError,
51278
+ parse: peg$parse
51279
+ };
51280
+
51281
+
49728
51282
  /***/ }),
49729
51283
 
49730
51284
  /***/ "./packages/loot-core/src/server/budget/goaltemplates.js":
@@ -49743,24 +51297,28 @@ __webpack_require__.r(__webpack_exports__);
49743
51297
  /* harmony import */ var _shared_util__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../shared/util */ "./packages/loot-core/src/shared/util.js");
49744
51298
  /* harmony import */ var _db__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../db */ "./packages/loot-core/src/server/db/index.js");
49745
51299
  /* harmony import */ var _actions__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./actions */ "./packages/loot-core/src/server/budget/actions.js");
51300
+ /* harmony import */ var _goal_template_pegjs__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./goal-template.pegjs */ "./packages/loot-core/src/server/budget/goal-template.pegjs");
51301
+ /* harmony import */ var _goal_template_pegjs__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_goal_template_pegjs__WEBPACK_IMPORTED_MODULE_5__);
49746
51302
 
49747
51303
 
49748
51304
 
49749
51305
 
49750
51306
 
49751
- async function applyTemplate({
51307
+
51308
+ function applyTemplate({
49752
51309
  month
49753
51310
  }) {
49754
- await processTemplate(month, false);
51311
+ return processTemplate(month, false);
49755
51312
  }
49756
- async function overwriteTemplate({
51313
+ function overwriteTemplate({
49757
51314
  month
49758
51315
  }) {
49759
- await processTemplate(month, true);
51316
+ return processTemplate(month, true);
49760
51317
  }
49761
51318
 
49762
51319
  async function processTemplate(month, force) {
49763
51320
  let category_templates = await getCategoryTemplates();
51321
+ let errors = [];
49764
51322
  let categories = await _db__WEBPACK_IMPORTED_MODULE_3__["all"]('SELECT * FROM v_categories WHERE tombstone = 0');
49765
51323
  let num_applied = 0;
49766
51324
 
@@ -49772,6 +51330,10 @@ async function processTemplate(month, force) {
49772
51330
  let template = category_templates[category.id];
49773
51331
 
49774
51332
  if (template) {
51333
+ errors = errors.concat(template.filter(t => t.type === 'error').map(({
51334
+ line,
51335
+ error
51336
+ }) => [category.name + ': ' + error.message, line, ' '.repeat(TEMPLATE_PREFIX.length + error.location.start.offset) + '^'].join('\n')));
49775
51337
  let to_budget = await applyCategoryTemplate(category, template, month, force);
49776
51338
 
49777
51339
  if (to_budget != null) {
@@ -49787,122 +51349,61 @@ async function processTemplate(month, force) {
49787
51349
  }
49788
51350
 
49789
51351
  if (num_applied === 0) {
49790
- console.log('All categories were up to date.');
51352
+ if (errors.length) {
51353
+ return {
51354
+ type: 'error',
51355
+ sticky: true,
51356
+ message: `There were errors interpreting some templates:`,
51357
+ pre: errors.join('\n\n')
51358
+ };
51359
+ } else {
51360
+ return {
51361
+ type: 'message',
51362
+ message: 'All categories were up to date.'
51363
+ };
51364
+ }
49791
51365
  } else {
49792
- console.log(`${num_applied} categories updated.`);
51366
+ let applied = `Successfully applied templates to ${num_applied} ${num_applied === 1 ? 'category' : 'categories'}.`;
51367
+
51368
+ if (errors.length) {
51369
+ return {
51370
+ sticky: true,
51371
+ message: `${applied} There were errors interpreting some templates:`,
51372
+ pre: errors.join('\n\n')
51373
+ };
51374
+ } else {
51375
+ return {
51376
+ type: 'message',
51377
+ message: applied
51378
+ };
51379
+ }
49793
51380
  }
49794
51381
  }
49795
51382
 
51383
+ const TEMPLATE_PREFIX = '#template ';
51384
+
49796
51385
  async function getCategoryTemplates() {
49797
- const matches = [{
49798
- type: 'simple',
49799
- re: /^#template \$?(\-?\d+(\.\d{2})?)$/im,
49800
- //eslint-disable-line
49801
- params: ['monthly']
49802
- }, {
49803
- type: 'simple',
49804
- re: /^#template up to \$?(\d+(\.\d{2})?)$/im,
49805
- params: ['limit']
49806
- }, {
49807
- type: 'simple',
49808
- re: /^#template \$?(\d+(\.\d{2})?) up to \$?(\d+(\.\d{2})?)$/im,
49809
- params: ['monthly', null, 'limit']
49810
- }, {
49811
- type: 'by',
49812
- re: /^#template \$?(\d+(\.\d{2})?) by (\d{4}\-\d{2})$/im,
49813
- //eslint-disable-line
49814
- params: ['amount', null, 'month']
49815
- }, {
49816
- type: 'by',
49817
- re: /^#template \$?(\d+(\.\d{2})?) by (\d{4}\-\d{2}) repeat every (\d+) months$/im,
49818
- //eslint-disable-line
49819
- params: ['amount', null, 'month', 'repeat']
49820
- }, {
49821
- type: 'week',
49822
- re: /^#template \$?(\d+(\.\d{2})?) repeat every week starting (\d{4}\-\d{2}\-\d{2})$/im,
49823
- //eslint-disable-line
49824
- params: ['amount', null, 'starting']
49825
- }, {
49826
- type: 'week',
49827
- re: /^#template \$?(\d+(\.\d{2})?) repeat every week starting (\d{4}\-\d{2}\-\d{2}) up to \$?(\d+(\.\d{2})?)$/im,
49828
- //eslint-disable-line
49829
- params: ['amount', null, 'starting', 'limit']
49830
- }, {
49831
- type: 'weeks',
49832
- re: /^#template \$?(\d+(\.\d{2})?) repeat every (\d+) weeks starting (\d{4}\-\d{2}\-\d{2})$/im,
49833
- //eslint-disable-line
49834
- params: ['amount', null, 'weeks', 'starting']
49835
- }, {
49836
- type: 'weeks',
49837
- re: /^#template \$?(\d+(\.\d{2})?) repeat every (\d+) weeks starting (\d{4}\-\d{2}\-\d{2}) up to \$?(\d+(\.\d{2})?)$/im,
49838
- //eslint-disable-line
49839
- params: ['amount', null, 'weeks', 'starting', 'limit']
49840
- }, {
49841
- type: 'by_annual',
49842
- re: /^#template \$?(\d+(\.\d{2})?) by (\d{4}\-\d{2}) repeat every year$/im,
49843
- //eslint-disable-line
49844
- params: ['amount', null, 'month']
49845
- }, {
49846
- type: 'by_annual',
49847
- re: /^#template \$?(\d+(\.\d{2})?) by (\d{4}\-\d{2}) repeat every (\d+) years$/im,
49848
- //eslint-disable-line
49849
- params: ['amount', null, 'month', 'repeat']
49850
- }, {
49851
- type: 'spend',
49852
- re: /^#template \$?(\d+(\.\d{2})?) by (\d{4}\-\d{2}) spend from (\d{4}\-\d{2})$/im,
49853
- //eslint-disable-line
49854
- params: ['amount', null, 'month', 'from']
49855
- }, {
49856
- type: 'spend',
49857
- re: /^#template \$?(\d+(\.\d{2})?) by (\d{4}\-\d{2}) spend from (\d{4}\-\d{2}) repeat every (\d+) months$/im,
49858
- //eslint-disable-line
49859
- params: ['amount', null, 'month', 'from', 'repeat']
49860
- }, {
49861
- type: 'spend_annual',
49862
- re: /^#template \$?(\d+(\.\d{2})?) by (\d{4}\-\d{2}) spend from (\d{4}\-\d{2}) repeat every year$/im,
49863
- //eslint-disable-line
49864
- params: ['amount', null, 'month', 'from']
49865
- }, {
49866
- type: 'spend_annual',
49867
- re: /^#template \$?(\d+(\.\d{2})?) by (\d{4}\-\d{2}) spend from (\d{4}\-\d{2}) repeat every (\d+) years$/im,
49868
- //eslint-disable-line
49869
- params: ['amount', null, 'month', 'from', 'repeat']
49870
- }, {
49871
- type: 'percentage',
49872
- re: /^#template (\d+(\.\d+)?)% of (.*)$/im,
49873
- params: ['percent', null, 'category']
49874
- }, {
49875
- type: 'error',
49876
- re: /^#template .*$/im,
49877
- params: []
49878
- }];
49879
51386
  let templates = {};
49880
- let notes = await _db__WEBPACK_IMPORTED_MODULE_3__["all"](`SELECT * FROM notes WHERE note like '%#template%'`);
51387
+ let notes = await _db__WEBPACK_IMPORTED_MODULE_3__["all"](`SELECT * FROM notes WHERE lower(note) like '%${TEMPLATE_PREFIX}%'`);
49881
51388
 
49882
51389
  for (let n = 0; n < notes.length; n++) {
49883
51390
  let lines = notes[n].note.split('\n');
49884
51391
  let template_lines = [];
49885
51392
 
49886
51393
  for (let l = 0; l < lines.length; l++) {
49887
- for (let m = 0; m < matches.length; m++) {
49888
- let arr = matches[m].re.exec(lines[l]);
49889
-
49890
- if (arr) {
49891
- let matched = {};
49892
- matched.line = arr[0];
49893
- matched.type = matches[m].type;
49894
-
49895
- for (let p = 0; p < matches[m].params.length; p++) {
49896
- let param_name = matches[m].params[p];
49897
-
49898
- if (param_name) {
49899
- matched[param_name] = arr[p + 1];
49900
- }
49901
- }
51394
+ let line = lines[l].trim();
51395
+ if (!line.toLowerCase().startsWith(TEMPLATE_PREFIX)) continue;
51396
+ let expression = line.slice(TEMPLATE_PREFIX.length);
49902
51397
 
49903
- template_lines.push(matched);
49904
- break;
49905
- }
51398
+ try {
51399
+ let parsed = Object(_goal_template_pegjs__WEBPACK_IMPORTED_MODULE_5__["parse"])(expression);
51400
+ template_lines.push(parsed);
51401
+ } catch (e) {
51402
+ template_lines.push({
51403
+ type: 'error',
51404
+ line,
51405
+ error: e
51406
+ });
49906
51407
  }
49907
51408
  }
49908
51409
 
@@ -49922,15 +51423,13 @@ async function applyCategoryTemplate(category, template_lines, month, force) {
49922
51423
  //debugger;
49923
51424
  switch (template.type) {
49924
51425
  case 'by':
49925
- case 'by_annual':
49926
51426
  case 'spend':
49927
- case 'spend_annual':
49928
51427
  let target_month = new Date(`${template.month}-01`);
49929
51428
  let num_months = Object(date_fns__WEBPACK_IMPORTED_MODULE_0__["differenceInCalendarMonths"])(target_month, current_month);
49930
- let repeat = template.type.includes('annual') ? (template.repeat || 1) * 12 : template.repeat;
51429
+ let repeat = template.annual ? (template.repeat || 1) * 12 : template.repeat;
49931
51430
  let spend_from;
49932
51431
 
49933
- if (template.type.includes('spend')) {
51432
+ if (template.type === 'spend') {
49934
51433
  spend_from = new Date(`${template.from}-01`);
49935
51434
  }
49936
51435
 
@@ -49965,13 +51464,13 @@ async function applyCategoryTemplate(category, template_lines, month, force) {
49965
51464
 
49966
51465
  if (template_lines.length > 1) {
49967
51466
  template_lines = template_lines.sort((a, b) => {
49968
- if (a.type.slice(0, 2) === b.type.slice(0, 2) && a.type.slice(0, 2) === 'by') {
51467
+ if (a.type === 'by' && !a.annual) {
49969
51468
  return Object(date_fns__WEBPACK_IMPORTED_MODULE_0__["differenceInCalendarMonths"])(new Date(`${a.month}-01`), new Date(`${b.month}-01`));
49970
51469
  } else {
49971
51470
  return a.type.localeCompare(b.type);
49972
51471
  }
49973
51472
  }).filter(el => {
49974
- if (el.type.slice(0, 2) === 'by') {
51473
+ if (el.type === 'by') {
49975
51474
  if (!got_by) {
49976
51475
  got_by = true;
49977
51476
  return el;
@@ -50019,7 +51518,6 @@ async function applyCategoryTemplate(category, template_lines, month, force) {
50019
51518
  }
50020
51519
 
50021
51520
  case 'by':
50022
- case 'by_annual':
50023
51521
  {
50024
51522
  // by has 'amount' and 'month' params
50025
51523
  let target_month = new Date(`${template.month}-01`);
@@ -50042,10 +51540,8 @@ async function applyCategoryTemplate(category, template_lines, month, force) {
50042
51540
  }
50043
51541
 
50044
51542
  case 'week':
50045
- case 'weeks':
50046
51543
  {
50047
- // weeks has 'amount', 'starting' and optional 'limit' params
50048
- // weeks has 'amount', 'starting', 'weeks' and optional 'limit' params
51544
+ // week has 'amount', 'starting', 'weeks' and optional 'limit' params
50049
51545
  let amount = Object(_shared_util__WEBPACK_IMPORTED_MODULE_2__["amountToInteger"])(template.amount);
50050
51546
  let weeks = template.weeks != null ? Math.round(template.weeks) : 1;
50051
51547
 
@@ -50073,7 +51569,6 @@ async function applyCategoryTemplate(category, template_lines, month, force) {
50073
51569
  }
50074
51570
 
50075
51571
  case 'spend':
50076
- case 'spend_annual':
50077
51572
  {
50078
51573
  // spend has 'amount' and 'from' and 'month' params
50079
51574
  let from_month = new Date(`${template.from}-01`);
@@ -50129,7 +51624,6 @@ async function applyCategoryTemplate(category, template_lines, month, force) {
50129
51624
  }
50130
51625
 
50131
51626
  case 'error':
50132
- console.log(`${category.name}: ${`Failed to match:`} ${template.line}`);
50133
51627
  return null;
50134
51628
 
50135
51629
  default:
@@ -53507,7 +55001,7 @@ handlers['account-create'] = Object(_mutators__WEBPACK_IMPORTED_MODULE_33__["mut
53507
55001
  transfer_acct: id
53508
55002
  });
53509
55003
 
53510
- if (balance != null) {
55004
+ if (balance != null && balance !== 0) {
53511
55005
  let payee = await Object(_accounts_payees__WEBPACK_IMPORTED_MODULE_16__["getStartingBalancePayee"])();
53512
55006
  await _db__WEBPACK_IMPORTED_MODULE_28__["insertTransaction"]({
53513
55007
  account: id,
@@ -53748,7 +55242,7 @@ handlers['accounts-sync'] = async function ({
53748
55242
  } else {
53749
55243
  errors.push({
53750
55244
  accountId: acct.id,
53751
- message: 'There was an internal error. Please email help@actualbudget.com for support.',
55245
+ message: 'There was an internal error. Please get in touch https://actualbudget.github.io/docs/Contact for support.',
53752
55246
  internal: err.stack
53753
55247
  });
53754
55248
  err.message = 'Failed syncing account: ' + err.message;
@@ -54064,22 +55558,13 @@ handlers['key-test'] = async function ({
54064
55558
  return {};
54065
55559
  };
54066
55560
 
54067
- handlers['should-pitch-subscribe'] = async function () {
54068
- let seenSubscribe = await _platform_server_asyncStorage__WEBPACK_IMPORTED_MODULE_4___default.a.getItem('seenSubscribe');
54069
- return seenSubscribe !== 'true';
54070
- };
54071
-
54072
- handlers['has-pitched-subscribe'] = async function () {
54073
- await _platform_server_asyncStorage__WEBPACK_IMPORTED_MODULE_4___default.a.setItem('seenSubscribe', 'true');
54074
- return 'ok';
54075
- };
54076
-
54077
55561
  handlers['subscribe-needs-bootstrap'] = async function ({
54078
55562
  url
54079
55563
  } = {}) {
54080
55564
  if (Object(_server_config__WEBPACK_IMPORTED_MODULE_39__["getServer"])(url).BASE_SERVER === UNCONFIGURED_SERVER) {
54081
55565
  return {
54082
- bootstrapped: true
55566
+ bootstrapped: true,
55567
+ hasServer: false
54083
55568
  };
54084
55569
  }
54085
55570
 
@@ -54108,7 +55593,8 @@ handlers['subscribe-needs-bootstrap'] = async function ({
54108
55593
  }
54109
55594
 
54110
55595
  return {
54111
- bootstrapped: res.data.bootstrapped
55596
+ bootstrapped: res.data.bootstrapped,
55597
+ hasServer: true
54112
55598
  };
54113
55599
  };
54114
55600
 
@@ -54256,19 +55742,22 @@ handlers['get-server-url'] = async function () {
54256
55742
  };
54257
55743
 
54258
55744
  handlers['set-server-url'] = async function ({
54259
- url
55745
+ url,
55746
+ validate = true
54260
55747
  }) {
54261
55748
  if (url != null) {
54262
- // Validate the server is running
54263
- let _await$runHandler = await Object(_mutators__WEBPACK_IMPORTED_MODULE_33__["runHandler"])(handlers['subscribe-needs-bootstrap'], {
54264
- url
54265
- }),
54266
- error = _await$runHandler.error;
55749
+ if (validate) {
55750
+ // Validate the server is running
55751
+ let _await$runHandler = await Object(_mutators__WEBPACK_IMPORTED_MODULE_33__["runHandler"])(handlers['subscribe-needs-bootstrap'], {
55752
+ url
55753
+ }),
55754
+ error = _await$runHandler.error;
54267
55755
 
54268
- if (error) {
54269
- return {
54270
- error
54271
- };
55756
+ if (error) {
55757
+ return {
55758
+ error
55759
+ };
55760
+ }
54272
55761
  }
54273
55762
  } else {
54274
55763
  // When the server isn't configured, we just use a placeholder
@@ -54408,26 +55897,31 @@ handlers['download-budget'] = async function ({
54408
55897
  }
54409
55898
  }
54410
55899
 
54411
- let id = result.id; // Load the budget and do a full sync
54412
-
54413
- result = await loadBudget(result.id, VERSION, {
54414
- showUpdate: true
55900
+ let id = result.id;
55901
+ await handlers['load-budget']({
55902
+ id
54415
55903
  });
55904
+ result = await handlers['sync-budget']({
55905
+ id
55906
+ });
55907
+ await handlers['close-budget']();
54416
55908
 
54417
55909
  if (result.error) {
54418
- return {
54419
- error: {
54420
- reason: result.error
54421
- }
54422
- };
55910
+ return result;
54423
55911
  }
54424
55912
 
54425
- Object(_sync__WEBPACK_IMPORTED_MODULE_41__["setSyncingMode"])('enabled');
54426
- await Object(_sync__WEBPACK_IMPORTED_MODULE_41__["initialFullSync"])();
54427
- await handlers['close-budget']();
54428
55913
  return {
54429
55914
  id
54430
55915
  };
55916
+ }; // open and sync, but don’t close
55917
+
55918
+
55919
+ handlers['sync-budget'] = async function ({
55920
+ id
55921
+ }) {
55922
+ Object(_sync__WEBPACK_IMPORTED_MODULE_41__["setSyncingMode"])('enabled');
55923
+ await Object(_sync__WEBPACK_IMPORTED_MODULE_41__["initialFullSync"])();
55924
+ return {};
54431
55925
  };
54432
55926
 
54433
55927
  handlers['load-budget'] = async function ({
@@ -54992,10 +56486,7 @@ async function initApp(version, isDev, socketName) {
54992
56486
  global.$setSyncingMode = _sync__WEBPACK_IMPORTED_MODULE_41__["setSyncingMode"];
54993
56487
  }
54994
56488
  }
54995
- async function init({
54996
- budgetId,
54997
- config
54998
- }) {
56489
+ async function init(config) {
54999
56490
  // Get from build
55000
56491
  // eslint-disable-next-line
55001
56492
  VERSION = "0.0.147";
@@ -55018,6 +56509,12 @@ async function init({
55018
56509
 
55019
56510
  if (serverURL) {
55020
56511
  Object(_server_config__WEBPACK_IMPORTED_MODULE_39__["setServer"])(serverURL);
56512
+
56513
+ if (config.password) {
56514
+ await Object(_mutators__WEBPACK_IMPORTED_MODULE_33__["runHandler"])(handlers['subscribe-sign-in'], {
56515
+ password: config.password
56516
+ });
56517
+ }
55021
56518
  } else {
55022
56519
  // This turns off all server URLs. In this mode we don't want any
55023
56520
  // access to the server, we are doing things locally
@@ -55027,12 +56524,6 @@ async function init({
55027
56524
  });
55028
56525
  }
55029
56526
 
55030
- if (budgetId) {
55031
- await Object(_mutators__WEBPACK_IMPORTED_MODULE_33__["runHandler"])(handlers['load-budget'], {
55032
- id: budgetId
55033
- });
55034
- }
55035
-
55036
56527
  return lib;
55037
56528
  } // Export a few things required for the platform
55038
56529
 
@@ -57419,7 +58910,7 @@ class Spreadsheet {
57419
58910
  result = node._run(...args);
57420
58911
 
57421
58912
  if (result instanceof Promise) {
57422
- console.warn('dynamic cell returned a promise! this is discouraged because errors are not handled properly');
58913
+ console.warn(`dynamic cell ${name} returned a promise! this is discouraged because errors are not handled properly`);
57423
58914
  }
57424
58915
  } else if (node.sql) {
57425
58916
  result = Object(_aql__WEBPACK_IMPORTED_MODULE_1__["runCompiledQuery"])(node.query, node.sql.sqlPieces, node.sql.state);
@@ -58088,9 +59579,9 @@ function apply(msg, prev) {
58088
59579
 
58089
59580
  if (dataset === 'prefs') {// Do nothing, it doesn't exist in the db
58090
59581
  } else {
58091
- try {
58092
- let query;
59582
+ let query;
58093
59583
 
59584
+ try {
58094
59585
  if (prev) {
58095
59586
  query = {
58096
59587
  sql: _db__WEBPACK_IMPORTED_MODULE_7__["cache"](`UPDATE ${dataset} SET ${column} = ? WHERE id = ?`),
@@ -58104,9 +59595,14 @@ function apply(msg, prev) {
58104
59595
  }
58105
59596
 
58106
59597
  _db__WEBPACK_IMPORTED_MODULE_7__["runQuery"](query.sql, query.params);
58107
- } catch (e) {
58108
- //console.log(e);
58109
- throw new SyncError('invalid-schema');
59598
+ } catch (error) {
59599
+ throw new SyncError('invalid-schema', {
59600
+ error: {
59601
+ message: error.message,
59602
+ stack: error.stack
59603
+ },
59604
+ query
59605
+ });
58110
59606
  }
58111
59607
  }
58112
59608
  }
@@ -58139,8 +59635,12 @@ async function fetchAll(table, ids) {
58139
59635
  try {
58140
59636
  let rows = await _db__WEBPACK_IMPORTED_MODULE_7__["runQuery"](sql, partIds, true);
58141
59637
  results = results.concat(rows);
58142
- } catch (e) {
58143
- throw new SyncError('invalid-schema');
59638
+ } catch (error) {
59639
+ throw new SyncError('invalid-schema', {
59640
+ error,
59641
+ sql,
59642
+ params: partIds
59643
+ });
58144
59644
  }
58145
59645
  }
58146
59646
 
@@ -58417,11 +59917,13 @@ async function _sendMessages(messages) {
58417
59917
  // message.
58418
59918
  _main_app__WEBPACK_IMPORTED_MODULE_8__["default"].events.emit('sync', {
58419
59919
  type: 'error',
58420
- subtype: 'apply-failure'
59920
+ subtype: 'apply-failure',
59921
+ meta: e.meta
58421
59922
  });
58422
59923
  } else {
58423
59924
  _main_app__WEBPACK_IMPORTED_MODULE_8__["default"].events.emit('sync', {
58424
- type: 'error'
59925
+ type: 'error',
59926
+ meta: e.meta
58425
59927
  });
58426
59928
  }
58427
59929
  }
@@ -61112,6 +62614,129 @@ function once(fn) {
61112
62614
 
61113
62615
  /***/ }),
61114
62616
 
62617
+ /***/ "./packages/loot-core/src/shared/errors.js":
62618
+ /*!*************************************************!*\
62619
+ !*** ./packages/loot-core/src/shared/errors.js ***!
62620
+ \*************************************************/
62621
+ /*! exports provided: getUploadError, getDownloadError, getCreateKeyError, getTestKeyError, getSubscribeError, getSyncError */
62622
+ /***/ (function(module, __webpack_exports__, __webpack_require__) {
62623
+
62624
+ "use strict";
62625
+ __webpack_require__.r(__webpack_exports__);
62626
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getUploadError", function() { return getUploadError; });
62627
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getDownloadError", function() { return getDownloadError; });
62628
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getCreateKeyError", function() { return getCreateKeyError; });
62629
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getTestKeyError", function() { return getTestKeyError; });
62630
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getSubscribeError", function() { return getSubscribeError; });
62631
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getSyncError", function() { return getSyncError; });
62632
+ function getUploadError({
62633
+ reason,
62634
+ meta
62635
+ }) {
62636
+ switch (reason) {
62637
+ case 'unauthorized':
62638
+ return 'You are not logged in.';
62639
+
62640
+ case 'encrypt-failure':
62641
+ if (meta.isMissingKey) {
62642
+ return 'Encrypting your file failed because you are missing your encryption key. Create your key in the next step.';
62643
+ }
62644
+
62645
+ return 'Encrypting the file failed. You have the correct key so this is an internal bug. To fix this, generate a new key in the next step.';
62646
+
62647
+ case 'file-has-reset':
62648
+ // Something really weird happened - during reset a sanity
62649
+ // check on the server failed. The user just needs to
62650
+ // restart the whole process.
62651
+ return 'Something went wrong while resetting your file. Please try again.';
62652
+
62653
+ case 'file-has-new-key':
62654
+ return 'Unable to encrypt your data because you are missing the key. Create the latest key in the next step.';
62655
+
62656
+ case 'network':
62657
+ return 'Uploading the file failed. Check your network connection.';
62658
+
62659
+ case 'beta-version':
62660
+ return 'You cannot perform this action in the beta version (resetting sync, deleting a file, etc).';
62661
+
62662
+ default:
62663
+ return `An internal error occurred, sorry! Contact help@actualbudget.com for support. (ref: ${reason})`;
62664
+ }
62665
+ }
62666
+ function getDownloadError({
62667
+ reason,
62668
+ meta,
62669
+ fileName
62670
+ }) {
62671
+ switch (reason) {
62672
+ case 'network':
62673
+ case 'download-failure':
62674
+ return 'Downloading the file failed. Check your network connection.';
62675
+
62676
+ case 'invalid-zip-file':
62677
+ case 'invalid-meta-file':
62678
+ return 'Downloaded file is invalid, sorry! Contact help@actualbudget.com for support.';
62679
+
62680
+ case 'decrypt-failure':
62681
+ return 'Unable to decrypt file ' + (fileName || '(unknown)') + '. To change your key, first ' + 'download this file with the proper password.';
62682
+
62683
+ case 'out-of-sync-migrations':
62684
+ return 'This budget cannot be loaded with this version of the app. ' + 'Make sure the app is up-to-date.';
62685
+
62686
+ default:
62687
+ let info = meta && meta.fileId ? `(fileId: ${meta.fileId})` : '';
62688
+ return 'Something went wrong trying to download that file, sorry! Contact help@actualbudget.com for support. ' + info;
62689
+ }
62690
+ }
62691
+ function getCreateKeyError(error) {
62692
+ return getUploadError(error);
62693
+ }
62694
+ function getTestKeyError({
62695
+ reason
62696
+ }) {
62697
+ switch (reason) {
62698
+ case 'network':
62699
+ return 'Unable to connect to the server. We need to access our server to get some information about your keys.';
62700
+
62701
+ case 'old-key-style':
62702
+ return 'This file is encrypted with an old unsupported key style. Recreate the key ' + 'on a device where the file is available, or use an older version of Actual to download ' + 'it.';
62703
+
62704
+ case 'decrypt-failure':
62705
+ return 'Unable to decrypt file with this password. Please try again.';
62706
+
62707
+ default:
62708
+ return 'Something went wrong trying to create a key, sorry! Contact help@actualbudget.com for support.';
62709
+ }
62710
+ }
62711
+ function getSubscribeError({
62712
+ reason
62713
+ }) {
62714
+ switch (reason) {
62715
+ case 'network':
62716
+ return 'Unable to reach the server. Check your internet connection';
62717
+
62718
+ case 'exists':
62719
+ return 'An account with that email already exists. Did you mean to login?';
62720
+
62721
+ case 'invalid-email':
62722
+ return 'Invalid email';
62723
+
62724
+ default:
62725
+ return 'An error occurred. Please try again later.';
62726
+ }
62727
+ }
62728
+ function getSyncError(error, id) {
62729
+ if (error === 'out-of-sync-migrations' || error === 'out-of-sync-data') {
62730
+ return 'This budget cannot be loaded with this version of the app.';
62731
+ } else if (error === 'budget-not-found') {
62732
+ return 'Budget "' + id + '" not found. Check the id of your budget in the "Advanced" section of the settings page.';
62733
+ } else {
62734
+ return 'We had an unknown problem opening "' + id + '".';
62735
+ }
62736
+ }
62737
+
62738
+ /***/ }),
62739
+
61115
62740
  /***/ "./packages/loot-core/src/shared/months.js":
61116
62741
  /*!*************************************************!*\
61117
62742
  !*** ./packages/loot-core/src/shared/months.js ***!
@@ -61774,7 +63399,7 @@ function getFieldError(type) {
61774
63399
  return 'Please choose a valid field for this type of rule';
61775
63400
 
61776
63401
  default:
61777
- return 'Internal error, sorry! Contact help@actualbudget.com';
63402
+ return 'Internal error, sorry! Please get in touch https://actualbudget.github.io/docs/Contact/ for support';
61778
63403
  }
61779
63404
  }
61780
63405
  function sortNumbers(num1, num2) {
@@ -61790,7 +63415,7 @@ function parse(item) {
61790
63415
  {
61791
63416
  let parsed = item.value;
61792
63417
 
61793
- if (item.field === 'amount' && item.op !== 'isbetween') {
63418
+ if (item.field === 'amount' && item.op !== 'isbetween' && parsed != null) {
61794
63419
  parsed = Object(_util__WEBPACK_IMPORTED_MODULE_0__["integerToAmount"])(parsed);
61795
63420
  }
61796
63421
 
@@ -61869,7 +63494,7 @@ function makeValue(value, cond) {
61869
63494
  if (cond.op !== 'isbetween') {
61870
63495
  return _objectSpread(_objectSpread({}, cond), {}, {
61871
63496
  error: null,
61872
- value: value ? Object(_util__WEBPACK_IMPORTED_MODULE_0__["currencyToAmount"])(value) || 0 : 0
63497
+ value: value ? Object(_util__WEBPACK_IMPORTED_MODULE_0__["currencyToAmount"])(String(value)) || 0 : 0
61873
63498
  });
61874
63499
  }
61875
63500