// for browser // let language; // if (window.navigator.languages) { // language = window.navigator.languages[0]; // } else { // language = window.navigator.userLanguage || window.navigator.language; // } // language = language.split('-')[0]; const inlineCode = (x) => `${x}`; const makeLink = (url, text) => `${text}` const url_importScripts = 'https://git.sequentialread.com/forest/LibreBookKeeper/src/master/importScripts' const url_bugReport = 'https://git.sequentialread.com/forest/LibreBookKeeper/issues' const url_excalibur = 'https://github.com/camelot-dev/excalibur' const macros = { "en-US" : { "pleaseIssueABugReport": `

If you believe that you have recieved this message in error, please issue a ${makeLink(url_bugReport, "bug report")}.

` } } const translations = { "en-US": { "title_OpenAnLBKFile": "Open a LibreBookKeeper .lbk File", "title_WhereToSaveYourFile": "Where to Save Your File?", "title_RecentlyOpened": "recently opened: ", "errorMessage_FileDoesNotExist": "file does not exist", "errorMessage_XReturnedY": (x, y) => `${x} returned ${y}.`, "title_CantAutoSave": "Can't Auto Save", "errorMessage_CantAutoSave": (errorMsg) => `

I was trying to auto-save your books database, but I encountered an error!

The data is still stored in my database, but I can't seem to write it to the lbk file.

${errorMsg}

${macros['en-US'].pleaseIssueABugReport} `, "errorMessage_WithBugReportLink": (errorMsg) => `${errorMsg} ${macros['en-US'].pleaseIssueABugReport} `, "errorMessage_NotAColor": `

Expected a color, but something that was not a color was given.

${macros['en-US'].pleaseIssueABugReport}`, "errorMessage_FilePathWasEmptyOrInvalid": "file path was empty or invalid", "errorMessage_ThisTypeOfFileXIsNotSupportedYet" : (x) => `this type of file "${x}" is not supported yet!`, "errorMessage_ThisTypeOfQIFFileXIsNotSupportedYet": (x) => `this type of QIF file "${x}" is not supported yet!`, "errorMessage_ThisFileXHasDateParseErrors": (x) => `

This file "${x}" appears to contain an unknown date format that I can't parse.

${macros['en-US'].pleaseIssueABugReport}`, "defaultFileName": "MyBooks.lbk", "nav_AccountsAndCategories": "accounts/categories", "nav_Timeline": "timeline", "nav_Reports": "reports", "nav_ImportExport": "import/export", "button_AboutFileTypes": "About supported file types...", "title_FileTypes": "File Types", "description_FileTypeQIF": ` QIF stands for Quicken Interchange Format. Most financial institutions will allow you to export your account data as a QIF file via thier online account portal.`, "description_FileTypeCSV": ` CSV stands for Comma Separated Values. Any spreadsheet program will be able to export as CSV. So if you want to import a spreadsheet, the best way will be to simply export it from your spreadsheet program as CSV. The file(s) must have one single list of transactions each.

Requirements:

The header row is optional.

`, "description_FileTypeJSON": ` JSON stands for JavaScript Object Notation. TODO JSON import is not implemented yet.`, "description_FileTypePDF": ` LibreBookKeeper does not directly support importing PDF files. If you want to be able to import PDF files, I would recommend using the free and open source tool ${makeLink(url_excalibur, "Excalibur")} to extract tabular data from your PDFs and convert it to CSV format first. `, "columnName_Date": "Date", "columnName_ClearDate": "Cleared Date", "columnName_Memo": "Memo", "columnName_CheckNumber": "Check Number", "columnName_Amount": "Amount", "columnName_Account": "Account", "columnName_ToSlashFrom": "To/From", "columnName_Category": "Category", "columnName_Description": "Description", "columnName_Transfer": "Transfer", "columnName_Actions": "Do", "columnName_Info": "Info", "columnName_Balance": "Balance", "description_ClearDate": "The date on which the transaction was marked as committed (rather than pending) by the financial institution.", "description_Date": "The date of the transaction, for example, the date of purchase.", "description_Memo": "A description of the transaction. May be entered by the user or exported from the financial institution.", "description_CheckNumber": "The unique serial number of the printed check. Only applies to transactions which were made by check.", "description_Amount": "The numerical amount of money associated with the transaction.", "description_Account": ` The financial institution account that this transaction is primarily associated with. For checks or debit card payments, it would be the associated checking account. For transactions between two of your accounts, for example, a monthly credit card payment or an investment transaction, it could be either account.`, "description_ToSlashFrom": ` The sender / recipient of a payment. This can be an income/spending category like "W2 Income", "Rent", or "Groceries". It can also be an Account like "Credit Card" or "Retirement Account". `, "label_Account": "Account: ", "label_InvertAmounts": "Invert Amounts: ", "button_NewFile": "New File", "button_CreateNewAccount": "New Account", "button_CreateNewCategory": "New Category", "title_CreateNewAccount": "New Account", "title_CreateNewCategory": "New Category", "title_EditAccount": "Edit Account", "title_EditCategory": "Edit Category", "button_AcknowledgementCreate": "Create", "label_Name": "Name: ", "label_Color": "Color: ", "button_PickAColor": "Pick a Color", "errorMessage_YouMustSelectAnAccount": "You must select an Account", "button_OpenFile": "Open File", "title_ImportExport": "Import/Export", "button_Import": "Import", "button_Discard": "Discard", "title_UnsupportedFormat": "Unsupported Format", "title_CantOpenDatabase": `Could Not Open LibreBookKeeper Database.`, "errorMessage_LockAlreadyTaken": (errorMsg) => ` ${errorMsg}

This is expected when there are two instances of LibreBookKeeper trying to run at once. One of them will fail to start (this one).

Otherwise, this could be because LibreBookKeeper crashed and exited without cleaning up after itself.

If this error persists, try deleting the LOCK file mentioned in the error message above.

`, "title_CantOpenFile": "Could Not Open File", "title_ImportProblem": "Import Problem", "title_CSVNeedsToBeCleanedUp": "CSV Needs To Be Cleaned Up Before Import", "errorMessage_TheFilesXHaveUnsupportedFormat": (x) => ` The file(s) "${x}" have an unsupported format. Supported formats are: csv, qif, json`, "errorMessage_TheCSVFileXDoesNotMeetRequirementsY": (x, y) => ` The file "${x}" does not meet the requirement${y.length > 1 ? 's':''}:

You may either manually edit this file and try importing it again, or enter some JavaScript code to clean it up for import.

For more information, see ${makeLink(url_importScripts, "import scripts")}.

${macros['en-US'].pleaseIssueABugReport}`, "errorMessage_NoContiguousNumericalColumn": "There must be at least one column that has a numerical value on each row.", "errorMessage_NoContiguousDateColumn": "There must be at least one column that has a date value on each row.", "button_EnterJavascript": "Enter JavaScript", "title_ImportScript": "Import Script", "description_ImportScripts" : (json) => ` Users may share import scripts for common formats via the ${makeLink(url_importScripts, "LibreBookKeeper source code repository")}.

To develop a new import script for your CSV file:
  1. copy and paste the sample JSON declaration below into your favorite JavaScript development environment
  2. develop & test the code which modifies the ${inlineCode("rows")} array so it meets your requirements
  3. paste the code below
JSON Sample:
let rows = ${json};

Import Script:

`, "title_ImportScriptResultPreview": "Import Script Result Preview", "description_ImportScriptResultPreview": (resultsHTML, requirementsHTML) => `

Results:

${resultsHTML}

Requirements:

${requirementsHTML}`, "errorMessage_RowsWasNotAnArrayOfArrays": ` Error: the returned ${inlineCode("rows")} object did not appear to be an array of arrays.`, "button_AcknowledgementRun": "Run", "title_ColumnToFieldMappings": "Column-to-Field Mappings", "description_ColumnToFieldMappings" : (tableHTML) => `

Please make sure that the columns in your spreadsheet are associated with the correct LibreBookKeeper fields. The 'Date' and 'Amount' fields are required.

${tableHTML}`, "button_MoreInfoAboutFields": "More information about fields...", "title_FieldValueMappings": "Field Value Mappings", "description_FieldValueMappings" : (formHTML) => `

Please review the way the values in each column will be interpreted.

${formHTML}`, "errorMessage_ConflictingDatesErrorExample": (ymdErrorExample, mdyErrorExample) => ` "${ymdErrorExample}" (error as Month/Day/Year) vs "${mdyErrorExample}" (error as Year/Month/Day)`, "errorMessage_AtLeastOneCellContainedADateThatCouldNotBeParsed": (example) => ` At least one cell contained a date that could not be parsed, or not all the dates could be parsed the same way. For example: "${example}" ${macros['en-US'].pleaseIssueABugReport}`, "label_AutomaticallyExtractTransactionDateFromMemo": (x) => ` Automatically extract Transaction Date and Time from Memo

(${x}% of these transaction memos contain a date and time. Transaction Date is separate from Cleared Date and will not override Cleared Date)`, "label_NumberFormat": "Number Format", "label_ThousandsCommaDecimalPeriod": "1,000.00 (North America, UK, Asia, South Africa, Australia)", "label_ThousandsPeriodDecimalComma": "1.000,00 (Europe, South America, North Africa)", "errorMessage_ConflictingNumberFormatError": (commaPeriodExample, periodCommaExample) => ` Not all numbers could be parsed the same way: "${commaPeriodExample}" (North America, UK, Asia, South Africa, Australia) vs "${periodCommaExample}" (Europe, South America, North Africa)`, "label_NewAccount": "New Account", "label_NewAccountName": "New Account Name", "label_NewCategory": "New Category", "label_NewCategoryName": "New Category Name", "errorMessage_NewAccountRequiresAName" : "New Account requires a name.", "errorMessage_NewAccountNameAlreadyTaken" : (x) => `Account name "${x}" is already being used.`, "title_ConfirmDateFormat": "Confirm Date Format", "button_MonthDayYear": "Month/Day/Year (United States of America)", "button_YearMonthDay": "Year/Month/Day (Standard)", "label_MonthDayYear": "Month/Day/Year (United States of America)", "label_YearMonthDay": "Year/Month/Day (Standard)", "description_ConfirmDateFormat" : (columnName, tableHTML) => ` Which date format is correct for the dates in the "${columnName}" column? ${tableHTML}`, "title_ValueMappings": "Value Mappings", "errorMessage_AccountOrCategoryXNotFound": (x) => ` Account or Category '${x}' was not found. ${macros['en-US'].pleaseIssueABugReport}`, "title_ResolveDuplicate" : "Potential Duplicate", "description_ResolveDuplicate" : `

Incoming:

Existing:

`, "button_Duplicate": "Incoming is a Duplicate of Existing", "button_NotDuplicate": "Incoming and Existing are different", "title_Categorize" : "Categorize", "description_Categorize" : `

This Transaction Was To/From:

`, "button_SelectAnAccountOrCategory": 'Select an Account or Category', "button_Categorize": 'Categorize ', "button_CreateNewAccountOrCategory": "New Account/Category", "title_AccountOrCategory": "Create Account or Category?", "description_AccountOrCategory": `

An Account would be an account you have, such as "Checking", "Credit Card" or "Retirement Account"

A Category would be an income/spending category like "W2 Income", "Rent", or "Groceries"

`, "errorMessage_AccountAndToSlashFromAreRequired": "Error saving transaction: Account and To/From are required.", "errorMessage_ClearDateRequired": "Error saving transaction: Cleared Date is required.", "title_Accounts": "Accounts", "label_AllAccounts": "All Accounts: ", "title_DeleteAccount": "Delete Account", "title_DeleteCategory": "Delete Category", "description_DeleteAccountOrCategory": (type, name) => ` Are you sure you want to delete the ${type} '${name}'?

This cannot be undone.

What do you want to do with the transactions to/from this ${type}?`, "label_DeleteTransactions": "Delete Transactions", "label_MoveTransactions": (type) => `Move transactions to another ${type}`, "label_RemoveSearch": ` Remove from categorization index

(No longer use this data when recommending categories for new transactions)

`, "label_MoveTo": "Move To: ", "title_Categories": "Categories", "option_ChoseOne": " -- choose -- ", "option_Account": "account", "option_Category": "category", "label_CategoryDisplayDuration": "Aggregate Category Value By: ", "option_Week": "Week", "option_Month": "Month", "option_Quarter": "Quarter", "option_Year": "Year", "option_31Days": "Last 31 Days", "option_MonthToDate": "Month To Date", "option_92Days": "Last 92 Days", "option_QuarterToDate": "Quarter To Date", "option_365Days": "Last 365 Days", "option_YearToDate": "Year To Date", "option_5Years": "Last 5 Years", "option_AllTime": "All Time", "button_AccountsAndCategories": "Accounts/Categories", "title_EditTransaction": "Edit Transaction", "errorMessage_ClearDateIsRequired": "Cleared Date is Required", "title_DeleteTransaction": "Delete Transaction", "description_DeleteTransaction": `

Are you sure you want to delete this transaction?

This cannot be undone.

`, "title_Reports": "Reports", "title_Aggregations": "Aggregations", "button_Reports": "Reports", "title_Aggregation": "Aggregation", "title_DeleteAggregation": "Delete Aggregation", "description_DeleteAggregation": (x) => `Are you sure you want to delete the aggregation '${x}'?`, "label_AggregationExpression": "Aggregation Expression Builder: ", "description_AggregationExpression": ` Drag and drop elements to add them to the expression. Drag and drop to remove them. `, "label_OperatorsAndFunctions": "Operators/Functions", "label_AccountsCategoriesAndAggregations": "Accounts/Categories/Aggregations", "label_Sum": "sum", "errorMessage_AggregationNameAlreadyTaken" : (x) => `Aggregation name "${x}" is already being used.`, "errorMessage_AggregationRequiresAName" : "Aggregation requires a name.", "errorMessage_AggregationRequiresAnExpression" : "Aggregation requires an expression.", "errorMessage_OpMultiplyRequiresANumber": "Multiplication operator requires a numerical value.", "errorMessage_OpConstantRequiresANumber": "Constant requires a numerical value.", "errorMessage_ParameterXOfYIsEmpty": (x,y) => `Parameter ${x} of ${y} is empty.`, "button_AggregationsExamples": "Aggregations Examples...", "title_AggregationExamples": "Aggregation Examples", "description_AggregationExamples": `

LibreBookKeeper does not force you to track your savings/spending in any particular way, you are free to do it however you want.

However, that freedom and flexibility comes at a price: you have to define how you categorize and graph your transaction data.

Aggregations are math expressions that combine transaction data from one or more accounts/categories/other aggregations in order to enable you to create meaningful reports (stats, pie charts, and graphs)

Here are some examples of a couple different types of aggregations that could be used to create a savings rate report.

`, "label_AggregationExampleGrouping": "Categorization / Grouping", "label_AggregationExampleSavingsRate": "Savings Rate", "label_AggregationExampleBudget": "Budget", "description_AggregationExampleGrouping": ` This aggregation type simply groups multiple categories together. Note that by default, spending transactions will show up with a negative value. So the sum of the spending transactions is multiplied by negative one in order to obtain a positive value. `, "description_AggregationExampleSavingsRate": ` This aggregation depends on two grouping aggregations, one named all-income and one named abs-all-spending. It computes the formula ${inlineCode(`((all-income - abs-all-spending) / all-income)*100`)} , in other words, what % of income is being saved rather than spent for any given period of time. `, "description_AggregationExampleBudget": ` This aggregation could be used to show whether or not you have spent more or less than a certain amount on a certain thing during a given period of time, say, each month. `, "title_Report": "Report", "title_DeleteReport": "Delete Report", "description_DeleteReport": (x) => `Are you sure you want to delete the report '${x}'?`, "label_Type": "Type: ", "label_Show": "Show: ", "label_Aggregate": "Aggregate: ", "description_EachInterval": "each interval", "description_TheTimeframe": "the timeframe", "option_CashFlowMonthly": (x) => `Cash Flow (sum of all transactions during ${x})`, "option_AccountBalance": (x) => ` Account Balance / Cumulative (sum of all transactions from the beginning of time until the end of ${x}) `, "option_LineChart": "Line Chart", "option_PieChart": "Pie Chart", "option_SingleStat": "Single Stat", "label_Preview": "Preview: ", "errorMessage_ReportNameAlreadyTaken" : (x) => `Report name "${x}" is already being used.`, "errorMessage_ReportRequiresAName" : "Report requires a name.", "errorMessage_SelectAReportType": "Please select a Report Type (Pie Chart, Line Chart, or Single Stat).", "errorMessage_SelectAnAggregationMethod": "Please select an Aggregation Method (Cash Flow or Account Balance).", "errorMessage_SelectAnAccountCategoryOrAggregation": "Please select at least one Account, Category, or Aggregation.", "label_ReportTimeframe": "Timeframe: ", "label_ReportInterval": "Interval: ", "label_Align": "Align: ", "option_Calendar": "Calendar", "option_Today": "Today", "label_Unit": "Unit: ", "option_Percent": "Percent", "option_Currency": "Currency", "button_AcknowledgementDelete": "Delete", "button_AcknowledgementOK": "Ok", "button_AcknowledgementSave": "Save", "button_AcknowledgementContinue": "Continue", "button_BackCancel": "Cancel", "button_Back": "Back" } } translations['en'] = translations['en-US']; module.exports = { translations }